difftreelog
build upgrade frontier
in: master
51 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -75,9 +75,9 @@
[[package]]
name = "aho-corasick"
-version = "0.7.19"
+version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
+checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
@@ -137,9 +137,9 @@
[[package]]
name = "array-bytes"
-version = "4.1.0"
+version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a913633b0c922e6b745072795f50d90ebea78ba31a57e2ac8c2fc7b50950949"
+checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6"
[[package]]
name = "arrayref"
@@ -196,30 +196,30 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
dependencies = [
- "concurrent-queue",
+ "concurrent-queue 1.2.4",
"event-listener",
"futures-core",
]
[[package]]
name = "async-executor"
-version = "1.4.1"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
+checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
dependencies = [
+ "async-lock",
"async-task",
- "concurrent-queue",
+ "concurrent-queue 2.0.0",
"fastrand",
"futures-lite",
- "once_cell",
"slab",
]
[[package]]
name = "async-global-executor"
-version = "2.3.0"
+version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0da5b41ee986eed3f524c380e6d64965aea573882a8907682ad100f7859305ca"
+checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
dependencies = [
"async-channel",
"async-executor",
@@ -232,16 +232,16 @@
[[package]]
name = "async-io"
-version = "1.9.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83e21f3a490c72b3b0cf44962180e60045de2925d8dff97918f7ee43c8f637c7"
+checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7"
dependencies = [
+ "async-lock",
"autocfg",
- "concurrent-queue",
+ "concurrent-queue 1.2.4",
"futures-lite",
"libc",
"log",
- "once_cell",
"parking",
"polling",
"slab",
@@ -340,9 +340,9 @@
[[package]]
name = "asynchronous-codec"
-version = "0.6.0"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0de5164e5edbf51c45fb8c2d9664ae1c095cce1b265ecf7569093c0d66ef690"
+checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182"
dependencies = [
"bytes",
"futures-sink",
@@ -595,16 +595,16 @@
"funty 2.0.0",
"radium 0.7.0",
"tap",
- "wyz 0.5.0",
+ "wyz 0.5.1",
]
[[package]]
name = "blake2"
-version = "0.10.4"
+version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388"
+checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e"
dependencies = [
- "digest 0.10.5",
+ "digest 0.10.6",
]
[[package]]
@@ -614,7 +614,7 @@
checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
dependencies = [
"arrayvec 0.4.12",
- "constant_time_eq",
+ "constant_time_eq 0.1.5",
]
[[package]]
@@ -625,7 +625,7 @@
dependencies = [
"arrayref",
"arrayvec 0.7.2",
- "constant_time_eq",
+ "constant_time_eq 0.1.5",
]
[[package]]
@@ -636,21 +636,21 @@
dependencies = [
"arrayref",
"arrayvec 0.7.2",
- "constant_time_eq",
+ "constant_time_eq 0.1.5",
]
[[package]]
name = "blake3"
-version = "1.3.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f"
+checksum = "895adc16c8b3273fbbc32685a7d55227705eda08c01e77704020f3491924b44b"
dependencies = [
"arrayref",
"arrayvec 0.7.2",
"cc",
"cfg-if 1.0.0",
- "constant_time_eq",
- "digest 0.10.5",
+ "constant_time_eq 0.2.4",
+ "digest 0.10.6",
]
[[package]]
@@ -769,9 +769,9 @@
[[package]]
name = "byte-slice-cast"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87c5fdd0166095e1d463fc6cc01aa8ce547ad77a4e84d42eb6762b084e28067e"
+checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
[[package]]
name = "byte-tools"
@@ -787,9 +787,9 @@
[[package]]
name = "bytes"
-version = "1.2.1"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
+checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
[[package]]
name = "bzip2-sys"
@@ -841,9 +841,9 @@
[[package]]
name = "cc"
-version = "1.0.73"
+version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
dependencies = [
"jobserver",
]
@@ -911,9 +911,9 @@
[[package]]
name = "chrono"
-version = "0.4.22"
+version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
+checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -973,7 +973,7 @@
dependencies = [
"glob",
"libc",
- "libloading 0.7.3",
+ "libloading 0.7.4",
]
[[package]]
@@ -1017,9 +1017,9 @@
[[package]]
name = "cmake"
-version = "0.1.48"
+version = "0.1.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a"
+checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c"
dependencies = [
"cc",
]
@@ -1048,9 +1048,9 @@
[[package]]
name = "comfy-table"
-version = "6.1.1"
+version = "6.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b3d16bb3da60be2f7c7acfc438f2ae6f3496897ce68c291d0509bb67b4e248e"
+checksum = "e621e7e86c46fd8a14c32c6ae3cb95656621b4743a27d0cffedb831d46e7ad21"
dependencies = [
"strum",
"strum_macros",
@@ -1059,9 +1059,9 @@
[[package]]
name = "concat-idents"
-version = "1.1.3"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b6f90860248d75014b7b103db8fee4f291c07bfb41306cdf77a0a5ab7a10d2f"
+checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832"
dependencies = [
"quote",
"syn",
@@ -1077,6 +1077,15 @@
]
[[package]]
+name = "concurrent-queue"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
name = "console"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1102,6 +1111,12 @@
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
+name = "constant_time_eq"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279"
+
+[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1152,18 +1167,18 @@
[[package]]
name = "cranelift-bforest"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44409ccf2d0f663920cab563d2b79fcd6b2e9a2bcc6e929fef76c8f82ad6c17a"
+checksum = "52056f6d0584484b57fa6c1a65c1fcb15f3780d8b6a758426d9e3084169b2ddd"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98de2018ad96eb97f621f7d6b900a0cc661aec8d02ea4a50e56ecb48e5a2fcaf"
+checksum = "18fed94c8770dc25d01154c3ffa64ed0b3ba9d583736f305fed7beebe5d9cf74"
dependencies = [
"arrayvec 0.7.2",
"bumpalo",
@@ -1181,33 +1196,33 @@
[[package]]
name = "cranelift-codegen-meta"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5287ce36e6c4758fbaf298bd1a8697ad97a4f2375a3d1b61142ea538db4877e5"
+checksum = "1c451b81faf237d11c7e4f3165eeb6bac61112762c5cfe7b4c0fb7241474358f"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2855c24219e2f08827f3f4ffb2da92e134ae8d8ecc185b11ec8f9878cf5f588e"
+checksum = "e7c940133198426d26128f08be2b40b0bd117b84771fd36798969c4d712d81fc"
[[package]]
name = "cranelift-entity"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b65673279d75d34bf11af9660ae2dbd1c22e6d28f163f5c72f4e1dc56d56103"
+checksum = "87a0f1b2fdc18776956370cf8d9b009ded3f855350c480c1c52142510961f352"
dependencies = [
"serde",
]
[[package]]
name = "cranelift-frontend"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed2b3d7a4751163f6c4a349205ab1b7d9c00eecf19dcea48592ef1f7688eefc"
+checksum = "34897538b36b216cc8dd324e73263596d51b8cf610da6498322838b2546baf8a"
dependencies = [
"cranelift-codegen",
"log",
@@ -1217,15 +1232,15 @@
[[package]]
name = "cranelift-isle"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3be64cecea9d90105fc6a2ba2d003e98c867c1d6c4c86cc878f97ad9fb916293"
+checksum = "1b2629a569fae540f16a76b70afcc87ad7decb38dc28fa6c648ac73b51e78470"
[[package]]
name = "cranelift-native"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4a03a6ac1b063e416ca4b93f6247978c991475e8271465340caa6f92f3c16a4"
+checksum = "20937dab4e14d3e225c5adfc9c7106bafd4ac669bdb43027b911ff794c6fb318"
dependencies = [
"cranelift-codegen",
"libc",
@@ -1234,9 +1249,9 @@
[[package]]
name = "cranelift-wasm"
-version = "0.88.1"
+version = "0.88.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c699873f7b30bc5f20dd03a796b4183e073a46616c91704792ec35e45d13f913"
+checksum = "80fc2288957a94fd342a015811479de1837850924166d1f1856d8406e6f3609b"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
@@ -1280,22 +1295,22 @@
[[package]]
name = "crossbeam-epoch"
-version = "0.9.11"
+version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
+checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if 1.0.0",
"crossbeam-utils",
- "memoffset",
+ "memoffset 0.7.1",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
+checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
@@ -1303,9 +1318,9 @@
[[package]]
name = "crossbeam-utils"
-version = "0.8.12"
+version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if 1.0.0",
]
@@ -1872,9 +1887,9 @@
[[package]]
name = "cxx"
-version = "1.0.80"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a"
+checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453"
dependencies = [
"cc",
"cxxbridge-flags",
@@ -1884,9 +1899,9 @@
[[package]]
name = "cxx-build"
-version = "1.0.80"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827"
+checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0"
dependencies = [
"cc",
"codespan-reporting",
@@ -1899,15 +1914,15 @@
[[package]]
name = "cxxbridge-flags"
-version = "1.0.80"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a"
+checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71"
[[package]]
name = "cxxbridge-macro"
-version = "1.0.80"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7"
+checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470"
dependencies = [
"proc-macro2",
"quote",
@@ -1993,9 +2008,9 @@
[[package]]
name = "digest"
-version = "0.10.5"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
+checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer 0.10.3",
"crypto-common",
@@ -2216,9 +2231,9 @@
[[package]]
name = "env_logger"
-version = "0.9.1"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272"
+checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
dependencies = [
"atty",
"humantime",
@@ -2479,7 +2494,7 @@
[[package]]
name = "fc-consensus"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"async-trait",
"fc-db",
@@ -2498,14 +2513,16 @@
[[package]]
name = "fc-db"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"fp-storage",
"kvdb-rocksdb",
+ "log",
"parity-db",
"parity-scale-codec 3.2.1",
"parking_lot 0.12.1",
"sc-client-db",
+ "sp-blockchain",
"sp-core",
"sp-database",
"sp-runtime",
@@ -2514,7 +2531,7 @@
[[package]]
name = "fc-mapping-sync"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"fc-db",
"fp-consensus",
@@ -2531,13 +2548,15 @@
[[package]]
name = "fc-rpc"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"ethereum",
"ethereum-types",
"evm",
"fc-db",
"fc-rpc-core",
+ "fp-ethereum",
+ "fp-evm",
"fp-rpc",
"fp-storage",
"futures 0.3.25",
@@ -2545,12 +2564,11 @@
"jsonrpsee",
"libsecp256k1",
"log",
- "lru 0.7.8",
+ "lru 0.8.1",
"parity-scale-codec 3.2.1",
"prometheus",
"rand 0.8.5",
"rlp",
- "rustc-hex",
"sc-client-api",
"sc-network",
"sc-network-common",
@@ -2573,7 +2591,7 @@
[[package]]
name = "fc-rpc-core"
version = "1.1.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"ethereum",
"ethereum-types",
@@ -2713,7 +2731,7 @@
[[package]]
name = "fp-consensus"
version = "2.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"ethereum",
"parity-scale-codec 3.2.1",
@@ -2723,9 +2741,24 @@
]
[[package]]
+name = "fp-ethereum"
+version = "1.0.0-dev"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
+dependencies = [
+ "ethereum",
+ "ethereum-types",
+ "fp-evm",
+ "frame-support",
+ "num_enum",
+ "parity-scale-codec 3.2.1",
+ "sp-core",
+ "sp-std",
+]
+
+[[package]]
name = "fp-evm"
version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"evm",
"frame-support",
@@ -2739,7 +2772,7 @@
[[package]]
name = "fp-evm-mapping"
version = "0.1.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"frame-support",
"sp-core",
@@ -2748,7 +2781,7 @@
[[package]]
name = "fp-rpc"
version = "3.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"ethereum",
"ethereum-types",
@@ -2765,7 +2798,7 @@
[[package]]
name = "fp-self-contained"
version = "1.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"ethereum",
"frame-support",
@@ -2773,17 +2806,16 @@
"parity-util-mem",
"scale-info",
"serde",
- "sp-debug-derive",
- "sp-io",
"sp-runtime",
]
[[package]]
name = "fp-storage"
version = "2.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"parity-scale-codec 3.2.1",
+ "serde",
]
[[package]]
@@ -3040,9 +3072,9 @@
[[package]]
name = "fs-err"
-version = "2.8.1"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50"
+checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
[[package]]
name = "fs-swap"
@@ -3512,9 +3544,9 @@
[[package]]
name = "hyper"
-version = "0.14.20"
+version = "0.14.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
+checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
dependencies = [
"bytes",
"futures-channel",
@@ -3536,9 +3568,9 @@
[[package]]
name = "hyper-rustls"
-version = "0.23.0"
+version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac"
+checksum = "59df7c4e19c950e6e0e868dcc0a300b09a9b88e9ec55bd879ca819087a77355d"
dependencies = [
"http",
"hyper",
@@ -3551,9 +3583,9 @@
[[package]]
name = "iana-time-zone"
-version = "0.1.51"
+version = "0.1.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
dependencies = [
"android_system_properties",
"core-foundation-sys",
@@ -3662,9 +3694,9 @@
[[package]]
name = "indexmap"
-version = "1.9.1"
+version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
@@ -3706,11 +3738,21 @@
[[package]]
name = "io-lifetimes"
-version = "0.7.4"
+version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6e481ccbe3dea62107216d0d1138bb8ad8e5e5c43009a098bd1990272c497b0"
+checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074"
[[package]]
+name = "io-lifetimes"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87"
+dependencies = [
+ "libc",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
name = "ip_network"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3718,9 +3760,9 @@
[[package]]
name = "ipconfig"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98"
+checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be"
dependencies = [
"socket2",
"widestring",
@@ -3730,9 +3772,9 @@
[[package]]
name = "ipnet"
-version = "2.5.0"
+version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
+checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745"
[[package]]
name = "itertools"
@@ -3925,9 +3967,12 @@
[[package]]
name = "keccak"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838"
+checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768"
+dependencies = [
+ "cpufeatures",
+]
[[package]]
name = "kusama-runtime"
@@ -4113,9 +4158,9 @@
[[package]]
name = "libloading"
-version = "0.7.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if 1.0.0",
"winapi",
@@ -4123,9 +4168,9 @@
[[package]]
name = "libm"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "292a948cd991e376cf75541fe5b97a1081d713c618b4f1b9500f8844e49eb565"
+checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
[[package]]
name = "libp2p"
@@ -4757,6 +4802,12 @@
checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
[[package]]
+name = "linux-raw-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb68f22743a3fb35785f1e7f844ca5a3de2dde5bd0c0ef5b372065814699b121"
+
+[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4880,18 +4931,18 @@
[[package]]
name = "memfd"
-version = "0.6.1"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "480b5a5de855d11ff13195950bdc8b98b5e942ef47afc447f6615cdcc4e15d80"
+checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb"
dependencies = [
- "rustix",
+ "rustix 0.36.2",
]
[[package]]
name = "memmap2"
-version = "0.5.7"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
+checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc"
dependencies = [
"libc",
]
@@ -4906,6 +4957,15 @@
]
[[package]]
+name = "memoffset"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "memory-db"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5020,7 +5080,7 @@
"blake2s_simd",
"blake3",
"core2",
- "digest 0.10.5",
+ "digest 0.10.6",
"multihash-derive",
"sha2 0.10.6",
"sha3",
@@ -5291,15 +5351,36 @@
[[package]]
name = "num_cpus"
-version = "1.13.1"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
+checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
+name = "num_enum"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5322,9 +5403,9 @@
[[package]]
name = "once_cell"
-version = "1.15.0"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "opal-runtime"
@@ -5577,9 +5658,9 @@
[[package]]
name = "os_str_bytes"
-version = "6.3.0"
+version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]]
name = "owning_ref"
@@ -5724,7 +5805,7 @@
[[package]]
name = "pallet-base-fee"
version = "1.0.0"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"fp-evm",
"frame-support",
@@ -5940,12 +6021,13 @@
[[package]]
name = "pallet-ethereum"
version = "4.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
"ethereum",
"ethereum-types",
"evm",
"fp-consensus",
+ "fp-ethereum",
"fp-evm",
"fp-evm-mapping",
"fp-rpc",
@@ -5953,14 +6035,12 @@
"fp-storage",
"frame-support",
"frame-system",
- "log",
"pallet-evm",
"pallet-timestamp",
"parity-scale-codec 3.2.1",
"rlp",
"scale-info",
"serde",
- "sha3",
"sp-io",
"sp-runtime",
"sp-std",
@@ -5969,8 +6049,9 @@
[[package]]
name = "pallet-evm"
version = "6.0.0-dev"
-source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30#65930cb2982258bee67b73a1f017711f6f4aa0a4"
+source = "git+https://github.com/uniquenetwork/frontier?branch=unique-polkadot-v0.9.30-2#6fce4a7f9c3591f4090dd1db39fe71f6562804d0"
dependencies = [
+ "environmental",
"evm",
"fp-evm",
"fp-evm-mapping",
@@ -5986,7 +6067,6 @@
"rlp",
"scale-info",
"serde",
- "sha3",
"sp-core",
"sp-io",
"sp-runtime",
@@ -7163,9 +7243,9 @@
[[package]]
name = "pest"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
+checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8"
dependencies = [
"thiserror",
"ucd-trie",
@@ -7173,9 +7253,9 @@
[[package]]
name = "pest_derive"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2"
+checksum = "d5fd9bc6500181952d34bd0b2b0163a54d794227b498be0b7afa7698d0a7b18f"
dependencies = [
"pest",
"pest_generator",
@@ -7183,9 +7263,9 @@
[[package]]
name = "pest_generator"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db"
+checksum = "d2610d5ac5156217b4ff8e46ddcef7cdf44b273da2ac5bca2ecbfa86a330e7c4"
dependencies = [
"pest",
"pest_meta",
@@ -7196,9 +7276,9 @@
[[package]]
name = "pest_meta"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d"
+checksum = "824749bf7e21dd66b36fbe26b3f45c713879cccd4a009a917ab8e045ca8246fe"
dependencies = [
"once_cell",
"pest",
@@ -8556,11 +8636,21 @@
[[package]]
name = "ppv-lite86"
-version = "0.2.16"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
+name = "prettyplease"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c142c0e46b57171fe0c528bee8c5b7569e80f0c17e377cd0e30ea57dbc11bb51"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
name = "primitive-types"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -8682,12 +8772,12 @@
[[package]]
name = "prost"
-version = "0.11.0"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "399c3c31cdec40583bb68f0b18403400d01ec4289c383aa047560439952c4dd7"
+checksum = "a0841812012b2d4a6145fae9a6af1534873c32aa67fff26bd09f8fa42c83f95a"
dependencies = [
"bytes",
- "prost-derive 0.11.0",
+ "prost-derive 0.11.2",
]
[[package]]
@@ -8714,9 +8804,9 @@
[[package]]
name = "prost-build"
-version = "0.11.1"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f835c582e6bd972ba8347313300219fed5bfa52caf175298d860b61ff6069bb"
+checksum = "1d8b442418ea0822409d9e7d047cbf1e7e9e1760b172bf9982cf29d517c93511"
dependencies = [
"bytes",
"heck",
@@ -8725,9 +8815,11 @@
"log",
"multimap",
"petgraph",
- "prost 0.11.0",
- "prost-types 0.11.1",
+ "prettyplease",
+ "prost 0.11.2",
+ "prost-types 0.11.2",
"regex",
+ "syn",
"tempfile",
"which",
]
@@ -8760,9 +8852,9 @@
[[package]]
name = "prost-derive"
-version = "0.11.0"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7345d5f0e08c0536d7ac7229952590239e77abf0a0100a1b1d890add6ea96364"
+checksum = "164ae68b6587001ca506d3bf7f1000bfa248d0e1217b618108fba4ec1d0cc306"
dependencies = [
"anyhow",
"itertools",
@@ -8783,12 +8875,12 @@
[[package]]
name = "prost-types"
-version = "0.11.1"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dfaa718ad76a44b3415e6c4d53b17c8f99160dcb3a99b10470fce8ad43f6e3e"
+checksum = "747761bc3dc48f9a34553bf65605cf6cb6288ba219f3450b4275dbd81539551a"
dependencies = [
"bytes",
- "prost 0.11.0",
+ "prost 0.11.2",
]
[[package]]
@@ -9039,11 +9131,10 @@
[[package]]
name = "rayon"
-version = "1.5.3"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
+checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b"
dependencies = [
- "autocfg",
"crossbeam-deque",
"either",
"rayon-core",
@@ -9051,9 +9142,9 @@
[[package]]
name = "rayon-core"
-version = "1.9.3"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
+checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@@ -9096,18 +9187,18 @@
[[package]]
name = "ref-cast"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12a733f1746c929b4913fe48f8697fcf9c55e3304ba251a79ffb41adfeaf49c2"
+checksum = "53b15debb4f9d60d767cd8ca9ef7abb2452922f3214671ff052defc7f3502c44"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5887de4a01acafd221861463be6113e6e87275e79804e56779f4cdc131c60368"
+checksum = "abfa8511e9e94fd3de6585a3d3cd00e01ed556dc9814829280af0e8dc72a8f36"
dependencies = [
"proc-macro2",
"quote",
@@ -9128,9 +9219,9 @@
[[package]]
name = "regex"
-version = "1.6.0"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
+checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
dependencies = [
"aho-corasick",
"memchr",
@@ -9148,9 +9239,9 @@
[[package]]
name = "regex-syntax"
-version = "0.6.27"
+version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "remote-externalities"
@@ -9426,16 +9517,30 @@
[[package]]
name = "rustix"
-version = "0.35.12"
+version = "0.35.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "985947f9b6423159c4726323f373be0a21bdb514c5af06a849cb3d2dce2d01e8"
+checksum = "727a1a6d65f786ec22df8a81ca3121107f235970dc1705ed681d3e6e8b9cd5f9"
dependencies = [
"bitflags",
"errno",
- "io-lifetimes",
+ "io-lifetimes 0.7.5",
"libc",
- "linux-raw-sys",
- "windows-sys 0.36.1",
+ "linux-raw-sys 0.0.46",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "rustix"
+version = "0.36.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "203974af07ea769452490ee8de3e5947971efc3a090dca8a779dd432d3fa46a7"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes 1.0.1",
+ "libc",
+ "linux-raw-sys 0.1.2",
+ "windows-sys 0.42.0",
]
[[package]]
@@ -9976,7 +10081,7 @@
"once_cell",
"parity-scale-codec 3.2.1",
"parity-wasm 0.45.0",
- "rustix",
+ "rustix 0.35.13",
"sc-allocator",
"sc-executor-common",
"sp-runtime-interface",
@@ -10135,8 +10240,8 @@
"futures 0.3.25",
"libp2p",
"log",
- "prost 0.11.0",
- "prost-build 0.11.1",
+ "prost 0.11.2",
+ "prost-build 0.11.2",
"sc-client-api",
"sc-network-common",
"sp-blockchain",
@@ -10612,9 +10717,9 @@
[[package]]
name = "scale-info"
-version = "2.2.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "333af15b02563b8182cd863f925bd31ef8fa86a0e095d30c091956057d436153"
+checksum = "88d8a765117b237ef233705cc2cc4c6a27fccd46eea6ef0c8c6dae5f3ef407f8"
dependencies = [
"bitvec 1.0.1",
"cfg-if 1.0.0",
@@ -10626,9 +10731,9 @@
[[package]]
name = "scale-info-derive"
-version = "2.2.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53f56acbd0743d29ffa08f911ab5397def774ad01bab3786804cf6ee057fb5e1"
+checksum = "cdcd47b380d8c4541044e341dcd9475f55ba37ddc50c908d945fc036a8642496"
dependencies = [
"proc-macro-crate",
"proc-macro2",
@@ -10804,9 +10909,9 @@
[[package]]
name = "serde_json"
-version = "1.0.87"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [
"itoa",
"ryu",
@@ -10843,7 +10948,7 @@
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
- "digest 0.10.5",
+ "digest 0.10.6",
]
[[package]]
@@ -10879,7 +10984,7 @@
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
- "digest 0.10.5",
+ "digest 0.10.6",
]
[[package]]
@@ -10888,7 +10993,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9"
dependencies = [
- "digest 0.10.5",
+ "digest 0.10.6",
"keccak",
]
@@ -10956,9 +11061,9 @@
[[package]]
name = "similar"
-version = "2.2.0"
+version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
+checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
dependencies = [
"bstr",
"unicode-segmentation",
@@ -11018,9 +11123,9 @@
[[package]]
name = "snap"
-version = "1.0.5"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451"
+checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831"
[[package]]
name = "snow"
@@ -11318,7 +11423,7 @@
dependencies = [
"blake2",
"byteorder",
- "digest 0.10.5",
+ "digest 0.10.6",
"sha2 0.10.6",
"sha3",
"sp-std",
@@ -11816,9 +11921,9 @@
[[package]]
name = "ss58-registry"
-version = "1.33.0"
+version = "1.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ab7554f8a8b6f8d71cd5a8e6536ef116e2ce0504cf97ebf16311d58065dc8a6"
+checksum = "fa0813c10b9dbdc842c2305f949f724c64866e4ef4d09c9151e96f6a2106773c"
dependencies = [
"Inflector",
"num-format",
@@ -12141,9 +12246,9 @@
[[package]]
name = "target-lexicon"
-version = "0.12.4"
+version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
+checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d"
[[package]]
name = "tempfile"
@@ -12368,9 +12473,9 @@
[[package]]
name = "tokio"
-version = "1.21.2"
+version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
+checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3"
dependencies = [
"autocfg",
"bytes",
@@ -12694,7 +12799,7 @@
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if 1.0.0",
- "digest 0.10.5",
+ "digest 0.10.6",
"rand 0.8.5",
"static_assertions",
]
@@ -13340,9 +13445,9 @@
[[package]]
name = "wasmtime"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1f511c4917c83d04da68333921107db75747c4e11a2f654a8e909cc5e0520dc"
+checksum = "4ad5af6ba38311282f2a21670d96e78266e8c8e2f38cbcd52c254df6ccbc7731"
dependencies = [
"anyhow",
"bincode",
@@ -13368,18 +13473,18 @@
[[package]]
name = "wasmtime-asm-macros"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39bf3debfe744bf19dd3732990ce6f8c0ced7439e2370ba4e1d8f5a3660a3178"
+checksum = "45de63ddfc8b9223d1adc8f7b2ee5f35d1f6d112833934ad7ea66e4f4339e597"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "wasmtime-cache"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ece42fa4676a263f7558cdaaf5a71c2592bebcbac22a0580e33cf3406c103da2"
+checksum = "bcd849399d17d2270141cfe47fa0d91ee52d5f8ea9b98cf7ddde0d53e5f79882"
dependencies = [
"anyhow",
"base64",
@@ -13387,7 +13492,7 @@
"directories-next",
"file-per-thread-logger",
"log",
- "rustix",
+ "rustix 0.35.13",
"serde",
"sha2 0.9.9",
"toml",
@@ -13397,9 +13502,9 @@
[[package]]
name = "wasmtime-cranelift"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "058217e28644b012bdcdf0e445f58d496d78c2e0b6a6dd93558e701591dad705"
+checksum = "4bd91339b742ff20bfed4532a27b73c86b5bcbfedd6bea2dcdf2d64471e1b5c6"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -13418,9 +13523,9 @@
[[package]]
name = "wasmtime-environ"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7af06848df28b7661471d9a80d30a973e0f401f2e3ed5396ad7e225ed217047"
+checksum = "ebb881c61f4f627b5d45c54e629724974f8a8890d455bcbe634330cc27309644"
dependencies = [
"anyhow",
"cranelift-entity",
@@ -13437,9 +13542,9 @@
[[package]]
name = "wasmtime-jit"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9028fb63a54185b3c192b7500ef8039c7bb8d7f62bfc9e7c258483a33a3d13bb"
+checksum = "1985c628011fe26adf5e23a5301bdc79b245e0e338f14bb58b39e4e25e4d8681"
dependencies = [
"addr2line",
"anyhow",
@@ -13450,7 +13555,7 @@
"log",
"object",
"rustc-demangle",
- "rustix",
+ "rustix 0.35.13",
"serde",
"target-lexicon",
"thiserror",
@@ -13462,20 +13567,20 @@
[[package]]
name = "wasmtime-jit-debug"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25e82d4ef93296785de7efca92f7679dc67fe68a13b625a5ecc8d7503b377a37"
+checksum = "f671b588486f5ccec8c5a3dba6b4c07eac2e66ab8c60e6f4e53717c77f709731"
dependencies = [
"object",
"once_cell",
- "rustix",
+ "rustix 0.35.13",
]
[[package]]
name = "wasmtime-runtime"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f0e9bea7d517d114fe66b930b2124ee086516ee93eeebfd97f75f366c5b0553"
+checksum = "ee8f92ad4b61736339c29361da85769ebc200f184361959d1792832e592a1afd"
dependencies = [
"anyhow",
"cc",
@@ -13485,10 +13590,10 @@
"log",
"mach",
"memfd",
- "memoffset",
+ "memoffset 0.6.5",
"paste",
"rand 0.8.5",
- "rustix",
+ "rustix 0.35.13",
"thiserror",
"wasmtime-asm-macros",
"wasmtime-environ",
@@ -13498,9 +13603,9 @@
[[package]]
name = "wasmtime-types"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69b83e93ed41b8fdc936244cfd5e455480cf1eca1fd60c78a0040038b4ce5075"
+checksum = "d23d61cb4c46e837b431196dd06abb11731541021916d03476a178b54dc07aeb"
dependencies = [
"cranelift-entity",
"serde",
@@ -13841,9 +13946,9 @@
[[package]]
name = "winreg"
-version = "0.7.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]
@@ -13856,9 +13961,9 @@
[[package]]
name = "wyz"
-version = "0.5.0"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e"
+checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
client/rpc/Cargo.tomldiffbeforeafterboth--- a/client/rpc/Cargo.toml
+++ b/client/rpc/Cargo.toml
@@ -19,4 +19,4 @@
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-rpc = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
crates/evm-coder/Cargo.tomldiffbeforeafterboth--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -19,7 +19,7 @@
# We have tuple-heavy code in solidity.rs
impl-trait-for-tuples = "0.2.2"
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
[dev-dependencies]
# We want to assert some large binary blobs equality in tests
crates/evm-coder/src/lib.rsdiffbeforeafterboth--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -197,7 +197,7 @@
impl EthCrossAccount {
pub fn from_sub_cross_account<T>(cross_account_id: &T::CrossAccountId) -> Self
where
- T: pallet_evm::account::Config,
+ T: pallet_evm::Config,
T::AccountId: AsRef<[u8; 32]>,
{
if cross_account_id.is_canonical_substrate() {
@@ -215,7 +215,7 @@
pub fn into_sub_cross_account<T>(&self) -> crate::execution::Result<T::CrossAccountId>
where
- T: pallet_evm::account::Config,
+ T: pallet_evm::Config,
T::AccountId: From<[u8; 32]>,
{
if self.eth == Default::default() && self.sub == Default::default() {
@@ -231,7 +231,7 @@
}
/// Convert `CrossAccountId` to `uint256`.
- pub fn convert_cross_account_to_uint256<T: pallet_evm::account::Config>(
+ pub fn convert_cross_account_to_uint256<T: pallet_evm::Config>(
from: &T::CrossAccountId,
) -> uint256
where
@@ -242,7 +242,7 @@
}
/// Convert `uint256` to `CrossAccountId`.
- pub fn convert_uint256_to_cross_account<T: pallet_evm::account::Config>(
+ pub fn convert_uint256_to_cross_account<T: pallet_evm::Config>(
from: uint256,
) -> T::CrossAccountId
where
node/cli/Cargo.tomldiffbeforeafterboth--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -309,13 +309,13 @@
jsonrpsee = { version = "0.15.1", features = ["server", "macros"] }
tokio = { version = "1.19.2", features = ["time"] }
-fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fc-rpc-core = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-consensus = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-mapping-sync = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-db = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
unique-rpc = { default-features = false, path = "../rpc" }
app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
node/cli/src/service.rsdiffbeforeafterboth--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -45,7 +45,8 @@
use cumulus_relay_chain_interface::{RelayChainError, RelayChainInterface, RelayChainResult};
use cumulus_relay_chain_rpc_interface::{RelayChainRpcInterface, create_client_and_start_worker};
-// Substrate Imports
+// Substrate ImportsA
+use sp_api::BlockT;
use sc_executor::NativeElseWasmExecutor;
use sc_executor::NativeExecutionDispatch;
use sc_network::{NetworkService, NetworkBlock};
@@ -159,7 +160,10 @@
}
}
-pub fn open_frontier_backend(config: &Configuration) -> Result<Arc<fc_db::Backend<Block>>, String> {
+pub fn open_frontier_backend<Block: BlockT, C: sp_blockchain::HeaderBackend<Block>>(
+ client: Arc<C>,
+ config: &Configuration,
+) -> Result<Arc<fc_db::Backend<Block>>, String> {
let config_dir = config
.base_path
.as_ref()
@@ -170,6 +174,7 @@
let database_dir = config_dir.join("frontier").join("db");
Ok(Arc::new(fc_db::Backend::<Block>::new(
+ client,
&fc_db::DatabaseSettings {
source: fc_db::DatabaseSource::RocksDb {
path: database_dir,
@@ -285,7 +290,7 @@
let filter_pool: Option<FilterPool> = Some(Arc::new(Mutex::new(BTreeMap::new())));
- let frontier_backend = open_frontier_backend(config)?;
+ let frontier_backend = open_frontier_backend(client.clone(), config)?;
let import_queue = build_import_queue(
client.clone(),
node/rpc/Cargo.tomldiffbeforeafterboth--- a/node/rpc/Cargo.toml
+++ b/node/rpc/Cargo.toml
@@ -40,20 +40,20 @@
substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
tokio = { version = "1.19.2", features = ["macros", "sync"] }
-pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-ethereum = { git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-storage = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-rpc-core = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-db = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fc-mapping-sync = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
pallet-common = { default-features = false, path = "../../pallets/common" }
up-common = { path = "../../primitives/common" }
pallet-unique = { path = "../../pallets/unique" }
uc-rpc = { path = "../../client/rpc" }
up-rpc = { path = "../../primitives/rpc" }
-app-promotion-rpc = { path = "../../primitives/app_promotion_rpc"}
+app-promotion-rpc = { path = "../../primitives/app_promotion_rpc" }
rmrk-rpc = { path = "../../primitives/rmrk-rpc" }
up-data-structs = { default-features = false, path = "../../primitives/data-structs" }
node/rpc/src/lib.rsdiffbeforeafterboth--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -230,6 +230,7 @@
block_data_cache.clone(),
fee_history_cache,
fee_history_limit,
+ 10,
)
.into_rpc(),
)?;
pallets/app-promotion/Cargo.tomldiffbeforeafterboth--- a/pallets/app-promotion/Cargo.toml
+++ b/pallets/app-promotion/Cargo.toml
@@ -47,28 +47,30 @@
################################################################################
# Substrate Dependencies
-codec = { default-features = false, features = ['derive'], package = 'parity-scale-codec', version = '3.1.2' }
-frame-benchmarking = {default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+codec = { default-features = false, features = [
+ 'derive',
+], package = 'parity-scale-codec', version = '3.1.2' }
+frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-frame-system ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-balances ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-timestamp ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-randomness-collective-flip ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm ={ default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-sp-std ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-randomness-collective-flip = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-sp-io ={ default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
+sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
serde = { default-features = false, features = ['derive'], version = '1.0.130' }
################################################################################
# local dependencies
-up-data-structs ={ default-features = false, path = "../../primitives/data-structs" }
-pallet-common ={ default-features = false, path = "../common" }
-pallet-unique ={ default-features = false, path = "../unique" }
-pallet-evm-contract-helpers ={ default-features = false, path = "../evm-contract-helpers" }
-pallet-evm-migration ={ default-features = false, path = "../evm-migration" }
+up-data-structs = { default-features = false, path = "../../primitives/data-structs" }
+pallet-common = { default-features = false, path = "../common" }
+pallet-unique = { default-features = false, path = "../unique" }
+pallet-evm-contract-helpers = { default-features = false, path = "../evm-contract-helpers" }
+pallet-evm-migration = { default-features = false, path = "../evm-migration" }
# [dev-dependencies]
pallets/app-promotion/src/lib.rsdiffbeforeafterboth--- a/pallets/app-promotion/src/lib.rs
+++ b/pallets/app-promotion/src/lib.rs
@@ -102,7 +102,7 @@
use frame_system::pallet_prelude::*;
#[pallet::config]
- pub trait Config: frame_system::Config + pallet_evm::account::Config {
+ pub trait Config: frame_system::Config + pallet_evm::Config {
/// Type to interact with the native token
type Currency: ExtendedLockableCurrency<Self::AccountId>
+ ReservableCurrency<Self::AccountId>;
@@ -274,11 +274,13 @@
if !block_pending.is_empty() {
block_pending.into_iter().for_each(|(staker, amount)| {
- <T::Currency as ReservableCurrency<T::AccountId>>::unreserve(&staker, amount);
+ <<T as Config>::Currency as ReservableCurrency<T::AccountId>>::unreserve(
+ &staker, amount,
+ );
});
}
- T::WeightInfo::on_initialize(counter)
+ <T as Config>::WeightInfo::on_initialize(counter)
}
}
@@ -297,7 +299,7 @@
/// # Arguments
///
/// * `admin`: account of the new admin.
- #[pallet::weight(T::WeightInfo::set_admin_address())]
+ #[pallet::weight(<T as Config>::WeightInfo::set_admin_address())]
pub fn set_admin_address(origin: OriginFor<T>, admin: T::CrossAccountId) -> DispatchResult {
ensure_root(origin)?;
@@ -315,7 +317,7 @@
/// # Arguments
///
/// * `amount`: in native tokens.
- #[pallet::weight(T::WeightInfo::stake())]
+ #[pallet::weight(<T as Config>::WeightInfo::stake())]
pub fn stake(staker: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {
let staker_id = ensure_signed(staker)?;
@@ -388,7 +390,7 @@
/// Moves the sum of all stakes to the `reserved` state.
/// After the end of `PendingInterval` this sum becomes completely
/// free for further use.
- #[pallet::weight(T::WeightInfo::unstake())]
+ #[pallet::weight(<T as Config>::WeightInfo::unstake())]
pub fn unstake(staker: OriginFor<T>) -> DispatchResultWithPostInfo {
let staker_id = ensure_signed(staker)?;
@@ -421,7 +423,10 @@
Self::unlock_balance(&staker_id, total_staked)?;
- <T::Currency as ReservableCurrency<T::AccountId>>::reserve(&staker_id, total_staked)?;
+ <<T as Config>::Currency as ReservableCurrency<T::AccountId>>::reserve(
+ &staker_id,
+ total_staked,
+ )?;
TotalStaked::<T>::set(
TotalStaked::<T>::get()
@@ -445,7 +450,7 @@
/// # Arguments
///
/// * `collection_id`: ID of the collection that will be sponsored by `pallet_id`
- #[pallet::weight(T::WeightInfo::sponsor_collection())]
+ #[pallet::weight(<T as Config>::WeightInfo::sponsor_collection())]
pub fn sponsor_collection(
admin: OriginFor<T>,
collection_id: CollectionId,
@@ -470,7 +475,7 @@
/// # Arguments
///
/// * `collection_id`: ID of the collection that is sponsored by `pallet_id`
- #[pallet::weight(T::WeightInfo::stop_sponsoring_collection())]
+ #[pallet::weight(<T as Config>::WeightInfo::stop_sponsoring_collection())]
pub fn stop_sponsoring_collection(
admin: OriginFor<T>,
collection_id: CollectionId,
@@ -499,7 +504,7 @@
/// # Arguments
///
/// * `contract_id`: the contract address that will be sponsored by `pallet_id`
- #[pallet::weight(T::WeightInfo::sponsor_contract())]
+ #[pallet::weight(<T as Config>::WeightInfo::sponsor_contract())]
pub fn sponsor_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {
let admin_id = ensure_signed(admin)?;
@@ -525,7 +530,7 @@
/// # Arguments
///
/// * `contract_id`: the contract address that is sponsored by `pallet_id`
- #[pallet::weight(T::WeightInfo::stop_sponsoring_contract())]
+ #[pallet::weight(<T as Config>::WeightInfo::stop_sponsoring_contract())]
pub fn stop_sponsoring_contract(admin: OriginFor<T>, contract_id: H160) -> DispatchResult {
let admin_id = ensure_signed(admin)?;
@@ -555,7 +560,7 @@
/// # Arguments
///
/// * `stakers_number`: the number of stakers for which recalculation will be performed
- #[pallet::weight(T::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]
+ #[pallet::weight(<T as Config>::WeightInfo::payout_stakers(stakers_number.unwrap_or(20) as u32))]
pub fn payout_stakers(admin: OriginFor<T>, stakers_number: Option<u8>) -> DispatchResult {
let admin_id = ensure_signed(admin)?;
@@ -589,7 +594,7 @@
let flush_stake = || -> DispatchResult {
if let Some(last_id) = &*last_id.borrow() {
if !income_acc.borrow().is_zero() {
- <T::Currency as Currency<T::AccountId>>::transfer(
+ <<T as Config>::Currency as Currency<T::AccountId>>::transfer(
&T::TreasuryAccountId::get(),
last_id,
*income_acc.borrow(),
@@ -700,9 +705,12 @@
/// - `amount`: amount of locked funds.
fn set_lock_unchecked(staker: &T::AccountId, amount: BalanceOf<T>) {
if amount.is_zero() {
- <T::Currency as LockableCurrency<T::AccountId>>::remove_lock(LOCK_IDENTIFIER, &staker);
+ <<T as Config>::Currency as LockableCurrency<T::AccountId>>::remove_lock(
+ LOCK_IDENTIFIER,
+ &staker,
+ );
} else {
- <T::Currency as LockableCurrency<T::AccountId>>::set_lock(
+ <<T as Config>::Currency as LockableCurrency<T::AccountId>>::set_lock(
LOCK_IDENTIFIER,
staker,
amount,
@@ -717,7 +725,7 @@
pub fn get_locked_balance(
staker: impl EncodeLike<T::AccountId>,
) -> Option<BalanceLock<BalanceOf<T>>> {
- <T::Currency as ExtendedLockableCurrency<T::AccountId>>::locks(staker)
+ <<T as Config>::Currency as ExtendedLockableCurrency<T::AccountId>>::locks(staker)
.into_iter()
.find(|l| l.id == LOCK_IDENTIFIER)
}
pallets/common/Cargo.tomldiffbeforeafterboth--- a/pallets/common/Cargo.toml
+++ b/pallets/common/Cargo.toml
@@ -17,12 +17,12 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
ethereum = { version = "0.12.0", default-features = false }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
serde = { version = "1.0.130", default-features = false }
scale-info = { version = "2.0.1", default-features = false, features = [
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -17,7 +17,7 @@
//! The module contains a number of functions for converting and checking ethereum identifiers.
use evm_coder::types::{uint256, address};
-pub use pallet_evm::account::{Config, CrossAccountId};
+pub use pallet_evm::{Config, account::CrossAccountId};
use sp_core::H160;
use up_data_structs::CollectionId;
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -342,7 +342,6 @@
#[frame_support::pallet]
pub mod pallet {
use super::*;
- use pallet_evm::account;
use dispatch::CollectionDispatch;
use frame_support::{Blake2_128Concat, pallet_prelude::*, storage::Key, traits::StorageVersion};
use frame_system::pallet_prelude::*;
@@ -353,11 +352,7 @@
#[pallet::config]
pub trait Config:
- frame_system::Config
- + pallet_evm_coder_substrate::Config
- + pallet_evm::Config
- + TypeInfo
- + account::Config
+ frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::Config + TypeInfo
{
/// Weight information for functions of this pallet.
type WeightInfo: WeightInfo;
pallets/configuration/Cargo.tomldiffbeforeafterboth--- a/pallets/configuration/Cargo.toml
+++ b/pallets/configuration/Cargo.toml
@@ -16,7 +16,7 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-arithmetic = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
smallvec = "1.6.1"
[features]
pallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-coder-substrate/Cargo.toml
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -12,8 +12,8 @@
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
ethereum = { version = "0.12.0", default-features = false }
evm-coder = { default-features = false, path = "../../crates/evm-coder" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
pallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-contract-helpers/Cargo.toml
+++ b/pallets/evm-contract-helpers/Cargo.toml
@@ -19,8 +19,8 @@
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
# Unique
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.30" }
# Locals
pallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/lib.rs
+++ b/pallets/evm-contract-helpers/src/lib.rs
@@ -41,7 +41,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::Config
{
/// Overarching event type.
type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
pallets/evm-migration/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-migration/Cargo.toml
+++ b/pallets/evm-migration/Cargo.toml
@@ -16,8 +16,8 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
[dependencies.codec]
default-features = false
pallets/evm-transaction-payment/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-transaction-payment/Cargo.toml
+++ b/pallets/evm-transaction-payment/Cargo.toml
@@ -14,11 +14,11 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
up-sponsorship = { version = "0.1.0", default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = "polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
[dependencies.codec]
default-features = false
pallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-transaction-payment/src/lib.rs
+++ b/pallets/evm-transaction-payment/src/lib.rs
@@ -44,7 +44,7 @@
}
#[pallet::config]
- pub trait Config: frame_system::Config + pallet_evm::account::Config {
+ pub trait Config: frame_system::Config + pallet_evm::Config {
/// Loosly-coupled handlers for evm call sponsoring
type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, CallContext>;
}
pallets/fungible/Cargo.tomldiffbeforeafterboth--- a/pallets/fungible/Cargo.toml
+++ b/pallets/fungible/Cargo.toml
@@ -23,7 +23,7 @@
pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
ethereum = { version = "0.12.0", default-features = false }
frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -106,7 +106,7 @@
pub mod erc;
pub mod weights;
-pub type CreateItemData<T> = (<T as pallet_evm::account::Config>::CrossAccountId, u128);
+pub type CreateItemData<T> = (<T as pallet_evm::Config>::CrossAccountId, u128);
pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
#[frame_support::pallet]
pallets/nonfungible/Cargo.tomldiffbeforeafterboth--- a/pallets/nonfungible/Cargo.toml
+++ b/pallets/nonfungible/Cargo.toml
@@ -16,7 +16,7 @@
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
pallet-common = { default-features = false, path = '../common' }
pallet-structure = { default-features = false, path = '../structure' }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -127,7 +127,7 @@
pub mod erc;
pub mod weights;
-pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;
+pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::Config>::CrossAccountId>;
pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
/// Token data, stored independently from other data used to describe it
pallets/proxy-rmrk-core/Cargo.tomldiffbeforeafterboth--- a/pallets/proxy-rmrk-core/Cargo.toml
+++ b/pallets/proxy-rmrk-core/Cargo.toml
@@ -20,7 +20,7 @@
pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
pallet-structure = { default-features = false, path = "../../pallets/structure" }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
scale-info = { version = "2.0.1", default-features = false, features = [
pallets/proxy-rmrk-core/src/lib.rsdiffbeforeafterboth1// 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/>.1617//! # RMRK Core Proxy Pallet18//!19//! A pallet used as proxy for RMRK Core (<https://rmrk-team.github.io/rmrk-substrate/#/pallets/rmrk-core>).20//!21//! - [`Config`]22//! - [`Call`]23//! - [`Pallet`]24//!25//! ## Overview26//!27//! The RMRK Core Proxy pallet mirrors the functionality of RMRK Core,28//! binding its externalities to Unique's own underlying structure.29//! It is purposed to mimic RMRK Core exactly, allowing seamless integrations30//! of solutions based on RMRK.31//!32//! RMRK Core itself contains essential functionality for RMRK's nested and33//! multi-resourced NFTs.34//!35//! *Note*, that while RMRK itself is subject to active development and restructuring,36//! the proxy may be caught temporarily out of date.37//!38//! ### What is RMRK?39//!40//! RMRK is a set of NFT standards which compose several "NFT 2.0 lego" primitives.41//! Putting these legos together allows a user to create NFT systems of arbitrary complexity.42//!43//! Meaning, RMRK NFTs are dynamic, able to nest into each other and form a hierarchy,44//! make use of specific changeable and partially shared metadata in the form of resources,45//! and more.46//!47//! Visit RMRK documentation and repositories to learn more:48//! - Docs: <https://docs.rmrk.app/getting-started/>49//! - FAQ: <https://coda.io/@rmrk/faq>50//! - Substrate code repository: <https://github.com/rmrk-team/rmrk-substrate>51//! - RMRK specification repository: <https://github.com/rmrk-team/rmrk-spec>52//!53//! ## Terminology54//!55//! For more information on RMRK, see RMRK's own documentation.56//!57//! ### Intro to RMRK58//!59//! - **Resource:** Additional piece of metadata of an NFT usually serving to add60//! a piece of media on top of the root metadata (NFT's own), be it a different wing61//! on the root template bird or something entirely unrelated.62//!63//! - **Base:** A list of possible "components" - Parts, a combination of which can64//! be appended/equipped to/on an NFT.65//!66//! - **Part:** Something that, together with other Parts, can constitute an NFT.67//! Parts are defined in the Base to which they belong. Parts can be either68//! of the `slot` type or `fixed` type. Slots are intended for equippables.69//! Note that "part of something" and "Part of a Base" can be easily confused,70//! and so in this documentation these words are distinguished by the capital letter.71//!72//! - **Theme:** Named objects of variable => value pairs which get interpolated into73//! the Base's `themable` Parts. Themes can hold any value, but are often represented74//! in RMRK's examples as colors applied to visible Parts.75//!76//! ### Peculiarities in Unique77//!78//! - **Scoped properties:** Properties that are normally obscured from users.79//! Their purpose is to contain structured metadata that was not included in the Unique standard80//! for collections and tokens, meant to be operated on by proxies and other outliers.81//! Scoped property keys are prefixed with `some-scope:`, where `some-scope` is82//! an arbitrary keyword, like "rmrk". `:` is considered an unacceptable symbol in user-defined83//! properties, which, along with other safeguards, makes scoped ones impossible to tamper with.84//!85//! - **Auxiliary properties:** A slightly different structure of properties,86//! trading universality of use for more convenient storage, writes and access.87//! Meant to be inaccessible to end users.88//!89//! ## Proxy Implementation90//!91//! An external user is supposed to be able to utilize this proxy as they would92//! utilize RMRK, and get exactly the same results. Normally, Unique transactions93//! are off-limits to RMRK collections and tokens, and vice versa. However,94//! the information stored on chain can be freely interpreted by storage reads and Unique RPCs.95//!96//! ### ID Mapping97//!98//! RMRK's collections' IDs are counted independently of Unique's and start at 0.99//! Note that tokens' IDs still start at 1.100//! The collections themselves, as well as tokens, are stored as Unique collections,101//! and thus RMRK IDs are mapped to Unique IDs (but not vice versa).102//!103//! ### External/Internal Collection Insulation104//!105//! A Unique transaction cannot target collections purposed for RMRK,106//! and they are flagged as `external` to specify that. On the other hand,107//! due to the mapping, RMRK transactions and RPCs simply cannot reach Unique collections.108//!109//! ### Native Properties110//!111//! Many of RMRK's native parameters are stored as scoped properties of a collection112//! or an NFT on the chain. Scoped properties are prefixed with `rmrk:`, where `:`113//! is an unacceptable symbol in user-defined properties, which, along with other safeguards,114//! makes them impossible to tamper with.115//!116//! ### Collection and NFT Types, or Base, Parts and Themes Handling117//!118//! RMRK introduces the concept of a Base, which is a catalogue of Parts,119//! possible components of an NFT. Due to its similarity with the functionality120//! of a token collection, a Base is stored and handled as one, and the Base's Parts and Themes121//! are this collection's NFTs. See [`CollectionType`] and [`NftType`].122//!123//! ## Interface124//!125//! ### Dispatchables126//!127//! - `create_collection` - Create a new collection of NFTs.128//! - `destroy_collection` - Destroy a collection.129//! - `change_collection_issuer` - Change the issuer of a collection.130//! Analogous to Unique's collection's [`owner`](up_data_structs::Collection).131//! - `lock_collection` - "Lock" the collection and prevent new token creation. **Cannot be undone.**132//! - `mint_nft` - Mint an NFT in a specified collection.133//! - `burn_nft` - Burn an NFT, destroying it and its nested tokens.134//! - `send` - Transfer an NFT from an account/NFT A to another account/NFT B.135//! - `accept_nft` - Accept an NFT sent from another account to self or an owned NFT.136//! - `reject_nft` - Reject an NFT sent from another account to self or owned NFT and **burn it**.137//! - `accept_resource` - Accept the addition of a newly created pending resource to an existing NFT.138//! - `accept_resource_removal` - Accept the removal of a removal-pending resource from an NFT.139//! - `set_property` - Add or edit a custom user property of a token or a collection.140//! - `set_priority` - Set a different order of resource priorities for an NFT.141//! - `add_basic_resource` - Create and set/propose a basic resource for an NFT.142//! - `add_composable_resource` - Create and set/propose a composable resource for an NFT.143//! - `add_slot_resource` - Create and set/propose a slot resource for an NFT.144//! - `remove_resource` - Remove and erase a resource from an NFT.145146#![cfg_attr(not(feature = "std"), no_std)]147148use frame_support::{pallet_prelude::*, BoundedVec, dispatch::DispatchResult};149use frame_system::{pallet_prelude::*, ensure_signed};150use sp_runtime::{DispatchError, Permill, traits::StaticLookup};151use sp_std::{152 vec::Vec,153 collections::{btree_set::BTreeSet, btree_map::BTreeMap},154};155use up_data_structs::{*, mapping::TokenAddressMapping};156use pallet_common::{157 Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,158};159use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};160use pallet_structure::{Pallet as PalletStructure, Error as StructureError};161use pallet_evm::account::CrossAccountId;162use core::convert::AsRef;163164pub use pallet::*;165166#[cfg(feature = "runtime-benchmarks")]167pub mod benchmarking;168pub mod misc;169pub mod property;170pub mod rpc;171pub mod weights;172173pub type SelfWeightOf<T> = <T as Config>::WeightInfo;174175use weights::WeightInfo;176use misc::*;177pub use property::*;178179use RmrkProperty::*;180181/// Maximum number of levels of depth in the token nesting tree.182pub const NESTING_BUDGET: u32 = 5;183184type PendingTarget = (CollectionId, TokenId);185type PendingChild = (RmrkCollectionId, RmrkNftId);186type PendingChildrenSet = BTreeSet<PendingChild>;187188type BasesMap = BTreeMap<RmrkBaseId, u32>;189190#[frame_support::pallet]191pub mod pallet {192 use super::*;193 use pallet_evm::account;194195 #[pallet::config]196 pub trait Config:197 frame_system::Config + pallet_common::Config + pallet_nonfungible::Config + account::Config198 {199 /// Overarching event type.200 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;201202 /// The weight information of this pallet.203 type WeightInfo: WeightInfo;204 }205206 /// Latest yet-unused collection ID.207 #[pallet::storage]208 #[pallet::getter(fn collection_index)]209 pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;210211 /// Mapping from RMRK collection ID to Unique's.212 #[pallet::storage]213 pub type UniqueCollectionId<T: Config> =214 StorageMap<_, Twox64Concat, RmrkCollectionId, CollectionId, ValueQuery>;215216 #[pallet::pallet]217 #[pallet::generate_store(pub(super) trait Store)]218 pub struct Pallet<T>(_);219220 #[pallet::event]221 #[pallet::generate_deposit(pub(super) fn deposit_event)]222 pub enum Event<T: Config> {223 CollectionCreated {224 issuer: T::AccountId,225 collection_id: RmrkCollectionId,226 },227 CollectionDestroyed {228 issuer: T::AccountId,229 collection_id: RmrkCollectionId,230 },231 IssuerChanged {232 old_issuer: T::AccountId,233 new_issuer: T::AccountId,234 collection_id: RmrkCollectionId,235 },236 CollectionLocked {237 issuer: T::AccountId,238 collection_id: RmrkCollectionId,239 },240 NftMinted {241 owner: T::AccountId,242 collection_id: RmrkCollectionId,243 nft_id: RmrkNftId,244 },245 NFTBurned {246 owner: T::AccountId,247 nft_id: RmrkNftId,248 },249 NFTSent {250 sender: T::AccountId,251 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,252 collection_id: RmrkCollectionId,253 nft_id: RmrkNftId,254 approval_required: bool,255 },256 NFTAccepted {257 sender: T::AccountId,258 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,259 collection_id: RmrkCollectionId,260 nft_id: RmrkNftId,261 },262 NFTRejected {263 sender: T::AccountId,264 collection_id: RmrkCollectionId,265 nft_id: RmrkNftId,266 },267 PropertySet {268 collection_id: RmrkCollectionId,269 maybe_nft_id: Option<RmrkNftId>,270 key: RmrkKeyString,271 value: RmrkValueString,272 },273 ResourceAdded {274 nft_id: RmrkNftId,275 resource_id: RmrkResourceId,276 },277 ResourceRemoval {278 nft_id: RmrkNftId,279 resource_id: RmrkResourceId,280 },281 ResourceAccepted {282 nft_id: RmrkNftId,283 resource_id: RmrkResourceId,284 },285 ResourceRemovalAccepted {286 nft_id: RmrkNftId,287 resource_id: RmrkResourceId,288 },289 PrioritySet {290 collection_id: RmrkCollectionId,291 nft_id: RmrkNftId,292 },293 }294295 #[pallet::error]296 pub enum Error<T> {297 /* Unique proxy-specific events */298 /// Property of the type of RMRK collection could not be read successfully.299 CorruptedCollectionType,300 // NftTypeEncodeError,301 /// Too many symbols supplied as the property key. The maximum is [256](up_data_structs::MAX_PROPERTY_KEY_LENGTH).302 RmrkPropertyKeyIsTooLong,303 /// Too many bytes supplied as the property value. The maximum is [32768](up_data_structs::MAX_PROPERTY_VALUE_LENGTH).304 RmrkPropertyValueIsTooLong,305 /// Could not find a property by the supplied key.306 RmrkPropertyIsNotFound,307 /// Something went wrong when decoding encoded data from the storage.308 /// Perhaps, there was a wrong key supplied for the type, or the data was improperly stored.309 UnableToDecodeRmrkData,310311 /* RMRK compatible events */312 /// Only destroying collections without tokens is allowed.313 CollectionNotEmpty,314 /// Could not find an ID for a collection. It is likely there were too many collections created on the chain, causing an overflow.315 NoAvailableCollectionId,316 /// Token does not exist, or there is no suitable ID for it, likely too many tokens were created in a collection, causing an overflow.317 NoAvailableNftId,318 /// Collection does not exist, has a wrong type, or does not map to a Unique ID.319 CollectionUnknown,320 /// No permission to perform action.321 NoPermission,322 /// Token is marked as non-transferable, and thus cannot be transferred.323 NonTransferable,324 /// Too many tokens created in the collection, no new ones are allowed.325 CollectionFullOrLocked,326 /// No such resource found.327 ResourceDoesntExist,328 /// If an NFT is sent to a descendant, that would form a nesting loop, an ouroboros.329 /// Sending to self is redundant.330 CannotSendToDescendentOrSelf,331 /// Not the target owner of the sent NFT.332 CannotAcceptNonOwnedNft,333 /// Not the target owner of the sent NFT.334 CannotRejectNonOwnedNft,335 /// NFT was not sent and is not pending.336 CannotRejectNonPendingNft,337 /// Resource is not pending for the operation.338 ResourceNotPending,339 /// Could not find an ID for the resource. It is likely there were too many resources created on an NFT, causing an overflow.340 NoAvailableResourceId,341 }342343 #[pallet::call]344 impl<T: Config> Pallet<T> {345 // todo :refactor replace every collection_id with rmrk_collection_id (and nft_id) in arguments for uniformity?346347 /// Create a new collection of NFTs.348 ///349 /// # Permissions:350 /// * Anyone - will be assigned as the issuer of the collection.351 ///352 /// # Arguments:353 /// - `origin`: sender of the transaction354 /// - `metadata`: Metadata describing the collection, e.g. IPFS hash. Cannot be changed.355 /// - `max`: Optional maximum number of tokens.356 /// - `symbol`: UTF-8 string with token prefix, by which to represent the token in wallets and UIs.357 /// Analogous to Unique's [`token_prefix`](up_data_structs::Collection). Cannot be changed.358 #[pallet::weight(<SelfWeightOf<T>>::create_collection())]359 pub fn create_collection(360 origin: OriginFor<T>,361 metadata: RmrkString,362 max: Option<u32>,363 symbol: RmrkCollectionSymbol,364 ) -> DispatchResult {365 let sender = ensure_signed(origin)?;366367 let limits = CollectionLimits {368 owner_can_transfer: Some(false),369 token_limit: max,370 ..Default::default()371 };372373 let data = CreateCollectionData {374 limits: Some(limits),375 token_prefix: symbol376 .into_inner()377 .try_into()378 .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,379 permissions: Some(CollectionPermissions {380 nesting: Some(NestingPermissions {381 token_owner: true,382 collection_admin: false,383 restricted: None,384 #[cfg(feature = "runtime-benchmarks")]385 permissive: false,386 }),387 ..Default::default()388 }),389 ..Default::default()390 };391392 let unique_collection_id = Self::init_collection(393 T::CrossAccountId::from_sub(sender.clone()),394 data,395 [396 Self::encode_rmrk_property(Metadata, &metadata)?,397 Self::encode_rmrk_property(CollectionType, &misc::CollectionType::Regular)?,398 ]399 .into_iter(),400 )?;401 let rmrk_collection_id = <CollectionIndex<T>>::get();402403 <UniqueCollectionId<T>>::insert(rmrk_collection_id, unique_collection_id);404405 <PalletCommon<T>>::set_scoped_collection_property(406 unique_collection_id,407 RMRK_SCOPE,408 Self::encode_rmrk_property(RmrkInternalCollectionId, &rmrk_collection_id)?,409 )?;410411 <CollectionIndex<T>>::mutate(|n| *n += 1);412413 Self::deposit_event(Event::CollectionCreated {414 issuer: sender,415 collection_id: rmrk_collection_id,416 });417418 Ok(())419 }420421 /// Destroy a collection.422 ///423 /// Only empty collections can be destroyed. If it has any tokens, they must be burned first.424 ///425 /// # Permissions:426 /// * Collection issuer427 ///428 /// # Arguments:429 /// - `origin`: sender of the transaction430 /// - `collection_id`: RMRK ID of the collection to destroy.431 #[pallet::weight(<SelfWeightOf<T>>::destroy_collection())]432 pub fn destroy_collection(433 origin: OriginFor<T>,434 collection_id: RmrkCollectionId,435 ) -> DispatchResult {436 let sender = ensure_signed(origin)?;437 let cross_sender = T::CrossAccountId::from_sub(sender.clone());438439 let collection = Self::get_typed_nft_collection(440 Self::unique_collection_id(collection_id)?,441 misc::CollectionType::Regular,442 )?;443 collection.check_is_external()?;444445 <PalletNft<T>>::destroy_collection(collection, &cross_sender)446 .map_err(Self::map_unique_err_to_proxy)?;447448 Self::deposit_event(Event::CollectionDestroyed {449 issuer: sender,450 collection_id,451 });452453 Ok(())454 }455456 /// Change the issuer of a collection. Analogous to Unique's collection's [`owner`](up_data_structs::Collection).457 ///458 /// # Permissions:459 /// * Collection issuer460 ///461 /// # Arguments:462 /// - `origin`: sender of the transaction463 /// - `collection_id`: RMRK collection ID to change the issuer of.464 /// - `new_issuer`: Collection's new issuer.465 #[pallet::weight(<SelfWeightOf<T>>::change_collection_issuer())]466 pub fn change_collection_issuer(467 origin: OriginFor<T>,468 collection_id: RmrkCollectionId,469 new_issuer: <T::Lookup as StaticLookup>::Source,470 ) -> DispatchResult {471 let sender = ensure_signed(origin)?;472473 let collection = Self::get_nft_collection(Self::unique_collection_id(collection_id)?)?;474 collection.check_is_external()?;475476 let new_issuer = T::Lookup::lookup(new_issuer)?;477478 Self::change_collection_owner(479 Self::unique_collection_id(collection_id)?,480 misc::CollectionType::Regular,481 sender.clone(),482 new_issuer.clone(),483 )?;484485 Self::deposit_event(Event::IssuerChanged {486 old_issuer: sender,487 new_issuer,488 collection_id,489 });490491 Ok(())492 }493494 /// "Lock" the collection and prevent new token creation. Cannot be undone.495 ///496 /// # Permissions:497 /// * Collection issuer498 ///499 /// # Arguments:500 /// - `origin`: sender of the transaction501 /// - `collection_id`: RMRK ID of the collection to lock.502 #[pallet::weight(<SelfWeightOf<T>>::lock_collection())]503 pub fn lock_collection(504 origin: OriginFor<T>,505 collection_id: RmrkCollectionId,506 ) -> DispatchResult {507 let sender = ensure_signed(origin)?;508 let cross_sender = T::CrossAccountId::from_sub(sender.clone());509510 let collection = Self::get_typed_nft_collection(511 Self::unique_collection_id(collection_id)?,512 misc::CollectionType::Regular,513 )?;514 collection.check_is_external()?;515516 Self::check_collection_owner(&collection, &cross_sender)?;517518 let token_count = collection.total_supply();519520 let mut collection = collection.into_inner();521 collection.limits.token_limit = Some(token_count);522 collection.save()?;523524 Self::deposit_event(Event::CollectionLocked {525 issuer: sender,526 collection_id,527 });528529 Ok(())530 }531532 /// Mint an NFT in a specified collection.533 ///534 /// # Permissions:535 /// * Collection issuer536 ///537 /// # Arguments:538 /// - `origin`: sender of the transaction539 /// - `owner`: Owner account of the NFT. If set to None, defaults to the sender (collection issuer).540 /// - `collection_id`: RMRK collection ID for the NFT to be minted within. Cannot be changed.541 /// - `recipient`: Receiver account of the royalty. Has no effect if the `royalty_amount` is not set. Cannot be changed.542 /// - `royalty_amount`: Optional permillage reward from each trade for the `recipient`. Cannot be changed.543 /// - `metadata`: Arbitrary data about an NFT, e.g. IPFS hash. Cannot be changed.544 /// - `transferable`: Can this NFT be transferred? Cannot be changed.545 /// - `resources`: Resource data to be added to the NFT immediately after minting.546 #[pallet::weight(<SelfWeightOf<T>>::mint_nft(resources.as_ref().map(|r| r.len() as u32).unwrap_or(0)))]547 pub fn mint_nft(548 origin: OriginFor<T>,549 owner: Option<T::AccountId>,550 collection_id: RmrkCollectionId,551 recipient: Option<T::AccountId>,552 royalty_amount: Option<Permill>,553 metadata: RmrkString,554 transferable: bool,555 resources: Option<BoundedVec<RmrkResourceTypes, MaxResourcesOnMint>>,556 ) -> DispatchResult {557 let sender = ensure_signed(origin)?;558 let cross_sender = T::CrossAccountId::from_sub(sender.clone());559560 let owner = owner.unwrap_or(sender.clone());561 let cross_owner = T::CrossAccountId::from_sub(owner.clone());562563 let collection = Self::get_typed_nft_collection(564 Self::unique_collection_id(collection_id)?,565 misc::CollectionType::Regular,566 )?;567 collection.check_is_external()?;568569 let royalty_info = royalty_amount.map(|amount| rmrk_traits::RoyaltyInfo {570 recipient: recipient.unwrap_or_else(|| owner.clone()),571 amount,572 });573574 let nft_id = Self::create_nft(575 &cross_sender,576 &cross_owner,577 &collection,578 [579 Self::encode_rmrk_property(TokenType, &NftType::Regular)?,580 Self::encode_rmrk_property(Transferable, &transferable)?,581 Self::encode_rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,582 Self::encode_rmrk_property(RoyaltyInfo, &royalty_info)?,583 Self::encode_rmrk_property(Metadata, &metadata)?,584 Self::encode_rmrk_property(Equipped, &false)?,585 Self::encode_rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,586 Self::encode_rmrk_property(NextResourceId, &(0 as RmrkResourceId))?,587 Self::encode_rmrk_property(PendingChildren, &PendingChildrenSet::new())?,588 Self::encode_rmrk_property(AssociatedBases, &BasesMap::new())?,589 ]590 .into_iter(),591 )592 .map_err(|err| match err {593 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),594 err => Self::map_unique_err_to_proxy(err),595 })?;596597 if let Some(resources) = resources {598 for resource in resources {599 Self::resource_add(sender.clone(), collection.id, nft_id, resource)?;600 }601 }602603 Self::deposit_event(Event::NftMinted {604 owner,605 collection_id,606 nft_id: nft_id.0,607 });608609 Ok(())610 }611612 /// Burn an NFT, destroying it and its nested tokens up to the specified limit.613 /// If the burning budget is exceeded, the transaction is reverted.614 ///615 /// This is the way to burn a nested token as well.616 ///617 /// For more information, see [`burn_recursively`](pallet_nonfungible::pallet::Pallet::burn_recursively).618 ///619 /// # Permissions:620 /// * Token owner621 ///622 /// # Arguments:623 /// - `origin`: sender of the transaction624 /// - `collection_id`: RMRK ID of the collection in which the NFT to burn belongs to.625 /// - `nft_id`: ID of the NFT to be destroyed.626 /// - `max_burns`: Maximum number of tokens to burn, assuming nesting. The transaction627 /// is reverted if there are more tokens to burn in the nesting tree than this number.628 /// This is primarily a mechanism of transaction weight control.629 #[pallet::weight(<SelfWeightOf<T>>::burn_nft(*max_burns))]630 pub fn burn_nft(631 origin: OriginFor<T>,632 collection_id: RmrkCollectionId,633 nft_id: RmrkNftId,634 max_burns: u32,635 ) -> DispatchResult {636 let sender = ensure_signed(origin)?;637 let cross_sender = T::CrossAccountId::from_sub(sender.clone());638639 let collection = Self::get_typed_nft_collection(640 Self::unique_collection_id(collection_id)?,641 misc::CollectionType::Regular,642 )?;643 collection.check_is_external()?;644645 Self::destroy_nft(646 cross_sender,647 Self::unique_collection_id(collection_id)?,648 nft_id.into(),649 max_burns,650 <Error<T>>::NoPermission,651 )652 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;653654 Self::deposit_event(Event::NFTBurned {655 owner: sender,656 nft_id,657 });658659 Ok(())660 }661662 /// Transfer an NFT from an account/NFT A to another account/NFT B.663 /// The token must be transferable. Nesting cannot occur deeper than the [`NESTING_BUDGET`].664 ///665 /// If the target owner is an NFT owned by another account, then the NFT will enter666 /// the pending state and will have to be accepted by the other account.667 ///668 /// # Permissions:669 /// - Token owner670 ///671 /// # Arguments:672 /// - `origin`: sender of the transaction673 /// - `rmrk_collection_id`: RMRK ID of the collection of the NFT to be transferred.674 /// - `rmrk_nft_id`: ID of the NFT to be transferred.675 /// - `new_owner`: New owner of the nft which can be either an account or a NFT.676 #[pallet::weight(<SelfWeightOf<T>>::send())]677 pub fn send(678 origin: OriginFor<T>,679 rmrk_collection_id: RmrkCollectionId,680 rmrk_nft_id: RmrkNftId,681 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,682 ) -> DispatchResult {683 let sender = ensure_signed(origin.clone())?;684 let cross_sender = T::CrossAccountId::from_sub(sender.clone());685686 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;687 let nft_id = rmrk_nft_id.into();688689 let collection =690 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;691 collection.check_is_external()?;692693 let token_data =694 <TokenData<T>>::get((collection_id, nft_id)).ok_or(<Error<T>>::NoAvailableNftId)?;695696 let from = token_data.owner;697698 ensure!(699 Self::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Transferable)?,700 <Error<T>>::NonTransferable701 );702703 ensure!(704 Self::get_nft_property_decoded::<Option<PendingTarget>>(705 collection_id,706 nft_id,707 RmrkProperty::PendingNftAccept708 )?709 .is_none(),710 <Error<T>>::NoPermission711 );712713 let target_owner;714 let approval_required;715716 match new_owner {717 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {718 target_owner = T::CrossAccountId::from_sub(account_id.clone());719 approval_required = false;720 }721 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(722 target_collection_id,723 target_nft_id,724 ) => {725 let target_collection_id = Self::unique_collection_id(target_collection_id)?;726727 let target_nft_budget = budget::Value::new(NESTING_BUDGET);728729 let target_nft_owner = <PalletStructure<T>>::get_checked_topmost_owner(730 target_collection_id,731 target_nft_id.into(),732 Some((collection_id, nft_id)),733 &target_nft_budget,734 )735 .map_err(Self::map_unique_err_to_proxy)?;736737 approval_required = cross_sender != target_nft_owner;738739 if approval_required {740 target_owner = target_nft_owner;741742 <PalletNft<T>>::set_scoped_token_property(743 collection.id,744 nft_id,745 RMRK_SCOPE,746 Self::encode_rmrk_property::<Option<PendingTarget>>(747 PendingNftAccept,748 &Some((target_collection_id, target_nft_id.into())),749 )?,750 )?;751752 Self::insert_pending_child(753 (target_collection_id, target_nft_id.into()),754 (rmrk_collection_id, rmrk_nft_id),755 )?;756 } else {757 target_owner = T::CrossTokenAddressMapping::token_to_address(758 target_collection_id,759 target_nft_id.into(),760 );761 }762 }763 }764765 let src_nft_budget = budget::Value::new(NESTING_BUDGET);766767 <PalletNft<T>>::transfer_from(768 &collection,769 &cross_sender,770 &from,771 &target_owner,772 nft_id,773 &src_nft_budget,774 )775 .map_err(Self::map_unique_err_to_proxy)?;776777 Self::deposit_event(Event::NFTSent {778 sender,779 recipient: new_owner,780 collection_id: rmrk_collection_id,781 nft_id: rmrk_nft_id,782 approval_required,783 });784785 Ok(())786 }787788 /// Accept an NFT sent from another account to self or an owned NFT.789 ///790 /// The NFT in question must be pending, and, thus, be [sent](`Pallet::send`) first.791 ///792 /// # Permissions:793 /// - Token-owner-to-be794 ///795 /// # Arguments:796 /// - `origin`: sender of the transaction797 /// - `rmrk_collection_id`: RMRK collection ID of the NFT to be accepted.798 /// - `rmrk_nft_id`: ID of the NFT to be accepted.799 /// - `new_owner`: Either the sender's account ID or a sender-owned NFT,800 /// whichever the accepted NFT was sent to.801 #[pallet::weight(<SelfWeightOf<T>>::accept_nft())]802 pub fn accept_nft(803 origin: OriginFor<T>,804 rmrk_collection_id: RmrkCollectionId,805 rmrk_nft_id: RmrkNftId,806 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,807 ) -> DispatchResult {808 let sender = ensure_signed(origin.clone())?;809 let cross_sender = T::CrossAccountId::from_sub(sender.clone());810811 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;812 let nft_id = rmrk_nft_id.into();813814 let collection =815 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;816 collection.check_is_external()?;817818 let new_cross_owner = match new_owner {819 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {820 T::CrossAccountId::from_sub(account_id.clone())821 }822 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(823 target_collection_id,824 target_nft_id,825 ) => {826 let target_collection_id = Self::unique_collection_id(target_collection_id)?;827828 T::CrossTokenAddressMapping::token_to_address(829 target_collection_id,830 TokenId(target_nft_id),831 )832 }833 };834835 let budget = budget::Value::new(NESTING_BUDGET);836837 <PalletNft<T>>::transfer(838 &collection,839 &cross_sender,840 &new_cross_owner,841 nft_id,842 &budget,843 )844 .map_err(|err| {845 if err == <CommonError<T>>::UserIsNotAllowedToNest.into() {846 <Error<T>>::CannotAcceptNonOwnedNft.into()847 } else {848 Self::map_unique_err_to_proxy(err)849 }850 })?;851852 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(853 collection_id,854 nft_id,855 RmrkProperty::PendingNftAccept,856 )?;857858 if let Some(pending_target) = pending_target {859 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?;860861 <PalletNft<T>>::set_scoped_token_property(862 collection.id,863 nft_id,864 RMRK_SCOPE,865 Self::encode_rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,866 )?;867 }868869 Self::deposit_event(Event::NFTAccepted {870 sender,871 recipient: new_owner,872 collection_id: rmrk_collection_id,873 nft_id: rmrk_nft_id,874 });875876 Ok(())877 }878879 /// Reject an NFT sent from another account to self or owned NFT.880 /// The NFT in question will not be sent back and burnt instead.881 ///882 /// The NFT in question must be pending, and, thus, be [sent](`Pallet::send`) first.883 ///884 /// # Permissions:885 /// - Token-owner-to-be-not886 ///887 /// # Arguments:888 /// - `origin`: sender of the transaction889 /// - `rmrk_collection_id`: RMRK ID of the NFT to be rejected.890 /// - `rmrk_nft_id`: ID of the NFT to be rejected.891 #[pallet::weight(<SelfWeightOf<T>>::reject_nft())]892 pub fn reject_nft(893 origin: OriginFor<T>,894 rmrk_collection_id: RmrkCollectionId,895 rmrk_nft_id: RmrkNftId,896 ) -> DispatchResult {897 let sender = ensure_signed(origin)?;898 let cross_sender = T::CrossAccountId::from_sub(sender.clone());899900 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;901 let nft_id = rmrk_nft_id.into();902903 let collection =904 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;905 collection.check_is_external()?;906907 ensure!(908 <TokenData<T>>::get((collection_id, nft_id)).is_some(),909 <Error<T>>::NoAvailableNftId910 );911912 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(913 collection_id,914 nft_id,915 RmrkProperty::PendingNftAccept,916 )?;917918 match pending_target {919 Some(pending_target) => {920 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?921 }922 None => return Err(<Error<T>>::CannotRejectNonPendingNft.into()),923 }924925 Self::destroy_nft(926 cross_sender,927 collection_id,928 nft_id,929 NESTING_BUDGET,930 <Error<T>>::CannotRejectNonOwnedNft,931 )932 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;933934 Self::deposit_event(Event::NFTRejected {935 sender,936 collection_id: rmrk_collection_id,937 nft_id: rmrk_nft_id,938 });939940 Ok(())941 }942943 /// Accept the addition of a newly created pending resource to an existing NFT.944 ///945 /// This transaction is needed when a resource is created and assigned to an NFT946 /// by a non-owner, i.e. the collection issuer, with one of the947 /// [`add_...` transactions](Pallet::add_basic_resource).948 ///949 /// # Permissions:950 /// - Token owner951 ///952 /// # Arguments:953 /// - `origin`: sender of the transaction954 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.955 /// - `rmrk_nft_id`: ID of the NFT with a pending resource to be accepted.956 /// - `resource_id`: ID of the newly created pending resource.957 /// accept the addition of a new resource to an existing NFT958 #[pallet::weight(<SelfWeightOf<T>>::accept_resource())]959 pub fn accept_resource(960 origin: OriginFor<T>,961 rmrk_collection_id: RmrkCollectionId,962 rmrk_nft_id: RmrkNftId,963 resource_id: RmrkResourceId,964 ) -> DispatchResult {965 let sender = ensure_signed(origin)?;966 let cross_sender = T::CrossAccountId::from_sub(sender);967968 let collection_id = Self::unique_collection_id(rmrk_collection_id)969 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;970 let collection =971 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;972 collection.check_is_external()?;973974 let nft_id = rmrk_nft_id.into();975976 let budget = budget::Value::new(NESTING_BUDGET);977978 let nft_owner =979 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)980 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;981982 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {983 ensure!(res.pending, <Error<T>>::ResourceNotPending);984 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);985986 res.pending = false;987988 Ok(())989 })?;990991 Self::deposit_event(Event::<T>::ResourceAccepted {992 nft_id: rmrk_nft_id,993 resource_id,994 });995996 Ok(())997 }998999 /// Accept the removal of a removal-pending resource from an NFT.1000 ///1001 /// This transaction is needed when a non-owner, i.e. the collection issuer,1002 /// requests a [removal](`Pallet::remove_resource`) of a resource from an NFT.1003 ///1004 /// # Permissions:1005 /// - Token owner1006 ///1007 /// # Arguments:1008 /// - `origin`: sender of the transaction1009 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1010 /// - `rmrk_nft_id`: ID of the NFT with a resource to be removed.1011 /// - `resource_id`: ID of the removal-pending resource.1012 #[pallet::weight(<SelfWeightOf<T>>::accept_resource_removal())]1013 pub fn accept_resource_removal(1014 origin: OriginFor<T>,1015 rmrk_collection_id: RmrkCollectionId,1016 rmrk_nft_id: RmrkNftId,1017 resource_id: RmrkResourceId,1018 ) -> DispatchResult {1019 let sender = ensure_signed(origin)?;1020 let cross_sender = T::CrossAccountId::from_sub(sender);10211022 let collection_id = Self::unique_collection_id(rmrk_collection_id)1023 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;1024 let collection =1025 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1026 collection.check_is_external()?;10271028 let nft_id = rmrk_nft_id.into();10291030 let budget = budget::Value::new(NESTING_BUDGET);10311032 let nft_owner =1033 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)1034 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;10351036 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);10371038 let resource_id_key = Self::get_scoped_property_key(ResourceId(resource_id))?;10391040 let resource_info = <PalletNft<T>>::token_aux_property((1041 collection_id,1042 nft_id,1043 RMRK_SCOPE,1044 resource_id_key.clone(),1045 ))1046 .ok_or(<Error<T>>::ResourceDoesntExist)?;10471048 let resource_info: RmrkResourceInfo = Self::decode_property_value(&resource_info)?;10491050 ensure!(1051 resource_info.pending_removal,1052 <Error<T>>::ResourceNotPending1053 );10541055 <PalletNft<T>>::remove_token_aux_property(1056 collection_id,1057 nft_id,1058 RMRK_SCOPE,1059 resource_id_key,1060 );10611062 if let RmrkResourceTypes::Composable(resource) = resource_info.resource {1063 let base_id = resource.base;10641065 Self::remove_associated_base_id(collection_id, nft_id, base_id)?;1066 }10671068 Self::deposit_event(Event::<T>::ResourceRemovalAccepted {1069 nft_id: rmrk_nft_id,1070 resource_id,1071 });10721073 Ok(())1074 }10751076 /// Add or edit a custom user property, a key-value pair, describing the metadata1077 /// of a token or a collection, on either one of these.1078 ///1079 /// Note that in this proxy implementation many details regarding RMRK are stored1080 /// as scoped properties prefixed with "rmrk:", normally inaccessible1081 /// to external transactions and RPCs.1082 ///1083 /// # Permissions:1084 /// - Collection issuer - in case of collection property1085 /// - Token owner - in case of NFT property1086 ///1087 /// # Arguments:1088 /// - `origin`: sender of the transaction1089 /// - `rmrk_collection_id`: RMRK collection ID.1090 /// - `maybe_nft_id`: Optional ID of the NFT. If left empty, then the property is set for the collection.1091 /// - `key`: Key of the custom property to be referenced by.1092 /// - `value`: Value of the custom property to be stored.1093 #[pallet::weight(<SelfWeightOf<T>>::set_property())]1094 pub fn set_property(1095 origin: OriginFor<T>,1096 #[pallet::compact] rmrk_collection_id: RmrkCollectionId,1097 maybe_nft_id: Option<RmrkNftId>,1098 key: RmrkKeyString,1099 value: RmrkValueString,1100 ) -> DispatchResult {1101 let sender = ensure_signed(origin)?;1102 let sender = T::CrossAccountId::from_sub(sender);11031104 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1105 let collection =1106 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1107 collection.check_is_external()?;11081109 let budget = budget::Value::new(NESTING_BUDGET);11101111 match maybe_nft_id {1112 Some(nft_id) => {1113 let token_id: TokenId = nft_id.into();11141115 Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;1116 Self::ensure_nft_owner(collection_id, token_id, &sender, &budget)?;11171118 <PalletNft<T>>::set_scoped_token_property(1119 collection_id,1120 token_id,1121 RMRK_SCOPE,1122 Self::encode_rmrk_property(UserProperty(key.as_slice()), &value)?,1123 )?;1124 }1125 None => {1126 let collection = Self::get_typed_nft_collection(1127 collection_id,1128 misc::CollectionType::Regular,1129 )?;11301131 Self::check_collection_owner(&collection, &sender)?;11321133 <PalletCommon<T>>::set_scoped_collection_property(1134 collection_id,1135 RMRK_SCOPE,1136 Self::encode_rmrk_property(UserProperty(key.as_slice()), &value)?,1137 )?;1138 }1139 }11401141 Self::deposit_event(Event::PropertySet {1142 collection_id: rmrk_collection_id,1143 maybe_nft_id,1144 key,1145 value,1146 });11471148 Ok(())1149 }11501151 /// Set a different order of resource priorities for an NFT. Priorities can be used,1152 /// for example, for order of rendering.1153 ///1154 /// Note that the priorities are not updated automatically, and are an empty vector1155 /// by default. There is no pre-set definition for the order to be particular,1156 /// it can be interpreted arbitrarily use-case by use-case.1157 ///1158 /// # Permissions:1159 /// - Token owner1160 ///1161 /// # Arguments:1162 /// - `origin`: sender of the transaction1163 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1164 /// - `rmrk_nft_id`: ID of the NFT to rearrange resource priorities for.1165 /// - `priorities`: Ordered vector of resource IDs.1166 #[pallet::weight(<SelfWeightOf<T>>::set_priority())]1167 pub fn set_priority(1168 origin: OriginFor<T>,1169 rmrk_collection_id: RmrkCollectionId,1170 rmrk_nft_id: RmrkNftId,1171 priorities: BoundedVec<RmrkResourceId, RmrkMaxPriorities>,1172 ) -> DispatchResult {1173 let sender = ensure_signed(origin)?;1174 let sender = T::CrossAccountId::from_sub(sender);11751176 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1177 let nft_id = rmrk_nft_id.into();11781179 let collection =1180 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1181 collection.check_is_external()?;11821183 let budget = budget::Value::new(NESTING_BUDGET);11841185 Self::ensure_nft_type(collection_id, nft_id, NftType::Regular)?;1186 Self::ensure_nft_owner(collection_id, nft_id, &sender, &budget)?;11871188 <PalletNft<T>>::set_scoped_token_property(1189 collection_id,1190 nft_id,1191 RMRK_SCOPE,1192 Self::encode_rmrk_property(ResourcePriorities, &priorities.into_inner())?,1193 )?;11941195 Self::deposit_event(Event::<T>::PrioritySet {1196 collection_id: rmrk_collection_id,1197 nft_id: rmrk_nft_id,1198 });11991200 Ok(())1201 }12021203 /// Create and set/propose a basic resource for an NFT.1204 ///1205 /// A basic resource is the simplest, lacking a Base and anything that comes with it.1206 /// See RMRK docs for more information and examples.1207 ///1208 /// # Permissions:1209 /// - Collection issuer - if not the token owner, adding the resource will warrant1210 /// the owner's [acceptance](Pallet::accept_resource).1211 ///1212 /// # Arguments:1213 /// - `origin`: sender of the transaction1214 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1215 /// - `nft_id`: ID of the NFT to assign a resource to.1216 /// - `resource`: Data of the resource to be created.1217 #[pallet::weight(<SelfWeightOf<T>>::add_basic_resource())]1218 pub fn add_basic_resource(1219 origin: OriginFor<T>,1220 rmrk_collection_id: RmrkCollectionId,1221 nft_id: RmrkNftId,1222 resource: RmrkBasicResource,1223 ) -> DispatchResult {1224 let sender = ensure_signed(origin.clone())?;12251226 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1227 let collection =1228 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1229 collection.check_is_external()?;12301231 let resource_id = Self::resource_add(1232 sender,1233 collection_id,1234 nft_id.into(),1235 RmrkResourceTypes::Basic(resource),1236 )?;12371238 Self::deposit_event(Event::ResourceAdded {1239 nft_id,1240 resource_id,1241 });1242 Ok(())1243 }12441245 /// Create and set/propose a composable resource for an NFT.1246 ///1247 /// A composable resource links to a Base and has a subset of its Parts it is composed of.1248 /// See RMRK docs for more information and examples.1249 ///1250 /// # Permissions:1251 /// - Collection issuer - if not the token owner, adding the resource will warrant1252 /// the owner's [acceptance](Pallet::accept_resource).1253 ///1254 /// # Arguments:1255 /// - `origin`: sender of the transaction1256 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1257 /// - `nft_id`: ID of the NFT to assign a resource to.1258 /// - `resource`: Data of the resource to be created.1259 #[pallet::weight(<SelfWeightOf<T>>::add_composable_resource())]1260 pub fn add_composable_resource(1261 origin: OriginFor<T>,1262 rmrk_collection_id: RmrkCollectionId,1263 nft_id: RmrkNftId,1264 resource: RmrkComposableResource,1265 ) -> DispatchResult {1266 let sender = ensure_signed(origin.clone())?;12671268 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1269 let collection =1270 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1271 collection.check_is_external()?;12721273 let base_id = resource.base;12741275 let resource_id = Self::resource_add(1276 sender,1277 collection_id,1278 nft_id.into(),1279 RmrkResourceTypes::Composable(resource),1280 )?;12811282 <PalletNft<T>>::try_mutate_token_aux_property(1283 collection_id,1284 nft_id.into(),1285 RMRK_SCOPE,1286 Self::get_scoped_property_key(AssociatedBases)?,1287 |value| -> DispatchResult {1288 let mut bases: BasesMap = match value {1289 Some(value) => Self::decode_property_value(value)?,1290 None => BasesMap::new(),1291 };12921293 *bases.entry(base_id).or_insert(0) += 1;12941295 *value = Some(Self::encode_property_value(&bases)?);1296 Ok(())1297 },1298 )?;12991300 Self::deposit_event(Event::ResourceAdded {1301 nft_id,1302 resource_id,1303 });1304 Ok(())1305 }13061307 /// Create and set/propose a slot resource for an NFT.1308 ///1309 /// A slot resource links to a Base and a slot ID in it which it can fit into.1310 /// See RMRK docs for more information and examples.1311 ///1312 /// # Permissions:1313 /// - Collection issuer - if not the token owner, adding the resource will warrant1314 /// the owner's [acceptance](Pallet::accept_resource).1315 ///1316 /// # Arguments:1317 /// - `origin`: sender of the transaction1318 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1319 /// - `nft_id`: ID of the NFT to assign a resource to.1320 /// - `resource`: Data of the resource to be created.1321 #[pallet::weight(<SelfWeightOf<T>>::add_slot_resource())]1322 pub fn add_slot_resource(1323 origin: OriginFor<T>,1324 rmrk_collection_id: RmrkCollectionId,1325 nft_id: RmrkNftId,1326 resource: RmrkSlotResource,1327 ) -> DispatchResult {1328 let sender = ensure_signed(origin.clone())?;13291330 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1331 let collection =1332 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1333 collection.check_is_external()?;13341335 let resource_id = Self::resource_add(1336 sender,1337 collection_id,1338 nft_id.into(),1339 RmrkResourceTypes::Slot(resource),1340 )?;13411342 Self::deposit_event(Event::ResourceAdded {1343 nft_id,1344 resource_id,1345 });1346 Ok(())1347 }13481349 /// Remove and erase a resource from an NFT.1350 ///1351 /// If the sender does not own the NFT, then it will be pending confirmation,1352 /// and will have to be [accepted](Pallet::accept_resource_removal) by the token owner.1353 ///1354 /// # Permissions1355 /// - Collection issuer1356 ///1357 /// # Arguments1358 /// - `origin`: sender of the transaction1359 /// - `rmrk_collection_id`: RMRK ID of a collection to which the NFT making use of the resource belongs to.1360 /// - `nft_id`: ID of the NFT with a resource to be removed.1361 /// - `resource_id`: ID of the resource to be removed.1362 #[pallet::weight(<SelfWeightOf<T>>::remove_resource())]1363 pub fn remove_resource(1364 origin: OriginFor<T>,1365 rmrk_collection_id: RmrkCollectionId,1366 nft_id: RmrkNftId,1367 resource_id: RmrkResourceId,1368 ) -> DispatchResult {1369 let sender = ensure_signed(origin.clone())?;13701371 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1372 let collection =1373 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1374 collection.check_is_external()?;13751376 Self::resource_remove(sender, collection_id, nft_id.into(), resource_id)?;13771378 Self::deposit_event(Event::ResourceRemoval {1379 nft_id,1380 resource_id,1381 });1382 Ok(())1383 }1384 }1385}13861387impl<T: Config> Pallet<T> {1388 /// Transform one of possible RMRK keys into a byte key with a RMRK scope.1389 pub fn get_scoped_property_key(rmrk_key: RmrkProperty) -> Result<PropertyKey, DispatchError> {1390 let key = rmrk_key.to_key::<T>()?;13911392 let scoped_key = RMRK_SCOPE1393 .apply(key)1394 .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)?;13951396 Ok(scoped_key)1397 }13981399 /// Form a Unique property, transforming a RMRK key into bytes (without assigning the scope yet)1400 /// and encoding the value from an arbitrary type into bytes.1401 pub fn encode_rmrk_property<E: Encode>(1402 rmrk_key: RmrkProperty,1403 value: &E,1404 ) -> Result<Property, DispatchError> {1405 let key = rmrk_key.to_key::<T>()?;14061407 let value = Self::encode_property_value(value)?;14081409 let property = Property { key, value };14101411 Ok(property)1412 }14131414 /// Encode property value from an arbitrary type into bytes for storage.1415 pub fn encode_property_value<E: Encode, S: Get<u32>>(1416 value: &E,1417 ) -> Result<BoundedBytes<S>, DispatchError> {1418 let value = value1419 .encode()1420 .try_into()1421 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;14221423 Ok(value)1424 }14251426 /// Decode property value from bytes into an arbitrary type.1427 pub fn decode_property_value<D: Decode, S: Get<u32>>(1428 vec: &BoundedBytes<S>,1429 ) -> Result<D, DispatchError> {1430 vec.decode()1431 .map_err(|_| <Error<T>>::UnableToDecodeRmrkData.into())1432 }14331434 /// Change the limit of a property value byte vector.1435 pub fn rebind<L, S>(vec: &BoundedVec<u8, L>) -> Result<BoundedVec<u8, S>, DispatchError>1436 where1437 BoundedVec<u8, S>: TryFrom<Vec<u8>>,1438 {1439 vec.rebind()1440 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())1441 }14421443 /// Initialize a new NFT collection with certain RMRK-scoped properties.1444 ///1445 /// See [`init_collection`](pallet_nonfungible::pallet::Pallet::init_collection) for more details.1446 fn init_collection(1447 sender: T::CrossAccountId,1448 data: CreateCollectionData<T::AccountId>,1449 properties: impl Iterator<Item = Property>,1450 ) -> Result<CollectionId, DispatchError> {1451 let collection_id = <PalletNft<T>>::init_collection(1452 sender.clone(),1453 sender,1454 data,1455 up_data_structs::CollectionFlags {1456 external: true,1457 ..Default::default()1458 },1459 );14601461 if let Err(DispatchError::Arithmetic(_)) = &collection_id {1462 return Err(<Error<T>>::NoAvailableCollectionId.into());1463 }14641465 <PalletCommon<T>>::set_scoped_collection_properties(1466 collection_id?,1467 RMRK_SCOPE,1468 properties,1469 )?;14701471 collection_id1472 }14731474 /// Mint a new NFT with certain RMRK-scoped properties. Sender must be the collection owner.1475 ///1476 /// See [`create_item`](pallet_nonfungible::pallet::Pallet::create_item) for more details.1477 pub fn create_nft(1478 sender: &T::CrossAccountId,1479 owner: &T::CrossAccountId,1480 collection: &NonfungibleHandle<T>,1481 properties: impl Iterator<Item = Property>,1482 ) -> Result<TokenId, DispatchError> {1483 let data = CreateNftExData {1484 properties: BoundedVec::default(),1485 owner: owner.clone(),1486 };14871488 let budget = budget::Value::new(NESTING_BUDGET);14891490 <PalletNft<T>>::create_item(collection, sender, data, &budget)?;14911492 let nft_id = <PalletNft<T>>::current_token_id(collection.id);14931494 <PalletNft<T>>::set_scoped_token_properties(collection.id, nft_id, RMRK_SCOPE, properties)?;14951496 Ok(nft_id)1497 }14981499 /// Burn an NFT, along with its nested children, limited by `max_burns`. The sender must be the token owner.1500 ///1501 /// See [`burn_recursively`](pallet_nonfungible::pallet::Pallet::burn_recursively) for more details.1502 fn destroy_nft(1503 sender: T::CrossAccountId,1504 collection_id: CollectionId,1505 token_id: TokenId,1506 max_burns: u32,1507 error_if_not_owned: Error<T>,1508 ) -> DispatchResultWithPostInfo {1509 let collection =1510 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;15111512 let token_data =1513 <TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;15141515 let from = token_data.owner;15161517 let owner_check_budget = budget::Value::new(NESTING_BUDGET);15181519 ensure!(1520 <PalletStructure<T>>::check_indirectly_owned(1521 sender.clone(),1522 collection_id,1523 token_id,1524 None,1525 &owner_check_budget1526 )?,1527 error_if_not_owned,1528 );15291530 let burns_budget = budget::Value::new(max_burns);1531 let breadth_budget = budget::Value::new(max_burns);15321533 <PalletNft<T>>::burn_recursively(1534 &collection,1535 &from,1536 token_id,1537 &burns_budget,1538 &breadth_budget,1539 )1540 }15411542 /// Add a sent token pending acceptance to the target owning token as a property.1543 fn insert_pending_child(1544 target: (CollectionId, TokenId),1545 child: (RmrkCollectionId, RmrkNftId),1546 ) -> DispatchResult {1547 Self::mutate_pending_children(target, |pending_children| {1548 pending_children.insert(child);1549 })1550 }15511552 /// Remove a sent token pending acceptance from the target token's properties.1553 fn remove_pending_child(1554 target: (CollectionId, TokenId),1555 child: (RmrkCollectionId, RmrkNftId),1556 ) -> DispatchResult {1557 Self::mutate_pending_children(target, |pending_children| {1558 pending_children.remove(&child);1559 })1560 }15611562 /// Apply a mutation to the property of a token containing sent tokens1563 /// that are currently pending acceptance.1564 fn mutate_pending_children(1565 (target_collection_id, target_nft_id): (CollectionId, TokenId),1566 f: impl FnOnce(&mut PendingChildrenSet),1567 ) -> DispatchResult {1568 <PalletNft<T>>::try_mutate_token_aux_property(1569 target_collection_id,1570 target_nft_id,1571 RMRK_SCOPE,1572 Self::get_scoped_property_key(PendingChildren)?,1573 |pending_children| -> DispatchResult {1574 let mut map = match pending_children {1575 Some(map) => Self::decode_property_value(map)?,1576 None => PendingChildrenSet::new(),1577 };15781579 f(&mut map);15801581 *pending_children = Some(Self::encode_property_value(&map)?);15821583 Ok(())1584 },1585 )1586 }15871588 /// Get an iterator from a token's property containing tokens sent to it1589 /// that are currently pending acceptance.1590 fn iterate_pending_children(1591 collection_id: CollectionId,1592 nft_id: TokenId,1593 ) -> Result<impl Iterator<Item = PendingChild>, DispatchError> {1594 let property = <PalletNft<T>>::token_aux_property((1595 collection_id,1596 nft_id,1597 RMRK_SCOPE,1598 Self::get_scoped_property_key(PendingChildren)?,1599 ));16001601 let pending_children = match property {1602 Some(map) => Self::decode_property_value(&map)?,1603 None => PendingChildrenSet::new(),1604 };16051606 Ok(pending_children.into_iter())1607 }16081609 /// Get incremented resource ID from within an NFT's properties and store the new latest ID.1610 /// Thus, the returned resource ID should be used.1611 ///1612 /// Resource IDs are unique only across an NFT.1613 fn acquire_next_resource_id(1614 collection_id: CollectionId,1615 nft_id: TokenId,1616 ) -> Result<RmrkResourceId, DispatchError> {1617 let resource_id: RmrkResourceId =1618 Self::get_nft_property_decoded(collection_id, nft_id, NextResourceId)?;16191620 let next_id = resource_id1621 .checked_add(1)1622 .ok_or(<Error<T>>::NoAvailableResourceId)?;16231624 <PalletNft<T>>::set_scoped_token_property(1625 collection_id,1626 nft_id,1627 RMRK_SCOPE,1628 Self::encode_rmrk_property(NextResourceId, &next_id)?,1629 )?;16301631 Ok(resource_id)1632 }16331634 /// Create and add a resource for a regular NFT, mark it as pending if the sender1635 /// is not the token owner. The sender must be the collection owner.1636 fn resource_add(1637 sender: T::AccountId,1638 collection_id: CollectionId,1639 nft_id: TokenId,1640 resource: RmrkResourceTypes,1641 ) -> Result<RmrkResourceId, DispatchError> {1642 let collection =1643 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1644 ensure!(collection.owner == sender, Error::<T>::NoPermission);16451646 let sender = T::CrossAccountId::from_sub(sender);1647 let budget = budget::Value::new(NESTING_BUDGET);16481649 let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)1650 .map_err(Self::map_unique_err_to_proxy)?;16511652 let pending = sender != nft_owner;16531654 let id = Self::acquire_next_resource_id(collection_id, nft_id)?;16551656 let resource_info = RmrkResourceInfo {1657 id,1658 resource,1659 pending,1660 pending_removal: false,1661 };16621663 <PalletNft<T>>::try_mutate_token_aux_property(1664 collection_id,1665 nft_id,1666 RMRK_SCOPE,1667 Self::get_scoped_property_key(ResourceId(id))?,1668 |value| -> DispatchResult {1669 *value = Some(Self::encode_property_value(&resource_info)?);16701671 Ok(())1672 },1673 )?;16741675 Ok(id)1676 }16771678 /// Designate a resource for erasure from an NFT, and remove it if the sender is the token owner.1679 /// The sender must be the collection owner.1680 fn resource_remove(1681 sender: T::AccountId,1682 collection_id: CollectionId,1683 nft_id: TokenId,1684 resource_id: RmrkResourceId,1685 ) -> DispatchResult {1686 let collection =1687 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1688 ensure!(collection.owner == sender, Error::<T>::NoPermission);16891690 let resource_id_key = Self::get_scoped_property_key(ResourceId(resource_id))?;16911692 let resource = <PalletNft<T>>::token_aux_property((1693 collection_id,1694 nft_id,1695 RMRK_SCOPE,1696 resource_id_key.clone(),1697 ))1698 .ok_or(<Error<T>>::ResourceDoesntExist)?;16991700 let resource_info: RmrkResourceInfo = Self::decode_property_value(&resource)?;17011702 let budget = up_data_structs::budget::Value::new(NESTING_BUDGET);1703 let topmost_owner =1704 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)?;17051706 let sender = T::CrossAccountId::from_sub(sender);1707 if topmost_owner == sender {1708 <PalletNft<T>>::remove_token_aux_property(1709 collection_id,1710 nft_id,1711 RMRK_SCOPE,1712 Self::get_scoped_property_key(ResourceId(resource_id))?,1713 );17141715 if let RmrkResourceTypes::Composable(resource) = resource_info.resource {1716 let base_id = resource.base;17171718 Self::remove_associated_base_id(collection_id, nft_id, base_id)?;1719 }1720 } else {1721 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {1722 res.pending_removal = true;17231724 Ok(())1725 })?;1726 }17271728 Ok(())1729 }17301731 /// Remove a Base ID from an NFT if they are associated.1732 /// The Base itself is deleted if the number of associated NFTs reaches 0.1733 fn remove_associated_base_id(1734 collection_id: CollectionId,1735 nft_id: TokenId,1736 base_id: RmrkBaseId,1737 ) -> DispatchResult {1738 <PalletNft<T>>::try_mutate_token_aux_property(1739 collection_id,1740 nft_id,1741 RMRK_SCOPE,1742 Self::get_scoped_property_key(AssociatedBases)?,1743 |value| -> DispatchResult {1744 let mut bases: BasesMap = match value {1745 Some(value) => Self::decode_property_value(value)?,1746 None => BasesMap::new(),1747 };17481749 let remaining = bases.get(&base_id);17501751 if let Some(remaining) = remaining {1752 if let Some(0) | None = remaining.checked_sub(1) {1753 bases.remove(&base_id);1754 }1755 }17561757 *value = Some(Self::encode_property_value(&bases)?);1758 Ok(())1759 },1760 )1761 }17621763 /// Apply a mutation to a resource stored in the token properties of an NFT.1764 fn try_mutate_resource_info(1765 collection_id: CollectionId,1766 nft_id: TokenId,1767 resource_id: RmrkResourceId,1768 f: impl FnOnce(&mut RmrkResourceInfo) -> DispatchResult,1769 ) -> DispatchResult {1770 <PalletNft<T>>::try_mutate_token_aux_property(1771 collection_id,1772 nft_id,1773 RMRK_SCOPE,1774 Self::get_scoped_property_key(ResourceId(resource_id))?,1775 |value| match value {1776 Some(value) => {1777 let mut resource_info: RmrkResourceInfo = Self::decode_property_value(value)?;17781779 f(&mut resource_info)?;17801781 *value = Self::encode_property_value(&resource_info)?;17821783 Ok(())1784 }1785 None => Err(<Error<T>>::ResourceDoesntExist.into()),1786 },1787 )1788 }17891790 /// Change the owner of an NFT collection, ensuring that the sender is the current owner.1791 fn change_collection_owner(1792 collection_id: CollectionId,1793 collection_type: misc::CollectionType,1794 sender: T::AccountId,1795 new_owner: T::AccountId,1796 ) -> DispatchResult {1797 let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;1798 Self::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))?;17991800 let mut collection = collection.into_inner();18011802 collection.owner = new_owner;1803 collection.save()1804 }18051806 /// Ensure that an account is the collection owner/issuer, return an error if not.1807 pub fn check_collection_owner(1808 collection: &NonfungibleHandle<T>,1809 account: &T::CrossAccountId,1810 ) -> DispatchResult {1811 collection1812 .check_is_owner(account)1813 .map_err(Self::map_unique_err_to_proxy)1814 }18151816 /// Get the latest yet-unused RMRK collection index from the storage.1817 pub fn last_collection_idx() -> RmrkCollectionId {1818 <CollectionIndex<T>>::get()1819 }18201821 /// Get a mapping from a RMRK collection ID to its corresponding Unique collection ID.1822 pub fn unique_collection_id(1823 rmrk_collection_id: RmrkCollectionId,1824 ) -> Result<CollectionId, DispatchError> {1825 <UniqueCollectionId<T>>::try_get(rmrk_collection_id)1826 .map_err(|_| <Error<T>>::CollectionUnknown.into())1827 }18281829 /// Get a mapping from a Unique collection ID to its RMRK collection ID counterpart, if it exists.1830 pub fn rmrk_collection_id(1831 unique_collection_id: CollectionId,1832 ) -> Result<RmrkCollectionId, DispatchError> {1833 Self::get_collection_property_decoded(unique_collection_id, RmrkInternalCollectionId)1834 }18351836 /// Fetch a Unique NFT collection.1837 pub fn get_nft_collection(1838 collection_id: CollectionId,1839 ) -> Result<NonfungibleHandle<T>, DispatchError> {1840 let collection = <CollectionHandle<T>>::try_get(collection_id)1841 .map_err(|_| <Error<T>>::CollectionUnknown)?;18421843 match collection.mode {1844 CollectionMode::NFT => Ok(NonfungibleHandle::cast(collection)),1845 _ => Err(<Error<T>>::CollectionUnknown.into()),1846 }1847 }18481849 /// Check if an NFT collection with such an ID exists.1850 pub fn collection_exists(collection_id: CollectionId) -> bool {1851 <CollectionHandle<T>>::try_get(collection_id).is_ok()1852 }18531854 /// Fetch and decode a RMRK-scoped collection property value in bytes.1855 pub fn get_collection_property(1856 collection_id: CollectionId,1857 key: RmrkProperty,1858 ) -> Result<PropertyValue, DispatchError> {1859 let collection_property = <PalletCommon<T>>::collection_properties(collection_id)1860 .get(&Self::get_scoped_property_key(key)?)1861 .ok_or(<Error<T>>::CollectionUnknown)?1862 .clone();18631864 Ok(collection_property)1865 }18661867 /// Fetch a RMRK-scoped collection property and decode it from bytes into an appropriate type.1868 pub fn get_collection_property_decoded<V: Decode>(1869 collection_id: CollectionId,1870 key: RmrkProperty,1871 ) -> Result<V, DispatchError> {1872 Self::decode_property_value(&Self::get_collection_property(collection_id, key)?)1873 }18741875 /// Get the type of a collection stored as a scoped property.1876 ///1877 /// RMRK Core proxy differentiates between regular collections as well as RMRK Bases as collections.1878 pub fn get_collection_type(1879 collection_id: CollectionId,1880 ) -> Result<misc::CollectionType, DispatchError> {1881 Self::get_collection_property_decoded(collection_id, CollectionType).map_err(|err| {1882 if err != <Error<T>>::CollectionUnknown.into() {1883 <Error<T>>::CorruptedCollectionType.into()1884 } else {1885 err1886 }1887 })1888 }18891890 /// Ensure that the type of the collection equals the provided type,1891 /// otherwise return an error.1892 pub fn ensure_collection_type(1893 collection_id: CollectionId,1894 collection_type: misc::CollectionType,1895 ) -> DispatchResult {1896 let actual_type = Self::get_collection_type(collection_id)?;1897 ensure!(1898 actual_type == collection_type,1899 <CommonError<T>>::NoPermission1900 );19011902 Ok(())1903 }19041905 /// Fetch an NFT collection, but make sure it has the appropriate type.1906 pub fn get_typed_nft_collection(1907 collection_id: CollectionId,1908 collection_type: misc::CollectionType,1909 ) -> Result<NonfungibleHandle<T>, DispatchError> {1910 Self::ensure_collection_type(collection_id, collection_type)?;19111912 Self::get_nft_collection(collection_id)1913 }19141915 /// Same as [`get_typed_nft_collection`](crate::pallet::Pallet::get_typed_nft_collection),1916 /// but also return the Unique collection ID.1917 pub fn get_typed_nft_collection_mapped(1918 rmrk_collection_id: RmrkCollectionId,1919 collection_type: misc::CollectionType,1920 ) -> Result<(NonfungibleHandle<T>, CollectionId), DispatchError> {1921 let unique_collection_id = match collection_type {1922 misc::CollectionType::Regular => Self::unique_collection_id(rmrk_collection_id)?,1923 _ => rmrk_collection_id.into(),1924 };19251926 let collection = Self::get_typed_nft_collection(unique_collection_id, collection_type)?;19271928 Ok((collection, unique_collection_id))1929 }19301931 /// Fetch and decode a RMRK-scoped NFT property value in bytes.1932 pub fn get_nft_property(1933 collection_id: CollectionId,1934 nft_id: TokenId,1935 key: RmrkProperty,1936 ) -> Result<PropertyValue, DispatchError> {1937 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))1938 .get(&Self::get_scoped_property_key(key)?)1939 .ok_or(<Error<T>>::RmrkPropertyIsNotFound)?1940 .clone();19411942 Ok(nft_property)1943 }19441945 /// Fetch a RMRK-scoped NFT property and decode it from bytes into an appropriate type.1946 pub fn get_nft_property_decoded<V: Decode>(1947 collection_id: CollectionId,1948 nft_id: TokenId,1949 key: RmrkProperty,1950 ) -> Result<V, DispatchError> {1951 Self::decode_property_value(&Self::get_nft_property(collection_id, nft_id, key)?)1952 }19531954 /// Check that an NFT exists.1955 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {1956 <TokenData<T>>::contains_key((collection_id, nft_id))1957 }19581959 /// Get the type of an NFT stored as a scoped property.1960 ///1961 /// RMRK Core proxy differentiates between regular NFTs, and RMRK Parts and Themes.1962 pub fn get_nft_type(1963 collection_id: CollectionId,1964 token_id: TokenId,1965 ) -> Result<NftType, DispatchError> {1966 Self::get_nft_property_decoded(collection_id, token_id, TokenType)1967 .map_err(|_| <Error<T>>::NoAvailableNftId.into())1968 }19691970 /// Ensure that the type of the NFT equals the provided type, otherwise return an error.1971 pub fn ensure_nft_type(1972 collection_id: CollectionId,1973 token_id: TokenId,1974 nft_type: NftType,1975 ) -> DispatchResult {1976 let actual_type = Self::get_nft_type(collection_id, token_id)?;1977 ensure!(actual_type == nft_type, <Error<T>>::NoPermission);19781979 Ok(())1980 }19811982 /// Ensure that an account is the owner of the token, either directly1983 /// or at the top of the nesting hierarchy; return an error if it is not.1984 pub fn ensure_nft_owner(1985 collection_id: CollectionId,1986 token_id: TokenId,1987 possible_owner: &T::CrossAccountId,1988 nesting_budget: &dyn budget::Budget,1989 ) -> DispatchResult {1990 let is_owned = <PalletStructure<T>>::check_indirectly_owned(1991 possible_owner.clone(),1992 collection_id,1993 token_id,1994 None,1995 nesting_budget,1996 )1997 .map_err(Self::map_unique_err_to_proxy)?;19981999 ensure!(is_owned, <Error<T>>::NoPermission);20002001 Ok(())2002 }20032004 /// Fetch non-scoped properties of a collection or a token that match the filter keys supplied,2005 /// or, if None are provided, return all non-scoped properties.2006 pub fn filter_user_properties<Key, Value, R, Mapper>(2007 collection_id: CollectionId,2008 token_id: Option<TokenId>,2009 filter_keys: Option<Vec<RmrkPropertyKey>>,2010 mapper: Mapper,2011 ) -> Result<Vec<R>, DispatchError>2012 where2013 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,2014 Value: Decode + Default,2015 Mapper: Fn(Key, Value) -> R,2016 {2017 filter_keys2018 .map(|keys| {2019 let properties = keys2020 .into_iter()2021 .filter_map(|key| {2022 let key: Key = key.try_into().ok()?;20232024 let value = match token_id {2025 Some(token_id) => Self::get_nft_property_decoded(2026 collection_id,2027 token_id,2028 UserProperty(key.as_ref()),2029 ),2030 None => Self::get_collection_property_decoded(2031 collection_id,2032 UserProperty(key.as_ref()),2033 ),2034 }2035 .ok()?;20362037 Some(mapper(key, value))2038 })2039 .collect();20402041 Ok(properties)2042 })2043 .unwrap_or_else(|| {2044 let properties =2045 Self::iterate_user_properties(collection_id, token_id, mapper)?.collect();20462047 Ok(properties)2048 })2049 }20502051 /// Get all non-scoped properties from a collection or a token, and apply some transformation,2052 /// supplied by `mapper`, to each key-value pair.2053 pub fn iterate_user_properties<Key, Value, R, Mapper>(2054 collection_id: CollectionId,2055 token_id: Option<TokenId>,2056 mapper: Mapper,2057 ) -> Result<impl Iterator<Item = R>, DispatchError>2058 where2059 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,2060 Value: Decode + Default,2061 Mapper: Fn(Key, Value) -> R,2062 {2063 let properties = match token_id {2064 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),2065 None => <PalletCommon<T>>::collection_properties(collection_id),2066 };20672068 let properties = properties.into_iter().filter_map(move |(key, value)| {2069 let key = strip_key_prefix(&key, USER_PROPERTY_PREFIX)?;20702071 let key: Key = key.to_vec().try_into().ok()?;2072 let value: Value = value.decode().ok()?;20732074 Some(mapper(key, value))2075 });20762077 Ok(properties)2078 }20792080 /// Match Unique errors to RMRK's own and return the RMRK error if a match is successful.2081 fn map_unique_err_to_proxy(err: DispatchError) -> DispatchError {2082 map_unique_err_to_proxy! {2083 match err {2084 CommonError::NoPermission => NoPermission,2085 CommonError::CollectionTokenLimitExceeded => CollectionFullOrLocked,2086 CommonError::PublicMintingNotAllowed => NoPermission,2087 CommonError::TokenNotFound => NoAvailableNftId,2088 CommonError::ApprovedValueTooLow => NoPermission,2089 CommonError::CantDestroyNotEmptyCollection => CollectionNotEmpty,2090 StructureError::TokenNotFound => NoAvailableNftId,2091 StructureError::OuroborosDetected => CannotSendToDescendentOrSelf,2092 }2093 }2094 }2095}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/>.1617//! # RMRK Core Proxy Pallet18//!19//! A pallet used as proxy for RMRK Core (<https://rmrk-team.github.io/rmrk-substrate/#/pallets/rmrk-core>).20//!21//! - [`Config`]22//! - [`Call`]23//! - [`Pallet`]24//!25//! ## Overview26//!27//! The RMRK Core Proxy pallet mirrors the functionality of RMRK Core,28//! binding its externalities to Unique's own underlying structure.29//! It is purposed to mimic RMRK Core exactly, allowing seamless integrations30//! of solutions based on RMRK.31//!32//! RMRK Core itself contains essential functionality for RMRK's nested and33//! multi-resourced NFTs.34//!35//! *Note*, that while RMRK itself is subject to active development and restructuring,36//! the proxy may be caught temporarily out of date.37//!38//! ### What is RMRK?39//!40//! RMRK is a set of NFT standards which compose several "NFT 2.0 lego" primitives.41//! Putting these legos together allows a user to create NFT systems of arbitrary complexity.42//!43//! Meaning, RMRK NFTs are dynamic, able to nest into each other and form a hierarchy,44//! make use of specific changeable and partially shared metadata in the form of resources,45//! and more.46//!47//! Visit RMRK documentation and repositories to learn more:48//! - Docs: <https://docs.rmrk.app/getting-started/>49//! - FAQ: <https://coda.io/@rmrk/faq>50//! - Substrate code repository: <https://github.com/rmrk-team/rmrk-substrate>51//! - RMRK specification repository: <https://github.com/rmrk-team/rmrk-spec>52//!53//! ## Terminology54//!55//! For more information on RMRK, see RMRK's own documentation.56//!57//! ### Intro to RMRK58//!59//! - **Resource:** Additional piece of metadata of an NFT usually serving to add60//! a piece of media on top of the root metadata (NFT's own), be it a different wing61//! on the root template bird or something entirely unrelated.62//!63//! - **Base:** A list of possible "components" - Parts, a combination of which can64//! be appended/equipped to/on an NFT.65//!66//! - **Part:** Something that, together with other Parts, can constitute an NFT.67//! Parts are defined in the Base to which they belong. Parts can be either68//! of the `slot` type or `fixed` type. Slots are intended for equippables.69//! Note that "part of something" and "Part of a Base" can be easily confused,70//! and so in this documentation these words are distinguished by the capital letter.71//!72//! - **Theme:** Named objects of variable => value pairs which get interpolated into73//! the Base's `themable` Parts. Themes can hold any value, but are often represented74//! in RMRK's examples as colors applied to visible Parts.75//!76//! ### Peculiarities in Unique77//!78//! - **Scoped properties:** Properties that are normally obscured from users.79//! Their purpose is to contain structured metadata that was not included in the Unique standard80//! for collections and tokens, meant to be operated on by proxies and other outliers.81//! Scoped property keys are prefixed with `some-scope:`, where `some-scope` is82//! an arbitrary keyword, like "rmrk". `:` is considered an unacceptable symbol in user-defined83//! properties, which, along with other safeguards, makes scoped ones impossible to tamper with.84//!85//! - **Auxiliary properties:** A slightly different structure of properties,86//! trading universality of use for more convenient storage, writes and access.87//! Meant to be inaccessible to end users.88//!89//! ## Proxy Implementation90//!91//! An external user is supposed to be able to utilize this proxy as they would92//! utilize RMRK, and get exactly the same results. Normally, Unique transactions93//! are off-limits to RMRK collections and tokens, and vice versa. However,94//! the information stored on chain can be freely interpreted by storage reads and Unique RPCs.95//!96//! ### ID Mapping97//!98//! RMRK's collections' IDs are counted independently of Unique's and start at 0.99//! Note that tokens' IDs still start at 1.100//! The collections themselves, as well as tokens, are stored as Unique collections,101//! and thus RMRK IDs are mapped to Unique IDs (but not vice versa).102//!103//! ### External/Internal Collection Insulation104//!105//! A Unique transaction cannot target collections purposed for RMRK,106//! and they are flagged as `external` to specify that. On the other hand,107//! due to the mapping, RMRK transactions and RPCs simply cannot reach Unique collections.108//!109//! ### Native Properties110//!111//! Many of RMRK's native parameters are stored as scoped properties of a collection112//! or an NFT on the chain. Scoped properties are prefixed with `rmrk:`, where `:`113//! is an unacceptable symbol in user-defined properties, which, along with other safeguards,114//! makes them impossible to tamper with.115//!116//! ### Collection and NFT Types, or Base, Parts and Themes Handling117//!118//! RMRK introduces the concept of a Base, which is a catalogue of Parts,119//! possible components of an NFT. Due to its similarity with the functionality120//! of a token collection, a Base is stored and handled as one, and the Base's Parts and Themes121//! are this collection's NFTs. See [`CollectionType`] and [`NftType`].122//!123//! ## Interface124//!125//! ### Dispatchables126//!127//! - `create_collection` - Create a new collection of NFTs.128//! - `destroy_collection` - Destroy a collection.129//! - `change_collection_issuer` - Change the issuer of a collection.130//! Analogous to Unique's collection's [`owner`](up_data_structs::Collection).131//! - `lock_collection` - "Lock" the collection and prevent new token creation. **Cannot be undone.**132//! - `mint_nft` - Mint an NFT in a specified collection.133//! - `burn_nft` - Burn an NFT, destroying it and its nested tokens.134//! - `send` - Transfer an NFT from an account/NFT A to another account/NFT B.135//! - `accept_nft` - Accept an NFT sent from another account to self or an owned NFT.136//! - `reject_nft` - Reject an NFT sent from another account to self or owned NFT and **burn it**.137//! - `accept_resource` - Accept the addition of a newly created pending resource to an existing NFT.138//! - `accept_resource_removal` - Accept the removal of a removal-pending resource from an NFT.139//! - `set_property` - Add or edit a custom user property of a token or a collection.140//! - `set_priority` - Set a different order of resource priorities for an NFT.141//! - `add_basic_resource` - Create and set/propose a basic resource for an NFT.142//! - `add_composable_resource` - Create and set/propose a composable resource for an NFT.143//! - `add_slot_resource` - Create and set/propose a slot resource for an NFT.144//! - `remove_resource` - Remove and erase a resource from an NFT.145146#![cfg_attr(not(feature = "std"), no_std)]147148use frame_support::{pallet_prelude::*, BoundedVec, dispatch::DispatchResult};149use frame_system::{pallet_prelude::*, ensure_signed};150use sp_runtime::{DispatchError, Permill, traits::StaticLookup};151use sp_std::{152 vec::Vec,153 collections::{btree_set::BTreeSet, btree_map::BTreeMap},154};155use up_data_structs::{*, mapping::TokenAddressMapping};156use pallet_common::{157 Pallet as PalletCommon, Error as CommonError, CollectionHandle, CommonCollectionOperations,158};159use pallet_nonfungible::{Pallet as PalletNft, NonfungibleHandle, TokenData};160use pallet_structure::{Pallet as PalletStructure, Error as StructureError};161use pallet_evm::account::CrossAccountId;162use core::convert::AsRef;163164pub use pallet::*;165166#[cfg(feature = "runtime-benchmarks")]167pub mod benchmarking;168pub mod misc;169pub mod property;170pub mod rpc;171pub mod weights;172173pub type SelfWeightOf<T> = <T as Config>::WeightInfo;174175use weights::WeightInfo;176use misc::*;177pub use property::*;178179use RmrkProperty::*;180181/// Maximum number of levels of depth in the token nesting tree.182pub const NESTING_BUDGET: u32 = 5;183184type PendingTarget = (CollectionId, TokenId);185type PendingChild = (RmrkCollectionId, RmrkNftId);186type PendingChildrenSet = BTreeSet<PendingChild>;187188type BasesMap = BTreeMap<RmrkBaseId, u32>;189190#[frame_support::pallet]191pub mod pallet {192 use super::*;193194 #[pallet::config]195 pub trait Config:196 frame_system::Config197 + pallet_common::Config198 + pallet_nonfungible::Config199 + pallet_evm::Config200 {201 /// Overarching event type.202 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;203204 /// The weight information of this pallet.205 type WeightInfo: WeightInfo;206 }207208 /// Latest yet-unused collection ID.209 #[pallet::storage]210 #[pallet::getter(fn collection_index)]211 pub type CollectionIndex<T: Config> = StorageValue<_, RmrkCollectionId, ValueQuery>;212213 /// Mapping from RMRK collection ID to Unique's.214 #[pallet::storage]215 pub type UniqueCollectionId<T: Config> =216 StorageMap<_, Twox64Concat, RmrkCollectionId, CollectionId, ValueQuery>;217218 #[pallet::pallet]219 #[pallet::generate_store(pub(super) trait Store)]220 pub struct Pallet<T>(_);221222 #[pallet::event]223 #[pallet::generate_deposit(pub(super) fn deposit_event)]224 pub enum Event<T: Config> {225 CollectionCreated {226 issuer: T::AccountId,227 collection_id: RmrkCollectionId,228 },229 CollectionDestroyed {230 issuer: T::AccountId,231 collection_id: RmrkCollectionId,232 },233 IssuerChanged {234 old_issuer: T::AccountId,235 new_issuer: T::AccountId,236 collection_id: RmrkCollectionId,237 },238 CollectionLocked {239 issuer: T::AccountId,240 collection_id: RmrkCollectionId,241 },242 NftMinted {243 owner: T::AccountId,244 collection_id: RmrkCollectionId,245 nft_id: RmrkNftId,246 },247 NFTBurned {248 owner: T::AccountId,249 nft_id: RmrkNftId,250 },251 NFTSent {252 sender: T::AccountId,253 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,254 collection_id: RmrkCollectionId,255 nft_id: RmrkNftId,256 approval_required: bool,257 },258 NFTAccepted {259 sender: T::AccountId,260 recipient: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,261 collection_id: RmrkCollectionId,262 nft_id: RmrkNftId,263 },264 NFTRejected {265 sender: T::AccountId,266 collection_id: RmrkCollectionId,267 nft_id: RmrkNftId,268 },269 PropertySet {270 collection_id: RmrkCollectionId,271 maybe_nft_id: Option<RmrkNftId>,272 key: RmrkKeyString,273 value: RmrkValueString,274 },275 ResourceAdded {276 nft_id: RmrkNftId,277 resource_id: RmrkResourceId,278 },279 ResourceRemoval {280 nft_id: RmrkNftId,281 resource_id: RmrkResourceId,282 },283 ResourceAccepted {284 nft_id: RmrkNftId,285 resource_id: RmrkResourceId,286 },287 ResourceRemovalAccepted {288 nft_id: RmrkNftId,289 resource_id: RmrkResourceId,290 },291 PrioritySet {292 collection_id: RmrkCollectionId,293 nft_id: RmrkNftId,294 },295 }296297 #[pallet::error]298 pub enum Error<T> {299 /* Unique proxy-specific events */300 /// Property of the type of RMRK collection could not be read successfully.301 CorruptedCollectionType,302 // NftTypeEncodeError,303 /// Too many symbols supplied as the property key. The maximum is [256](up_data_structs::MAX_PROPERTY_KEY_LENGTH).304 RmrkPropertyKeyIsTooLong,305 /// Too many bytes supplied as the property value. The maximum is [32768](up_data_structs::MAX_PROPERTY_VALUE_LENGTH).306 RmrkPropertyValueIsTooLong,307 /// Could not find a property by the supplied key.308 RmrkPropertyIsNotFound,309 /// Something went wrong when decoding encoded data from the storage.310 /// Perhaps, there was a wrong key supplied for the type, or the data was improperly stored.311 UnableToDecodeRmrkData,312313 /* RMRK compatible events */314 /// Only destroying collections without tokens is allowed.315 CollectionNotEmpty,316 /// Could not find an ID for a collection. It is likely there were too many collections created on the chain, causing an overflow.317 NoAvailableCollectionId,318 /// Token does not exist, or there is no suitable ID for it, likely too many tokens were created in a collection, causing an overflow.319 NoAvailableNftId,320 /// Collection does not exist, has a wrong type, or does not map to a Unique ID.321 CollectionUnknown,322 /// No permission to perform action.323 NoPermission,324 /// Token is marked as non-transferable, and thus cannot be transferred.325 NonTransferable,326 /// Too many tokens created in the collection, no new ones are allowed.327 CollectionFullOrLocked,328 /// No such resource found.329 ResourceDoesntExist,330 /// If an NFT is sent to a descendant, that would form a nesting loop, an ouroboros.331 /// Sending to self is redundant.332 CannotSendToDescendentOrSelf,333 /// Not the target owner of the sent NFT.334 CannotAcceptNonOwnedNft,335 /// Not the target owner of the sent NFT.336 CannotRejectNonOwnedNft,337 /// NFT was not sent and is not pending.338 CannotRejectNonPendingNft,339 /// Resource is not pending for the operation.340 ResourceNotPending,341 /// Could not find an ID for the resource. It is likely there were too many resources created on an NFT, causing an overflow.342 NoAvailableResourceId,343 }344345 #[pallet::call]346 impl<T: Config> Pallet<T> {347 // todo :refactor replace every collection_id with rmrk_collection_id (and nft_id) in arguments for uniformity?348349 /// Create a new collection of NFTs.350 ///351 /// # Permissions:352 /// * Anyone - will be assigned as the issuer of the collection.353 ///354 /// # Arguments:355 /// - `origin`: sender of the transaction356 /// - `metadata`: Metadata describing the collection, e.g. IPFS hash. Cannot be changed.357 /// - `max`: Optional maximum number of tokens.358 /// - `symbol`: UTF-8 string with token prefix, by which to represent the token in wallets and UIs.359 /// Analogous to Unique's [`token_prefix`](up_data_structs::Collection). Cannot be changed.360 #[pallet::weight(<SelfWeightOf<T>>::create_collection())]361 pub fn create_collection(362 origin: OriginFor<T>,363 metadata: RmrkString,364 max: Option<u32>,365 symbol: RmrkCollectionSymbol,366 ) -> DispatchResult {367 let sender = ensure_signed(origin)?;368369 let limits = CollectionLimits {370 owner_can_transfer: Some(false),371 token_limit: max,372 ..Default::default()373 };374375 let data = CreateCollectionData {376 limits: Some(limits),377 token_prefix: symbol378 .into_inner()379 .try_into()380 .map_err(|_| <CommonError<T>>::CollectionTokenPrefixLimitExceeded)?,381 permissions: Some(CollectionPermissions {382 nesting: Some(NestingPermissions {383 token_owner: true,384 collection_admin: false,385 restricted: None,386 #[cfg(feature = "runtime-benchmarks")]387 permissive: false,388 }),389 ..Default::default()390 }),391 ..Default::default()392 };393394 let unique_collection_id = Self::init_collection(395 T::CrossAccountId::from_sub(sender.clone()),396 data,397 [398 Self::encode_rmrk_property(Metadata, &metadata)?,399 Self::encode_rmrk_property(CollectionType, &misc::CollectionType::Regular)?,400 ]401 .into_iter(),402 )?;403 let rmrk_collection_id = <CollectionIndex<T>>::get();404405 <UniqueCollectionId<T>>::insert(rmrk_collection_id, unique_collection_id);406407 <PalletCommon<T>>::set_scoped_collection_property(408 unique_collection_id,409 RMRK_SCOPE,410 Self::encode_rmrk_property(RmrkInternalCollectionId, &rmrk_collection_id)?,411 )?;412413 <CollectionIndex<T>>::mutate(|n| *n += 1);414415 Self::deposit_event(Event::CollectionCreated {416 issuer: sender,417 collection_id: rmrk_collection_id,418 });419420 Ok(())421 }422423 /// Destroy a collection.424 ///425 /// Only empty collections can be destroyed. If it has any tokens, they must be burned first.426 ///427 /// # Permissions:428 /// * Collection issuer429 ///430 /// # Arguments:431 /// - `origin`: sender of the transaction432 /// - `collection_id`: RMRK ID of the collection to destroy.433 #[pallet::weight(<SelfWeightOf<T>>::destroy_collection())]434 pub fn destroy_collection(435 origin: OriginFor<T>,436 collection_id: RmrkCollectionId,437 ) -> DispatchResult {438 let sender = ensure_signed(origin)?;439 let cross_sender = T::CrossAccountId::from_sub(sender.clone());440441 let collection = Self::get_typed_nft_collection(442 Self::unique_collection_id(collection_id)?,443 misc::CollectionType::Regular,444 )?;445 collection.check_is_external()?;446447 <PalletNft<T>>::destroy_collection(collection, &cross_sender)448 .map_err(Self::map_unique_err_to_proxy)?;449450 Self::deposit_event(Event::CollectionDestroyed {451 issuer: sender,452 collection_id,453 });454455 Ok(())456 }457458 /// Change the issuer of a collection. Analogous to Unique's collection's [`owner`](up_data_structs::Collection).459 ///460 /// # Permissions:461 /// * Collection issuer462 ///463 /// # Arguments:464 /// - `origin`: sender of the transaction465 /// - `collection_id`: RMRK collection ID to change the issuer of.466 /// - `new_issuer`: Collection's new issuer.467 #[pallet::weight(<SelfWeightOf<T>>::change_collection_issuer())]468 pub fn change_collection_issuer(469 origin: OriginFor<T>,470 collection_id: RmrkCollectionId,471 new_issuer: <T::Lookup as StaticLookup>::Source,472 ) -> DispatchResult {473 let sender = ensure_signed(origin)?;474475 let collection = Self::get_nft_collection(Self::unique_collection_id(collection_id)?)?;476 collection.check_is_external()?;477478 let new_issuer = T::Lookup::lookup(new_issuer)?;479480 Self::change_collection_owner(481 Self::unique_collection_id(collection_id)?,482 misc::CollectionType::Regular,483 sender.clone(),484 new_issuer.clone(),485 )?;486487 Self::deposit_event(Event::IssuerChanged {488 old_issuer: sender,489 new_issuer,490 collection_id,491 });492493 Ok(())494 }495496 /// "Lock" the collection and prevent new token creation. Cannot be undone.497 ///498 /// # Permissions:499 /// * Collection issuer500 ///501 /// # Arguments:502 /// - `origin`: sender of the transaction503 /// - `collection_id`: RMRK ID of the collection to lock.504 #[pallet::weight(<SelfWeightOf<T>>::lock_collection())]505 pub fn lock_collection(506 origin: OriginFor<T>,507 collection_id: RmrkCollectionId,508 ) -> DispatchResult {509 let sender = ensure_signed(origin)?;510 let cross_sender = T::CrossAccountId::from_sub(sender.clone());511512 let collection = Self::get_typed_nft_collection(513 Self::unique_collection_id(collection_id)?,514 misc::CollectionType::Regular,515 )?;516 collection.check_is_external()?;517518 Self::check_collection_owner(&collection, &cross_sender)?;519520 let token_count = collection.total_supply();521522 let mut collection = collection.into_inner();523 collection.limits.token_limit = Some(token_count);524 collection.save()?;525526 Self::deposit_event(Event::CollectionLocked {527 issuer: sender,528 collection_id,529 });530531 Ok(())532 }533534 /// Mint an NFT in a specified collection.535 ///536 /// # Permissions:537 /// * Collection issuer538 ///539 /// # Arguments:540 /// - `origin`: sender of the transaction541 /// - `owner`: Owner account of the NFT. If set to None, defaults to the sender (collection issuer).542 /// - `collection_id`: RMRK collection ID for the NFT to be minted within. Cannot be changed.543 /// - `recipient`: Receiver account of the royalty. Has no effect if the `royalty_amount` is not set. Cannot be changed.544 /// - `royalty_amount`: Optional permillage reward from each trade for the `recipient`. Cannot be changed.545 /// - `metadata`: Arbitrary data about an NFT, e.g. IPFS hash. Cannot be changed.546 /// - `transferable`: Can this NFT be transferred? Cannot be changed.547 /// - `resources`: Resource data to be added to the NFT immediately after minting.548 #[pallet::weight(<SelfWeightOf<T>>::mint_nft(resources.as_ref().map(|r| r.len() as u32).unwrap_or(0)))]549 pub fn mint_nft(550 origin: OriginFor<T>,551 owner: Option<T::AccountId>,552 collection_id: RmrkCollectionId,553 recipient: Option<T::AccountId>,554 royalty_amount: Option<Permill>,555 metadata: RmrkString,556 transferable: bool,557 resources: Option<BoundedVec<RmrkResourceTypes, MaxResourcesOnMint>>,558 ) -> DispatchResult {559 let sender = ensure_signed(origin)?;560 let cross_sender = T::CrossAccountId::from_sub(sender.clone());561562 let owner = owner.unwrap_or(sender.clone());563 let cross_owner = T::CrossAccountId::from_sub(owner.clone());564565 let collection = Self::get_typed_nft_collection(566 Self::unique_collection_id(collection_id)?,567 misc::CollectionType::Regular,568 )?;569 collection.check_is_external()?;570571 let royalty_info = royalty_amount.map(|amount| rmrk_traits::RoyaltyInfo {572 recipient: recipient.unwrap_or_else(|| owner.clone()),573 amount,574 });575576 let nft_id = Self::create_nft(577 &cross_sender,578 &cross_owner,579 &collection,580 [581 Self::encode_rmrk_property(TokenType, &NftType::Regular)?,582 Self::encode_rmrk_property(Transferable, &transferable)?,583 Self::encode_rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,584 Self::encode_rmrk_property(RoyaltyInfo, &royalty_info)?,585 Self::encode_rmrk_property(Metadata, &metadata)?,586 Self::encode_rmrk_property(Equipped, &false)?,587 Self::encode_rmrk_property(ResourcePriorities, &<Vec<u8>>::new())?,588 Self::encode_rmrk_property(NextResourceId, &(0 as RmrkResourceId))?,589 Self::encode_rmrk_property(PendingChildren, &PendingChildrenSet::new())?,590 Self::encode_rmrk_property(AssociatedBases, &BasesMap::new())?,591 ]592 .into_iter(),593 )594 .map_err(|err| match err {595 DispatchError::Arithmetic(_) => <Error<T>>::NoAvailableNftId.into(),596 err => Self::map_unique_err_to_proxy(err),597 })?;598599 if let Some(resources) = resources {600 for resource in resources {601 Self::resource_add(sender.clone(), collection.id, nft_id, resource)?;602 }603 }604605 Self::deposit_event(Event::NftMinted {606 owner,607 collection_id,608 nft_id: nft_id.0,609 });610611 Ok(())612 }613614 /// Burn an NFT, destroying it and its nested tokens up to the specified limit.615 /// If the burning budget is exceeded, the transaction is reverted.616 ///617 /// This is the way to burn a nested token as well.618 ///619 /// For more information, see [`burn_recursively`](pallet_nonfungible::pallet::Pallet::burn_recursively).620 ///621 /// # Permissions:622 /// * Token owner623 ///624 /// # Arguments:625 /// - `origin`: sender of the transaction626 /// - `collection_id`: RMRK ID of the collection in which the NFT to burn belongs to.627 /// - `nft_id`: ID of the NFT to be destroyed.628 /// - `max_burns`: Maximum number of tokens to burn, assuming nesting. The transaction629 /// is reverted if there are more tokens to burn in the nesting tree than this number.630 /// This is primarily a mechanism of transaction weight control.631 #[pallet::weight(<SelfWeightOf<T>>::burn_nft(*max_burns))]632 pub fn burn_nft(633 origin: OriginFor<T>,634 collection_id: RmrkCollectionId,635 nft_id: RmrkNftId,636 max_burns: u32,637 ) -> DispatchResult {638 let sender = ensure_signed(origin)?;639 let cross_sender = T::CrossAccountId::from_sub(sender.clone());640641 let collection = Self::get_typed_nft_collection(642 Self::unique_collection_id(collection_id)?,643 misc::CollectionType::Regular,644 )?;645 collection.check_is_external()?;646647 Self::destroy_nft(648 cross_sender,649 Self::unique_collection_id(collection_id)?,650 nft_id.into(),651 max_burns,652 <Error<T>>::NoPermission,653 )654 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;655656 Self::deposit_event(Event::NFTBurned {657 owner: sender,658 nft_id,659 });660661 Ok(())662 }663664 /// Transfer an NFT from an account/NFT A to another account/NFT B.665 /// The token must be transferable. Nesting cannot occur deeper than the [`NESTING_BUDGET`].666 ///667 /// If the target owner is an NFT owned by another account, then the NFT will enter668 /// the pending state and will have to be accepted by the other account.669 ///670 /// # Permissions:671 /// - Token owner672 ///673 /// # Arguments:674 /// - `origin`: sender of the transaction675 /// - `rmrk_collection_id`: RMRK ID of the collection of the NFT to be transferred.676 /// - `rmrk_nft_id`: ID of the NFT to be transferred.677 /// - `new_owner`: New owner of the nft which can be either an account or a NFT.678 #[pallet::weight(<SelfWeightOf<T>>::send())]679 pub fn send(680 origin: OriginFor<T>,681 rmrk_collection_id: RmrkCollectionId,682 rmrk_nft_id: RmrkNftId,683 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,684 ) -> DispatchResult {685 let sender = ensure_signed(origin.clone())?;686 let cross_sender = T::CrossAccountId::from_sub(sender.clone());687688 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;689 let nft_id = rmrk_nft_id.into();690691 let collection =692 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;693 collection.check_is_external()?;694695 let token_data =696 <TokenData<T>>::get((collection_id, nft_id)).ok_or(<Error<T>>::NoAvailableNftId)?;697698 let from = token_data.owner;699700 ensure!(701 Self::get_nft_property_decoded(collection_id, nft_id, RmrkProperty::Transferable)?,702 <Error<T>>::NonTransferable703 );704705 ensure!(706 Self::get_nft_property_decoded::<Option<PendingTarget>>(707 collection_id,708 nft_id,709 RmrkProperty::PendingNftAccept710 )?711 .is_none(),712 <Error<T>>::NoPermission713 );714715 let target_owner;716 let approval_required;717718 match new_owner {719 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {720 target_owner = T::CrossAccountId::from_sub(account_id.clone());721 approval_required = false;722 }723 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(724 target_collection_id,725 target_nft_id,726 ) => {727 let target_collection_id = Self::unique_collection_id(target_collection_id)?;728729 let target_nft_budget = budget::Value::new(NESTING_BUDGET);730731 let target_nft_owner = <PalletStructure<T>>::get_checked_topmost_owner(732 target_collection_id,733 target_nft_id.into(),734 Some((collection_id, nft_id)),735 &target_nft_budget,736 )737 .map_err(Self::map_unique_err_to_proxy)?;738739 approval_required = cross_sender != target_nft_owner;740741 if approval_required {742 target_owner = target_nft_owner;743744 <PalletNft<T>>::set_scoped_token_property(745 collection.id,746 nft_id,747 RMRK_SCOPE,748 Self::encode_rmrk_property::<Option<PendingTarget>>(749 PendingNftAccept,750 &Some((target_collection_id, target_nft_id.into())),751 )?,752 )?;753754 Self::insert_pending_child(755 (target_collection_id, target_nft_id.into()),756 (rmrk_collection_id, rmrk_nft_id),757 )?;758 } else {759 target_owner = T::CrossTokenAddressMapping::token_to_address(760 target_collection_id,761 target_nft_id.into(),762 );763 }764 }765 }766767 let src_nft_budget = budget::Value::new(NESTING_BUDGET);768769 <PalletNft<T>>::transfer_from(770 &collection,771 &cross_sender,772 &from,773 &target_owner,774 nft_id,775 &src_nft_budget,776 )777 .map_err(Self::map_unique_err_to_proxy)?;778779 Self::deposit_event(Event::NFTSent {780 sender,781 recipient: new_owner,782 collection_id: rmrk_collection_id,783 nft_id: rmrk_nft_id,784 approval_required,785 });786787 Ok(())788 }789790 /// Accept an NFT sent from another account to self or an owned NFT.791 ///792 /// The NFT in question must be pending, and, thus, be [sent](`Pallet::send`) first.793 ///794 /// # Permissions:795 /// - Token-owner-to-be796 ///797 /// # Arguments:798 /// - `origin`: sender of the transaction799 /// - `rmrk_collection_id`: RMRK collection ID of the NFT to be accepted.800 /// - `rmrk_nft_id`: ID of the NFT to be accepted.801 /// - `new_owner`: Either the sender's account ID or a sender-owned NFT,802 /// whichever the accepted NFT was sent to.803 #[pallet::weight(<SelfWeightOf<T>>::accept_nft())]804 pub fn accept_nft(805 origin: OriginFor<T>,806 rmrk_collection_id: RmrkCollectionId,807 rmrk_nft_id: RmrkNftId,808 new_owner: RmrkAccountIdOrCollectionNftTuple<T::AccountId>,809 ) -> DispatchResult {810 let sender = ensure_signed(origin.clone())?;811 let cross_sender = T::CrossAccountId::from_sub(sender.clone());812813 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;814 let nft_id = rmrk_nft_id.into();815816 let collection =817 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;818 collection.check_is_external()?;819820 let new_cross_owner = match new_owner {821 RmrkAccountIdOrCollectionNftTuple::AccountId(ref account_id) => {822 T::CrossAccountId::from_sub(account_id.clone())823 }824 RmrkAccountIdOrCollectionNftTuple::CollectionAndNftTuple(825 target_collection_id,826 target_nft_id,827 ) => {828 let target_collection_id = Self::unique_collection_id(target_collection_id)?;829830 T::CrossTokenAddressMapping::token_to_address(831 target_collection_id,832 TokenId(target_nft_id),833 )834 }835 };836837 let budget = budget::Value::new(NESTING_BUDGET);838839 <PalletNft<T>>::transfer(840 &collection,841 &cross_sender,842 &new_cross_owner,843 nft_id,844 &budget,845 )846 .map_err(|err| {847 if err == <CommonError<T>>::UserIsNotAllowedToNest.into() {848 <Error<T>>::CannotAcceptNonOwnedNft.into()849 } else {850 Self::map_unique_err_to_proxy(err)851 }852 })?;853854 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(855 collection_id,856 nft_id,857 RmrkProperty::PendingNftAccept,858 )?;859860 if let Some(pending_target) = pending_target {861 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?;862863 <PalletNft<T>>::set_scoped_token_property(864 collection.id,865 nft_id,866 RMRK_SCOPE,867 Self::encode_rmrk_property(PendingNftAccept, &None::<PendingTarget>)?,868 )?;869 }870871 Self::deposit_event(Event::NFTAccepted {872 sender,873 recipient: new_owner,874 collection_id: rmrk_collection_id,875 nft_id: rmrk_nft_id,876 });877878 Ok(())879 }880881 /// Reject an NFT sent from another account to self or owned NFT.882 /// The NFT in question will not be sent back and burnt instead.883 ///884 /// The NFT in question must be pending, and, thus, be [sent](`Pallet::send`) first.885 ///886 /// # Permissions:887 /// - Token-owner-to-be-not888 ///889 /// # Arguments:890 /// - `origin`: sender of the transaction891 /// - `rmrk_collection_id`: RMRK ID of the NFT to be rejected.892 /// - `rmrk_nft_id`: ID of the NFT to be rejected.893 #[pallet::weight(<SelfWeightOf<T>>::reject_nft())]894 pub fn reject_nft(895 origin: OriginFor<T>,896 rmrk_collection_id: RmrkCollectionId,897 rmrk_nft_id: RmrkNftId,898 ) -> DispatchResult {899 let sender = ensure_signed(origin)?;900 let cross_sender = T::CrossAccountId::from_sub(sender.clone());901902 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;903 let nft_id = rmrk_nft_id.into();904905 let collection =906 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;907 collection.check_is_external()?;908909 ensure!(910 <TokenData<T>>::get((collection_id, nft_id)).is_some(),911 <Error<T>>::NoAvailableNftId912 );913914 let pending_target = Self::get_nft_property_decoded::<Option<PendingTarget>>(915 collection_id,916 nft_id,917 RmrkProperty::PendingNftAccept,918 )?;919920 match pending_target {921 Some(pending_target) => {922 Self::remove_pending_child(pending_target, (rmrk_collection_id, rmrk_nft_id))?923 }924 None => return Err(<Error<T>>::CannotRejectNonPendingNft.into()),925 }926927 Self::destroy_nft(928 cross_sender,929 collection_id,930 nft_id,931 NESTING_BUDGET,932 <Error<T>>::CannotRejectNonOwnedNft,933 )934 .map_err(|err| Self::map_unique_err_to_proxy(err.error))?;935936 Self::deposit_event(Event::NFTRejected {937 sender,938 collection_id: rmrk_collection_id,939 nft_id: rmrk_nft_id,940 });941942 Ok(())943 }944945 /// Accept the addition of a newly created pending resource to an existing NFT.946 ///947 /// This transaction is needed when a resource is created and assigned to an NFT948 /// by a non-owner, i.e. the collection issuer, with one of the949 /// [`add_...` transactions](Pallet::add_basic_resource).950 ///951 /// # Permissions:952 /// - Token owner953 ///954 /// # Arguments:955 /// - `origin`: sender of the transaction956 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.957 /// - `rmrk_nft_id`: ID of the NFT with a pending resource to be accepted.958 /// - `resource_id`: ID of the newly created pending resource.959 /// accept the addition of a new resource to an existing NFT960 #[pallet::weight(<SelfWeightOf<T>>::accept_resource())]961 pub fn accept_resource(962 origin: OriginFor<T>,963 rmrk_collection_id: RmrkCollectionId,964 rmrk_nft_id: RmrkNftId,965 resource_id: RmrkResourceId,966 ) -> DispatchResult {967 let sender = ensure_signed(origin)?;968 let cross_sender = T::CrossAccountId::from_sub(sender);969970 let collection_id = Self::unique_collection_id(rmrk_collection_id)971 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;972 let collection =973 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;974 collection.check_is_external()?;975976 let nft_id = rmrk_nft_id.into();977978 let budget = budget::Value::new(NESTING_BUDGET);979980 let nft_owner =981 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)982 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;983984 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {985 ensure!(res.pending, <Error<T>>::ResourceNotPending);986 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);987988 res.pending = false;989990 Ok(())991 })?;992993 Self::deposit_event(Event::<T>::ResourceAccepted {994 nft_id: rmrk_nft_id,995 resource_id,996 });997998 Ok(())999 }10001001 /// Accept the removal of a removal-pending resource from an NFT.1002 ///1003 /// This transaction is needed when a non-owner, i.e. the collection issuer,1004 /// requests a [removal](`Pallet::remove_resource`) of a resource from an NFT.1005 ///1006 /// # Permissions:1007 /// - Token owner1008 ///1009 /// # Arguments:1010 /// - `origin`: sender of the transaction1011 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1012 /// - `rmrk_nft_id`: ID of the NFT with a resource to be removed.1013 /// - `resource_id`: ID of the removal-pending resource.1014 #[pallet::weight(<SelfWeightOf<T>>::accept_resource_removal())]1015 pub fn accept_resource_removal(1016 origin: OriginFor<T>,1017 rmrk_collection_id: RmrkCollectionId,1018 rmrk_nft_id: RmrkNftId,1019 resource_id: RmrkResourceId,1020 ) -> DispatchResult {1021 let sender = ensure_signed(origin)?;1022 let cross_sender = T::CrossAccountId::from_sub(sender);10231024 let collection_id = Self::unique_collection_id(rmrk_collection_id)1025 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;1026 let collection =1027 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1028 collection.check_is_external()?;10291030 let nft_id = rmrk_nft_id.into();10311032 let budget = budget::Value::new(NESTING_BUDGET);10331034 let nft_owner =1035 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)1036 .map_err(|_| <Error<T>>::ResourceDoesntExist)?;10371038 ensure!(cross_sender == nft_owner, <Error<T>>::NoPermission);10391040 let resource_id_key = Self::get_scoped_property_key(ResourceId(resource_id))?;10411042 let resource_info = <PalletNft<T>>::token_aux_property((1043 collection_id,1044 nft_id,1045 RMRK_SCOPE,1046 resource_id_key.clone(),1047 ))1048 .ok_or(<Error<T>>::ResourceDoesntExist)?;10491050 let resource_info: RmrkResourceInfo = Self::decode_property_value(&resource_info)?;10511052 ensure!(1053 resource_info.pending_removal,1054 <Error<T>>::ResourceNotPending1055 );10561057 <PalletNft<T>>::remove_token_aux_property(1058 collection_id,1059 nft_id,1060 RMRK_SCOPE,1061 resource_id_key,1062 );10631064 if let RmrkResourceTypes::Composable(resource) = resource_info.resource {1065 let base_id = resource.base;10661067 Self::remove_associated_base_id(collection_id, nft_id, base_id)?;1068 }10691070 Self::deposit_event(Event::<T>::ResourceRemovalAccepted {1071 nft_id: rmrk_nft_id,1072 resource_id,1073 });10741075 Ok(())1076 }10771078 /// Add or edit a custom user property, a key-value pair, describing the metadata1079 /// of a token or a collection, on either one of these.1080 ///1081 /// Note that in this proxy implementation many details regarding RMRK are stored1082 /// as scoped properties prefixed with "rmrk:", normally inaccessible1083 /// to external transactions and RPCs.1084 ///1085 /// # Permissions:1086 /// - Collection issuer - in case of collection property1087 /// - Token owner - in case of NFT property1088 ///1089 /// # Arguments:1090 /// - `origin`: sender of the transaction1091 /// - `rmrk_collection_id`: RMRK collection ID.1092 /// - `maybe_nft_id`: Optional ID of the NFT. If left empty, then the property is set for the collection.1093 /// - `key`: Key of the custom property to be referenced by.1094 /// - `value`: Value of the custom property to be stored.1095 #[pallet::weight(<SelfWeightOf<T>>::set_property())]1096 pub fn set_property(1097 origin: OriginFor<T>,1098 #[pallet::compact] rmrk_collection_id: RmrkCollectionId,1099 maybe_nft_id: Option<RmrkNftId>,1100 key: RmrkKeyString,1101 value: RmrkValueString,1102 ) -> DispatchResult {1103 let sender = ensure_signed(origin)?;1104 let sender = T::CrossAccountId::from_sub(sender);11051106 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1107 let collection =1108 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1109 collection.check_is_external()?;11101111 let budget = budget::Value::new(NESTING_BUDGET);11121113 match maybe_nft_id {1114 Some(nft_id) => {1115 let token_id: TokenId = nft_id.into();11161117 Self::ensure_nft_type(collection_id, token_id, NftType::Regular)?;1118 Self::ensure_nft_owner(collection_id, token_id, &sender, &budget)?;11191120 <PalletNft<T>>::set_scoped_token_property(1121 collection_id,1122 token_id,1123 RMRK_SCOPE,1124 Self::encode_rmrk_property(UserProperty(key.as_slice()), &value)?,1125 )?;1126 }1127 None => {1128 let collection = Self::get_typed_nft_collection(1129 collection_id,1130 misc::CollectionType::Regular,1131 )?;11321133 Self::check_collection_owner(&collection, &sender)?;11341135 <PalletCommon<T>>::set_scoped_collection_property(1136 collection_id,1137 RMRK_SCOPE,1138 Self::encode_rmrk_property(UserProperty(key.as_slice()), &value)?,1139 )?;1140 }1141 }11421143 Self::deposit_event(Event::PropertySet {1144 collection_id: rmrk_collection_id,1145 maybe_nft_id,1146 key,1147 value,1148 });11491150 Ok(())1151 }11521153 /// Set a different order of resource priorities for an NFT. Priorities can be used,1154 /// for example, for order of rendering.1155 ///1156 /// Note that the priorities are not updated automatically, and are an empty vector1157 /// by default. There is no pre-set definition for the order to be particular,1158 /// it can be interpreted arbitrarily use-case by use-case.1159 ///1160 /// # Permissions:1161 /// - Token owner1162 ///1163 /// # Arguments:1164 /// - `origin`: sender of the transaction1165 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1166 /// - `rmrk_nft_id`: ID of the NFT to rearrange resource priorities for.1167 /// - `priorities`: Ordered vector of resource IDs.1168 #[pallet::weight(<SelfWeightOf<T>>::set_priority())]1169 pub fn set_priority(1170 origin: OriginFor<T>,1171 rmrk_collection_id: RmrkCollectionId,1172 rmrk_nft_id: RmrkNftId,1173 priorities: BoundedVec<RmrkResourceId, RmrkMaxPriorities>,1174 ) -> DispatchResult {1175 let sender = ensure_signed(origin)?;1176 let sender = T::CrossAccountId::from_sub(sender);11771178 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1179 let nft_id = rmrk_nft_id.into();11801181 let collection =1182 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1183 collection.check_is_external()?;11841185 let budget = budget::Value::new(NESTING_BUDGET);11861187 Self::ensure_nft_type(collection_id, nft_id, NftType::Regular)?;1188 Self::ensure_nft_owner(collection_id, nft_id, &sender, &budget)?;11891190 <PalletNft<T>>::set_scoped_token_property(1191 collection_id,1192 nft_id,1193 RMRK_SCOPE,1194 Self::encode_rmrk_property(ResourcePriorities, &priorities.into_inner())?,1195 )?;11961197 Self::deposit_event(Event::<T>::PrioritySet {1198 collection_id: rmrk_collection_id,1199 nft_id: rmrk_nft_id,1200 });12011202 Ok(())1203 }12041205 /// Create and set/propose a basic resource for an NFT.1206 ///1207 /// A basic resource is the simplest, lacking a Base and anything that comes with it.1208 /// See RMRK docs for more information and examples.1209 ///1210 /// # Permissions:1211 /// - Collection issuer - if not the token owner, adding the resource will warrant1212 /// the owner's [acceptance](Pallet::accept_resource).1213 ///1214 /// # Arguments:1215 /// - `origin`: sender of the transaction1216 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1217 /// - `nft_id`: ID of the NFT to assign a resource to.1218 /// - `resource`: Data of the resource to be created.1219 #[pallet::weight(<SelfWeightOf<T>>::add_basic_resource())]1220 pub fn add_basic_resource(1221 origin: OriginFor<T>,1222 rmrk_collection_id: RmrkCollectionId,1223 nft_id: RmrkNftId,1224 resource: RmrkBasicResource,1225 ) -> DispatchResult {1226 let sender = ensure_signed(origin.clone())?;12271228 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1229 let collection =1230 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1231 collection.check_is_external()?;12321233 let resource_id = Self::resource_add(1234 sender,1235 collection_id,1236 nft_id.into(),1237 RmrkResourceTypes::Basic(resource),1238 )?;12391240 Self::deposit_event(Event::ResourceAdded {1241 nft_id,1242 resource_id,1243 });1244 Ok(())1245 }12461247 /// Create and set/propose a composable resource for an NFT.1248 ///1249 /// A composable resource links to a Base and has a subset of its Parts it is composed of.1250 /// See RMRK docs for more information and examples.1251 ///1252 /// # Permissions:1253 /// - Collection issuer - if not the token owner, adding the resource will warrant1254 /// the owner's [acceptance](Pallet::accept_resource).1255 ///1256 /// # Arguments:1257 /// - `origin`: sender of the transaction1258 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1259 /// - `nft_id`: ID of the NFT to assign a resource to.1260 /// - `resource`: Data of the resource to be created.1261 #[pallet::weight(<SelfWeightOf<T>>::add_composable_resource())]1262 pub fn add_composable_resource(1263 origin: OriginFor<T>,1264 rmrk_collection_id: RmrkCollectionId,1265 nft_id: RmrkNftId,1266 resource: RmrkComposableResource,1267 ) -> DispatchResult {1268 let sender = ensure_signed(origin.clone())?;12691270 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1271 let collection =1272 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1273 collection.check_is_external()?;12741275 let base_id = resource.base;12761277 let resource_id = Self::resource_add(1278 sender,1279 collection_id,1280 nft_id.into(),1281 RmrkResourceTypes::Composable(resource),1282 )?;12831284 <PalletNft<T>>::try_mutate_token_aux_property(1285 collection_id,1286 nft_id.into(),1287 RMRK_SCOPE,1288 Self::get_scoped_property_key(AssociatedBases)?,1289 |value| -> DispatchResult {1290 let mut bases: BasesMap = match value {1291 Some(value) => Self::decode_property_value(value)?,1292 None => BasesMap::new(),1293 };12941295 *bases.entry(base_id).or_insert(0) += 1;12961297 *value = Some(Self::encode_property_value(&bases)?);1298 Ok(())1299 },1300 )?;13011302 Self::deposit_event(Event::ResourceAdded {1303 nft_id,1304 resource_id,1305 });1306 Ok(())1307 }13081309 /// Create and set/propose a slot resource for an NFT.1310 ///1311 /// A slot resource links to a Base and a slot ID in it which it can fit into.1312 /// See RMRK docs for more information and examples.1313 ///1314 /// # Permissions:1315 /// - Collection issuer - if not the token owner, adding the resource will warrant1316 /// the owner's [acceptance](Pallet::accept_resource).1317 ///1318 /// # Arguments:1319 /// - `origin`: sender of the transaction1320 /// - `rmrk_collection_id`: RMRK collection ID of the NFT.1321 /// - `nft_id`: ID of the NFT to assign a resource to.1322 /// - `resource`: Data of the resource to be created.1323 #[pallet::weight(<SelfWeightOf<T>>::add_slot_resource())]1324 pub fn add_slot_resource(1325 origin: OriginFor<T>,1326 rmrk_collection_id: RmrkCollectionId,1327 nft_id: RmrkNftId,1328 resource: RmrkSlotResource,1329 ) -> DispatchResult {1330 let sender = ensure_signed(origin.clone())?;13311332 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1333 let collection =1334 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1335 collection.check_is_external()?;13361337 let resource_id = Self::resource_add(1338 sender,1339 collection_id,1340 nft_id.into(),1341 RmrkResourceTypes::Slot(resource),1342 )?;13431344 Self::deposit_event(Event::ResourceAdded {1345 nft_id,1346 resource_id,1347 });1348 Ok(())1349 }13501351 /// Remove and erase a resource from an NFT.1352 ///1353 /// If the sender does not own the NFT, then it will be pending confirmation,1354 /// and will have to be [accepted](Pallet::accept_resource_removal) by the token owner.1355 ///1356 /// # Permissions1357 /// - Collection issuer1358 ///1359 /// # Arguments1360 /// - `origin`: sender of the transaction1361 /// - `rmrk_collection_id`: RMRK ID of a collection to which the NFT making use of the resource belongs to.1362 /// - `nft_id`: ID of the NFT with a resource to be removed.1363 /// - `resource_id`: ID of the resource to be removed.1364 #[pallet::weight(<SelfWeightOf<T>>::remove_resource())]1365 pub fn remove_resource(1366 origin: OriginFor<T>,1367 rmrk_collection_id: RmrkCollectionId,1368 nft_id: RmrkNftId,1369 resource_id: RmrkResourceId,1370 ) -> DispatchResult {1371 let sender = ensure_signed(origin.clone())?;13721373 let collection_id = Self::unique_collection_id(rmrk_collection_id)?;1374 let collection =1375 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1376 collection.check_is_external()?;13771378 Self::resource_remove(sender, collection_id, nft_id.into(), resource_id)?;13791380 Self::deposit_event(Event::ResourceRemoval {1381 nft_id,1382 resource_id,1383 });1384 Ok(())1385 }1386 }1387}13881389impl<T: Config> Pallet<T> {1390 /// Transform one of possible RMRK keys into a byte key with a RMRK scope.1391 pub fn get_scoped_property_key(rmrk_key: RmrkProperty) -> Result<PropertyKey, DispatchError> {1392 let key = rmrk_key.to_key::<T>()?;13931394 let scoped_key = RMRK_SCOPE1395 .apply(key)1396 .map_err(|_| <Error<T>>::RmrkPropertyKeyIsTooLong)?;13971398 Ok(scoped_key)1399 }14001401 /// Form a Unique property, transforming a RMRK key into bytes (without assigning the scope yet)1402 /// and encoding the value from an arbitrary type into bytes.1403 pub fn encode_rmrk_property<E: Encode>(1404 rmrk_key: RmrkProperty,1405 value: &E,1406 ) -> Result<Property, DispatchError> {1407 let key = rmrk_key.to_key::<T>()?;14081409 let value = Self::encode_property_value(value)?;14101411 let property = Property { key, value };14121413 Ok(property)1414 }14151416 /// Encode property value from an arbitrary type into bytes for storage.1417 pub fn encode_property_value<E: Encode, S: Get<u32>>(1418 value: &E,1419 ) -> Result<BoundedBytes<S>, DispatchError> {1420 let value = value1421 .encode()1422 .try_into()1423 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong)?;14241425 Ok(value)1426 }14271428 /// Decode property value from bytes into an arbitrary type.1429 pub fn decode_property_value<D: Decode, S: Get<u32>>(1430 vec: &BoundedBytes<S>,1431 ) -> Result<D, DispatchError> {1432 vec.decode()1433 .map_err(|_| <Error<T>>::UnableToDecodeRmrkData.into())1434 }14351436 /// Change the limit of a property value byte vector.1437 pub fn rebind<L, S>(vec: &BoundedVec<u8, L>) -> Result<BoundedVec<u8, S>, DispatchError>1438 where1439 BoundedVec<u8, S>: TryFrom<Vec<u8>>,1440 {1441 vec.rebind()1442 .map_err(|_| <Error<T>>::RmrkPropertyValueIsTooLong.into())1443 }14441445 /// Initialize a new NFT collection with certain RMRK-scoped properties.1446 ///1447 /// See [`init_collection`](pallet_nonfungible::pallet::Pallet::init_collection) for more details.1448 fn init_collection(1449 sender: T::CrossAccountId,1450 data: CreateCollectionData<T::AccountId>,1451 properties: impl Iterator<Item = Property>,1452 ) -> Result<CollectionId, DispatchError> {1453 let collection_id = <PalletNft<T>>::init_collection(1454 sender.clone(),1455 sender,1456 data,1457 up_data_structs::CollectionFlags {1458 external: true,1459 ..Default::default()1460 },1461 );14621463 if let Err(DispatchError::Arithmetic(_)) = &collection_id {1464 return Err(<Error<T>>::NoAvailableCollectionId.into());1465 }14661467 <PalletCommon<T>>::set_scoped_collection_properties(1468 collection_id?,1469 RMRK_SCOPE,1470 properties,1471 )?;14721473 collection_id1474 }14751476 /// Mint a new NFT with certain RMRK-scoped properties. Sender must be the collection owner.1477 ///1478 /// See [`create_item`](pallet_nonfungible::pallet::Pallet::create_item) for more details.1479 pub fn create_nft(1480 sender: &T::CrossAccountId,1481 owner: &T::CrossAccountId,1482 collection: &NonfungibleHandle<T>,1483 properties: impl Iterator<Item = Property>,1484 ) -> Result<TokenId, DispatchError> {1485 let data = CreateNftExData {1486 properties: BoundedVec::default(),1487 owner: owner.clone(),1488 };14891490 let budget = budget::Value::new(NESTING_BUDGET);14911492 <PalletNft<T>>::create_item(collection, sender, data, &budget)?;14931494 let nft_id = <PalletNft<T>>::current_token_id(collection.id);14951496 <PalletNft<T>>::set_scoped_token_properties(collection.id, nft_id, RMRK_SCOPE, properties)?;14971498 Ok(nft_id)1499 }15001501 /// Burn an NFT, along with its nested children, limited by `max_burns`. The sender must be the token owner.1502 ///1503 /// See [`burn_recursively`](pallet_nonfungible::pallet::Pallet::burn_recursively) for more details.1504 fn destroy_nft(1505 sender: T::CrossAccountId,1506 collection_id: CollectionId,1507 token_id: TokenId,1508 max_burns: u32,1509 error_if_not_owned: Error<T>,1510 ) -> DispatchResultWithPostInfo {1511 let collection =1512 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;15131514 let token_data =1515 <TokenData<T>>::get((collection_id, token_id)).ok_or(<Error<T>>::NoAvailableNftId)?;15161517 let from = token_data.owner;15181519 let owner_check_budget = budget::Value::new(NESTING_BUDGET);15201521 ensure!(1522 <PalletStructure<T>>::check_indirectly_owned(1523 sender.clone(),1524 collection_id,1525 token_id,1526 None,1527 &owner_check_budget1528 )?,1529 error_if_not_owned,1530 );15311532 let burns_budget = budget::Value::new(max_burns);1533 let breadth_budget = budget::Value::new(max_burns);15341535 <PalletNft<T>>::burn_recursively(1536 &collection,1537 &from,1538 token_id,1539 &burns_budget,1540 &breadth_budget,1541 )1542 }15431544 /// Add a sent token pending acceptance to the target owning token as a property.1545 fn insert_pending_child(1546 target: (CollectionId, TokenId),1547 child: (RmrkCollectionId, RmrkNftId),1548 ) -> DispatchResult {1549 Self::mutate_pending_children(target, |pending_children| {1550 pending_children.insert(child);1551 })1552 }15531554 /// Remove a sent token pending acceptance from the target token's properties.1555 fn remove_pending_child(1556 target: (CollectionId, TokenId),1557 child: (RmrkCollectionId, RmrkNftId),1558 ) -> DispatchResult {1559 Self::mutate_pending_children(target, |pending_children| {1560 pending_children.remove(&child);1561 })1562 }15631564 /// Apply a mutation to the property of a token containing sent tokens1565 /// that are currently pending acceptance.1566 fn mutate_pending_children(1567 (target_collection_id, target_nft_id): (CollectionId, TokenId),1568 f: impl FnOnce(&mut PendingChildrenSet),1569 ) -> DispatchResult {1570 <PalletNft<T>>::try_mutate_token_aux_property(1571 target_collection_id,1572 target_nft_id,1573 RMRK_SCOPE,1574 Self::get_scoped_property_key(PendingChildren)?,1575 |pending_children| -> DispatchResult {1576 let mut map = match pending_children {1577 Some(map) => Self::decode_property_value(map)?,1578 None => PendingChildrenSet::new(),1579 };15801581 f(&mut map);15821583 *pending_children = Some(Self::encode_property_value(&map)?);15841585 Ok(())1586 },1587 )1588 }15891590 /// Get an iterator from a token's property containing tokens sent to it1591 /// that are currently pending acceptance.1592 fn iterate_pending_children(1593 collection_id: CollectionId,1594 nft_id: TokenId,1595 ) -> Result<impl Iterator<Item = PendingChild>, DispatchError> {1596 let property = <PalletNft<T>>::token_aux_property((1597 collection_id,1598 nft_id,1599 RMRK_SCOPE,1600 Self::get_scoped_property_key(PendingChildren)?,1601 ));16021603 let pending_children = match property {1604 Some(map) => Self::decode_property_value(&map)?,1605 None => PendingChildrenSet::new(),1606 };16071608 Ok(pending_children.into_iter())1609 }16101611 /// Get incremented resource ID from within an NFT's properties and store the new latest ID.1612 /// Thus, the returned resource ID should be used.1613 ///1614 /// Resource IDs are unique only across an NFT.1615 fn acquire_next_resource_id(1616 collection_id: CollectionId,1617 nft_id: TokenId,1618 ) -> Result<RmrkResourceId, DispatchError> {1619 let resource_id: RmrkResourceId =1620 Self::get_nft_property_decoded(collection_id, nft_id, NextResourceId)?;16211622 let next_id = resource_id1623 .checked_add(1)1624 .ok_or(<Error<T>>::NoAvailableResourceId)?;16251626 <PalletNft<T>>::set_scoped_token_property(1627 collection_id,1628 nft_id,1629 RMRK_SCOPE,1630 Self::encode_rmrk_property(NextResourceId, &next_id)?,1631 )?;16321633 Ok(resource_id)1634 }16351636 /// Create and add a resource for a regular NFT, mark it as pending if the sender1637 /// is not the token owner. The sender must be the collection owner.1638 fn resource_add(1639 sender: T::AccountId,1640 collection_id: CollectionId,1641 nft_id: TokenId,1642 resource: RmrkResourceTypes,1643 ) -> Result<RmrkResourceId, DispatchError> {1644 let collection =1645 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1646 ensure!(collection.owner == sender, Error::<T>::NoPermission);16471648 let sender = T::CrossAccountId::from_sub(sender);1649 let budget = budget::Value::new(NESTING_BUDGET);16501651 let nft_owner = <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)1652 .map_err(Self::map_unique_err_to_proxy)?;16531654 let pending = sender != nft_owner;16551656 let id = Self::acquire_next_resource_id(collection_id, nft_id)?;16571658 let resource_info = RmrkResourceInfo {1659 id,1660 resource,1661 pending,1662 pending_removal: false,1663 };16641665 <PalletNft<T>>::try_mutate_token_aux_property(1666 collection_id,1667 nft_id,1668 RMRK_SCOPE,1669 Self::get_scoped_property_key(ResourceId(id))?,1670 |value| -> DispatchResult {1671 *value = Some(Self::encode_property_value(&resource_info)?);16721673 Ok(())1674 },1675 )?;16761677 Ok(id)1678 }16791680 /// Designate a resource for erasure from an NFT, and remove it if the sender is the token owner.1681 /// The sender must be the collection owner.1682 fn resource_remove(1683 sender: T::AccountId,1684 collection_id: CollectionId,1685 nft_id: TokenId,1686 resource_id: RmrkResourceId,1687 ) -> DispatchResult {1688 let collection =1689 Self::get_typed_nft_collection(collection_id, misc::CollectionType::Regular)?;1690 ensure!(collection.owner == sender, Error::<T>::NoPermission);16911692 let resource_id_key = Self::get_scoped_property_key(ResourceId(resource_id))?;16931694 let resource = <PalletNft<T>>::token_aux_property((1695 collection_id,1696 nft_id,1697 RMRK_SCOPE,1698 resource_id_key.clone(),1699 ))1700 .ok_or(<Error<T>>::ResourceDoesntExist)?;17011702 let resource_info: RmrkResourceInfo = Self::decode_property_value(&resource)?;17031704 let budget = up_data_structs::budget::Value::new(NESTING_BUDGET);1705 let topmost_owner =1706 <PalletStructure<T>>::find_topmost_owner(collection_id, nft_id, &budget)?;17071708 let sender = T::CrossAccountId::from_sub(sender);1709 if topmost_owner == sender {1710 <PalletNft<T>>::remove_token_aux_property(1711 collection_id,1712 nft_id,1713 RMRK_SCOPE,1714 Self::get_scoped_property_key(ResourceId(resource_id))?,1715 );17161717 if let RmrkResourceTypes::Composable(resource) = resource_info.resource {1718 let base_id = resource.base;17191720 Self::remove_associated_base_id(collection_id, nft_id, base_id)?;1721 }1722 } else {1723 Self::try_mutate_resource_info(collection_id, nft_id, resource_id, |res| {1724 res.pending_removal = true;17251726 Ok(())1727 })?;1728 }17291730 Ok(())1731 }17321733 /// Remove a Base ID from an NFT if they are associated.1734 /// The Base itself is deleted if the number of associated NFTs reaches 0.1735 fn remove_associated_base_id(1736 collection_id: CollectionId,1737 nft_id: TokenId,1738 base_id: RmrkBaseId,1739 ) -> DispatchResult {1740 <PalletNft<T>>::try_mutate_token_aux_property(1741 collection_id,1742 nft_id,1743 RMRK_SCOPE,1744 Self::get_scoped_property_key(AssociatedBases)?,1745 |value| -> DispatchResult {1746 let mut bases: BasesMap = match value {1747 Some(value) => Self::decode_property_value(value)?,1748 None => BasesMap::new(),1749 };17501751 let remaining = bases.get(&base_id);17521753 if let Some(remaining) = remaining {1754 if let Some(0) | None = remaining.checked_sub(1) {1755 bases.remove(&base_id);1756 }1757 }17581759 *value = Some(Self::encode_property_value(&bases)?);1760 Ok(())1761 },1762 )1763 }17641765 /// Apply a mutation to a resource stored in the token properties of an NFT.1766 fn try_mutate_resource_info(1767 collection_id: CollectionId,1768 nft_id: TokenId,1769 resource_id: RmrkResourceId,1770 f: impl FnOnce(&mut RmrkResourceInfo) -> DispatchResult,1771 ) -> DispatchResult {1772 <PalletNft<T>>::try_mutate_token_aux_property(1773 collection_id,1774 nft_id,1775 RMRK_SCOPE,1776 Self::get_scoped_property_key(ResourceId(resource_id))?,1777 |value| match value {1778 Some(value) => {1779 let mut resource_info: RmrkResourceInfo = Self::decode_property_value(value)?;17801781 f(&mut resource_info)?;17821783 *value = Self::encode_property_value(&resource_info)?;17841785 Ok(())1786 }1787 None => Err(<Error<T>>::ResourceDoesntExist.into()),1788 },1789 )1790 }17911792 /// Change the owner of an NFT collection, ensuring that the sender is the current owner.1793 fn change_collection_owner(1794 collection_id: CollectionId,1795 collection_type: misc::CollectionType,1796 sender: T::AccountId,1797 new_owner: T::AccountId,1798 ) -> DispatchResult {1799 let collection = Self::get_typed_nft_collection(collection_id, collection_type)?;1800 Self::check_collection_owner(&collection, &T::CrossAccountId::from_sub(sender))?;18011802 let mut collection = collection.into_inner();18031804 collection.owner = new_owner;1805 collection.save()1806 }18071808 /// Ensure that an account is the collection owner/issuer, return an error if not.1809 pub fn check_collection_owner(1810 collection: &NonfungibleHandle<T>,1811 account: &T::CrossAccountId,1812 ) -> DispatchResult {1813 collection1814 .check_is_owner(account)1815 .map_err(Self::map_unique_err_to_proxy)1816 }18171818 /// Get the latest yet-unused RMRK collection index from the storage.1819 pub fn last_collection_idx() -> RmrkCollectionId {1820 <CollectionIndex<T>>::get()1821 }18221823 /// Get a mapping from a RMRK collection ID to its corresponding Unique collection ID.1824 pub fn unique_collection_id(1825 rmrk_collection_id: RmrkCollectionId,1826 ) -> Result<CollectionId, DispatchError> {1827 <UniqueCollectionId<T>>::try_get(rmrk_collection_id)1828 .map_err(|_| <Error<T>>::CollectionUnknown.into())1829 }18301831 /// Get a mapping from a Unique collection ID to its RMRK collection ID counterpart, if it exists.1832 pub fn rmrk_collection_id(1833 unique_collection_id: CollectionId,1834 ) -> Result<RmrkCollectionId, DispatchError> {1835 Self::get_collection_property_decoded(unique_collection_id, RmrkInternalCollectionId)1836 }18371838 /// Fetch a Unique NFT collection.1839 pub fn get_nft_collection(1840 collection_id: CollectionId,1841 ) -> Result<NonfungibleHandle<T>, DispatchError> {1842 let collection = <CollectionHandle<T>>::try_get(collection_id)1843 .map_err(|_| <Error<T>>::CollectionUnknown)?;18441845 match collection.mode {1846 CollectionMode::NFT => Ok(NonfungibleHandle::cast(collection)),1847 _ => Err(<Error<T>>::CollectionUnknown.into()),1848 }1849 }18501851 /// Check if an NFT collection with such an ID exists.1852 pub fn collection_exists(collection_id: CollectionId) -> bool {1853 <CollectionHandle<T>>::try_get(collection_id).is_ok()1854 }18551856 /// Fetch and decode a RMRK-scoped collection property value in bytes.1857 pub fn get_collection_property(1858 collection_id: CollectionId,1859 key: RmrkProperty,1860 ) -> Result<PropertyValue, DispatchError> {1861 let collection_property = <PalletCommon<T>>::collection_properties(collection_id)1862 .get(&Self::get_scoped_property_key(key)?)1863 .ok_or(<Error<T>>::CollectionUnknown)?1864 .clone();18651866 Ok(collection_property)1867 }18681869 /// Fetch a RMRK-scoped collection property and decode it from bytes into an appropriate type.1870 pub fn get_collection_property_decoded<V: Decode>(1871 collection_id: CollectionId,1872 key: RmrkProperty,1873 ) -> Result<V, DispatchError> {1874 Self::decode_property_value(&Self::get_collection_property(collection_id, key)?)1875 }18761877 /// Get the type of a collection stored as a scoped property.1878 ///1879 /// RMRK Core proxy differentiates between regular collections as well as RMRK Bases as collections.1880 pub fn get_collection_type(1881 collection_id: CollectionId,1882 ) -> Result<misc::CollectionType, DispatchError> {1883 Self::get_collection_property_decoded(collection_id, CollectionType).map_err(|err| {1884 if err != <Error<T>>::CollectionUnknown.into() {1885 <Error<T>>::CorruptedCollectionType.into()1886 } else {1887 err1888 }1889 })1890 }18911892 /// Ensure that the type of the collection equals the provided type,1893 /// otherwise return an error.1894 pub fn ensure_collection_type(1895 collection_id: CollectionId,1896 collection_type: misc::CollectionType,1897 ) -> DispatchResult {1898 let actual_type = Self::get_collection_type(collection_id)?;1899 ensure!(1900 actual_type == collection_type,1901 <CommonError<T>>::NoPermission1902 );19031904 Ok(())1905 }19061907 /// Fetch an NFT collection, but make sure it has the appropriate type.1908 pub fn get_typed_nft_collection(1909 collection_id: CollectionId,1910 collection_type: misc::CollectionType,1911 ) -> Result<NonfungibleHandle<T>, DispatchError> {1912 Self::ensure_collection_type(collection_id, collection_type)?;19131914 Self::get_nft_collection(collection_id)1915 }19161917 /// Same as [`get_typed_nft_collection`](crate::pallet::Pallet::get_typed_nft_collection),1918 /// but also return the Unique collection ID.1919 pub fn get_typed_nft_collection_mapped(1920 rmrk_collection_id: RmrkCollectionId,1921 collection_type: misc::CollectionType,1922 ) -> Result<(NonfungibleHandle<T>, CollectionId), DispatchError> {1923 let unique_collection_id = match collection_type {1924 misc::CollectionType::Regular => Self::unique_collection_id(rmrk_collection_id)?,1925 _ => rmrk_collection_id.into(),1926 };19271928 let collection = Self::get_typed_nft_collection(unique_collection_id, collection_type)?;19291930 Ok((collection, unique_collection_id))1931 }19321933 /// Fetch and decode a RMRK-scoped NFT property value in bytes.1934 pub fn get_nft_property(1935 collection_id: CollectionId,1936 nft_id: TokenId,1937 key: RmrkProperty,1938 ) -> Result<PropertyValue, DispatchError> {1939 let nft_property = <PalletNft<T>>::token_properties((collection_id, nft_id))1940 .get(&Self::get_scoped_property_key(key)?)1941 .ok_or(<Error<T>>::RmrkPropertyIsNotFound)?1942 .clone();19431944 Ok(nft_property)1945 }19461947 /// Fetch a RMRK-scoped NFT property and decode it from bytes into an appropriate type.1948 pub fn get_nft_property_decoded<V: Decode>(1949 collection_id: CollectionId,1950 nft_id: TokenId,1951 key: RmrkProperty,1952 ) -> Result<V, DispatchError> {1953 Self::decode_property_value(&Self::get_nft_property(collection_id, nft_id, key)?)1954 }19551956 /// Check that an NFT exists.1957 pub fn nft_exists(collection_id: CollectionId, nft_id: TokenId) -> bool {1958 <TokenData<T>>::contains_key((collection_id, nft_id))1959 }19601961 /// Get the type of an NFT stored as a scoped property.1962 ///1963 /// RMRK Core proxy differentiates between regular NFTs, and RMRK Parts and Themes.1964 pub fn get_nft_type(1965 collection_id: CollectionId,1966 token_id: TokenId,1967 ) -> Result<NftType, DispatchError> {1968 Self::get_nft_property_decoded(collection_id, token_id, TokenType)1969 .map_err(|_| <Error<T>>::NoAvailableNftId.into())1970 }19711972 /// Ensure that the type of the NFT equals the provided type, otherwise return an error.1973 pub fn ensure_nft_type(1974 collection_id: CollectionId,1975 token_id: TokenId,1976 nft_type: NftType,1977 ) -> DispatchResult {1978 let actual_type = Self::get_nft_type(collection_id, token_id)?;1979 ensure!(actual_type == nft_type, <Error<T>>::NoPermission);19801981 Ok(())1982 }19831984 /// Ensure that an account is the owner of the token, either directly1985 /// or at the top of the nesting hierarchy; return an error if it is not.1986 pub fn ensure_nft_owner(1987 collection_id: CollectionId,1988 token_id: TokenId,1989 possible_owner: &T::CrossAccountId,1990 nesting_budget: &dyn budget::Budget,1991 ) -> DispatchResult {1992 let is_owned = <PalletStructure<T>>::check_indirectly_owned(1993 possible_owner.clone(),1994 collection_id,1995 token_id,1996 None,1997 nesting_budget,1998 )1999 .map_err(Self::map_unique_err_to_proxy)?;20002001 ensure!(is_owned, <Error<T>>::NoPermission);20022003 Ok(())2004 }20052006 /// Fetch non-scoped properties of a collection or a token that match the filter keys supplied,2007 /// or, if None are provided, return all non-scoped properties.2008 pub fn filter_user_properties<Key, Value, R, Mapper>(2009 collection_id: CollectionId,2010 token_id: Option<TokenId>,2011 filter_keys: Option<Vec<RmrkPropertyKey>>,2012 mapper: Mapper,2013 ) -> Result<Vec<R>, DispatchError>2014 where2015 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,2016 Value: Decode + Default,2017 Mapper: Fn(Key, Value) -> R,2018 {2019 filter_keys2020 .map(|keys| {2021 let properties = keys2022 .into_iter()2023 .filter_map(|key| {2024 let key: Key = key.try_into().ok()?;20252026 let value = match token_id {2027 Some(token_id) => Self::get_nft_property_decoded(2028 collection_id,2029 token_id,2030 UserProperty(key.as_ref()),2031 ),2032 None => Self::get_collection_property_decoded(2033 collection_id,2034 UserProperty(key.as_ref()),2035 ),2036 }2037 .ok()?;20382039 Some(mapper(key, value))2040 })2041 .collect();20422043 Ok(properties)2044 })2045 .unwrap_or_else(|| {2046 let properties =2047 Self::iterate_user_properties(collection_id, token_id, mapper)?.collect();20482049 Ok(properties)2050 })2051 }20522053 /// Get all non-scoped properties from a collection or a token, and apply some transformation,2054 /// supplied by `mapper`, to each key-value pair.2055 pub fn iterate_user_properties<Key, Value, R, Mapper>(2056 collection_id: CollectionId,2057 token_id: Option<TokenId>,2058 mapper: Mapper,2059 ) -> Result<impl Iterator<Item = R>, DispatchError>2060 where2061 Key: TryFrom<RmrkPropertyKey> + AsRef<[u8]>,2062 Value: Decode + Default,2063 Mapper: Fn(Key, Value) -> R,2064 {2065 let properties = match token_id {2066 Some(token_id) => <PalletNft<T>>::token_properties((collection_id, token_id)),2067 None => <PalletCommon<T>>::collection_properties(collection_id),2068 };20692070 let properties = properties.into_iter().filter_map(move |(key, value)| {2071 let key = strip_key_prefix(&key, USER_PROPERTY_PREFIX)?;20722073 let key: Key = key.to_vec().try_into().ok()?;2074 let value: Value = value.decode().ok()?;20752076 Some(mapper(key, value))2077 });20782079 Ok(properties)2080 }20812082 /// Match Unique errors to RMRK's own and return the RMRK error if a match is successful.2083 fn map_unique_err_to_proxy(err: DispatchError) -> DispatchError {2084 map_unique_err_to_proxy! {2085 match err {2086 CommonError::NoPermission => NoPermission,2087 CommonError::CollectionTokenLimitExceeded => CollectionFullOrLocked,2088 CommonError::PublicMintingNotAllowed => NoPermission,2089 CommonError::TokenNotFound => NoAvailableNftId,2090 CommonError::ApprovedValueTooLow => NoPermission,2091 CommonError::CantDestroyNotEmptyCollection => CollectionNotEmpty,2092 StructureError::TokenNotFound => NoAvailableNftId,2093 StructureError::OuroborosDetected => CannotSendToDescendentOrSelf,2094 }2095 }2096 }2097}pallets/proxy-rmrk-equip/Cargo.tomldiffbeforeafterboth--- a/pallets/proxy-rmrk-equip/Cargo.toml
+++ b/pallets/proxy-rmrk-equip/Cargo.toml
@@ -19,7 +19,7 @@
pallet-common = { default-features = false, path = '../common' }
pallet-nonfungible = { default-features = false, path = "../../pallets/nonfungible" }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
rmrk-traits = { default-features = false, path = "../../primitives/rmrk-traits" }
scale-info = { version = "2.0.1", default-features = false, features = [
pallets/refungible/Cargo.tomldiffbeforeafterboth--- a/pallets/refungible/Cargo.toml
+++ b/pallets/refungible/Cargo.toml
@@ -16,7 +16,7 @@
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
pallet-common = { default-features = false, path = '../common' }
pallets/structure/Cargo.tomldiffbeforeafterboth--- a/pallets/structure/Cargo.toml
+++ b/pallets/structure/Cargo.toml
@@ -16,7 +16,7 @@
"derive",
] }
up-data-structs = { path = "../../primitives/data-structs", default-features = false }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
[features]
default = ["std"]
pallets/unique/Cargo.tomldiffbeforeafterboth--- a/pallets/unique/Cargo.toml
+++ b/pallets/unique/Cargo.toml
@@ -100,7 +100,7 @@
scale-info = { version = "2.0.1", default-features = false, features = [
"derive",
] }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
pallet-common = { default-features = false, path = "../common" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' }
pallets/unique/src/lib.rsdiffbeforeafterboth--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -138,7 +138,7 @@
pub enum Event<T>
where
<T as frame_system::Config>::AccountId,
- <T as pallet_evm::account::Config>::CrossAccountId,
+ <T as pallet_evm::Config>::CrossAccountId,
{
/// Collection sponsor was removed
///
primitives/app_promotion_rpc/Cargo.tomldiffbeforeafterboth--- a/primitives/app_promotion_rpc/Cargo.toml
+++ b/primitives/app_promotion_rpc/Cargo.toml
@@ -14,7 +14,7 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
[features]
default = ["std"]
primitives/common/Cargo.tomldiffbeforeafterboth--- a/primitives/common/Cargo.toml
+++ b/primitives/common/Cargo.toml
@@ -48,9 +48,9 @@
[dependencies.fp-rpc]
default-features = false
git = "https://github.com/uniquenetwork/frontier"
-branch = "unique-polkadot-v0.9.30"
+branch = "unique-polkadot-v0.9.30-2"
[dependencies.pallet-evm]
default-features = false
git = "https://github.com/uniquenetwork/frontier"
-branch = "unique-polkadot-v0.9.30"
+branch = "unique-polkadot-v0.9.30-2"
primitives/data-structs/Cargo.tomldiffbeforeafterboth--- a/primitives/data-structs/Cargo.toml
+++ b/primitives/data-structs/Cargo.toml
@@ -25,9 +25,11 @@
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
derivative = { version = "2.2.0", features = ["use_core"] }
struct-versioning = { path = "../../crates/struct-versioning" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
rmrk-traits = { default-features = false, path = "../rmrk-traits" }
-bondrewd = { version = "0.1.14", features = ["derive"], default-features = false }
+bondrewd = { version = "0.1.14", features = [
+ "derive",
+], default-features = false }
[features]
default = ["std"]
primitives/data-structs/src/lib.rsdiffbeforeafterboth--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -962,12 +962,15 @@
use scale_info::{
Type, Path,
build::{FieldsBuilder, UnnamedFields},
+ form::MetaForm,
type_params,
};
Type::builder()
.path(Path::new("up_data_structs", "PhantomType"))
.type_params(type_params!(T))
- .composite(<FieldsBuilder<UnnamedFields>>::default().field(|b| b.ty::<[T; 0]>()))
+ .composite(
+ <FieldsBuilder<MetaForm, UnnamedFields>>::default().field(|b| b.ty::<[T; 0]>()),
+ )
}
}
impl<T> MaxEncodedLen for PhantomType<T> {
primitives/rpc/Cargo.tomldiffbeforeafterboth--- a/primitives/rpc/Cargo.toml
+++ b/primitives/rpc/Cargo.toml
@@ -14,7 +14,7 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-api = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
[features]
default = ["std"]
runtime/common/config/ethereum.rsdiffbeforeafterboth--- a/runtime/common/config/ethereum.rs
+++ b/runtime/common/config/ethereum.rs
@@ -17,19 +17,15 @@
pub type CrossAccountId = pallet_evm::account::BasicCrossAccountId<Runtime>;
-impl pallet_evm::account::Config for Runtime {
- type CrossAccountId = CrossAccountId;
- type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
- type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
-}
-
// Assuming slowest ethereum opcode is SSTORE, with gas price of 20000 as our worst case
// (contract, which only writes a lot of data),
// approximating on top of our real store write weight
parameter_types! {
pub const WritesPerSecond: u64 = WEIGHT_PER_SECOND.ref_time() / <Runtime as frame_system::Config>::DbWeight::get().write;
pub const GasPerSecond: u64 = WritesPerSecond::get() * 20000;
- pub const WeightPerGas: u64 = WEIGHT_PER_SECOND.ref_time() / GasPerSecond::get();
+ pub const WeightTimePerGas: u64 = WEIGHT_PER_SECOND.ref_time() / GasPerSecond::get();
+
+ pub const WeightPerGas: Weight = Weight::from_ref_time(WeightTimePerGas::get());
}
/// Limiting EVM execution to 50% of block for substrate users and management tasks
@@ -37,17 +33,7 @@
/// scheduled fairly
const EVM_DISPATCH_RATIO: Perbill = Perbill::from_percent(50);
parameter_types! {
- pub BlockGasLimit: U256 = U256::from((NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightPerGas::get()).ref_time());
-}
-
-pub enum FixedGasWeightMapping {}
-impl pallet_evm::GasWeightMapping for FixedGasWeightMapping {
- fn gas_to_weight(gas: u64) -> Weight {
- Weight::from_ref_time(gas).saturating_mul(WeightPerGas::get())
- }
- fn weight_to_gas(weight: Weight) -> u64 {
- (weight / WeightPerGas::get()).ref_time()
- }
+ pub BlockGasLimit: U256 = U256::from((NORMAL_DISPATCH_RATIO * EVM_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT / WeightTimePerGas::get()).ref_time());
}
pub struct EthereumFindAuthor<F>(core::marker::PhantomData<F>);
@@ -65,9 +51,13 @@
}
impl pallet_evm::Config for Runtime {
+ type CrossAccountId = CrossAccountId;
+ type EvmAddressMapping = pallet_evm::HashedAddressMapping<Self::Hashing>;
+ type EvmBackwardsAddressMapping = fp_evm_mapping::MapBackwardsAddressTruncated;
type BlockGasLimit = BlockGasLimit;
type FeeCalculator = pallet_configuration::FeeCalculator<Self>;
- type GasWeightMapping = FixedGasWeightMapping;
+ type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
+ type WeightPerGas = WeightPerGas;
type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping<Self>;
type CallOrigin = EnsureAddressTruncated<Self>;
type WithdrawOrigin = EnsureAddressTruncated<Self>;
runtime/common/ethereum/self_contained_call.rsdiffbeforeafterboth--- a/runtime/common/ethereum/self_contained_call.rs
+++ b/runtime/common/ethereum/self_contained_call.rs
@@ -69,9 +69,13 @@
fn pre_dispatch_self_contained(
&self,
info: &Self::SignedInfo,
+ dispatch_info: &DispatchInfoOf<RuntimeCall>,
+ len: usize,
) -> Option<Result<(), TransactionValidityError>> {
match self {
- RuntimeCall::Ethereum(call) => call.pre_dispatch_self_contained(info),
+ RuntimeCall::Ethereum(call) => {
+ call.pre_dispatch_self_contained(info, dispatch_info, len)
+ }
_ => None,
}
}
runtime/common/runtime_apis.rsdiffbeforeafterboth--- a/runtime/common/runtime_apis.rs
+++ b/runtime/common/runtime_apis.rs
@@ -493,6 +493,7 @@
nonce,
access_list.unwrap_or_default(),
is_transactional,
+ false,
config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
).map_err(|err| err.error.into())
}
@@ -528,6 +529,7 @@
nonce,
access_list.unwrap_or_default(),
is_transactional,
+ false,
config.as_ref().unwrap_or_else(|| <Runtime as pallet_evm::Config>::config()),
).map_err(|err| err.error.into())
}
runtime/opal/Cargo.tomldiffbeforeafterboth--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -82,7 +82,6 @@
'pallet-proxy-rmrk-equip/try-runtime',
'pallet-app-promotion/try-runtime',
'pallet-foreign-assets/try-runtime',
- 'pallet-evm/try-runtime',
'pallet-ethereum/try-runtime',
'pallet-evm-coder-substrate/try-runtime',
'pallet-evm-contract-helpers/try-runtime',
@@ -174,7 +173,14 @@
'pallet-test-utils?/std',
]
limit-testing = ['pallet-unique/limit-testing', 'up-data-structs/limit-testing']
-opal-runtime = ['refungible', 'scheduler', 'rmrk', 'app-promotion', 'foreign-assets', 'pallet-test-utils']
+opal-runtime = [
+ 'refungible',
+ 'scheduler',
+ 'rmrk',
+ 'app-promotion',
+ 'foreign-assets',
+ 'pallet-test-utils',
+]
refungible = []
scheduler = []
@@ -461,7 +467,7 @@
up-rpc = { path = "../../primitives/rpc", default-features = false }
app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
rmrk-rpc = { path = "../../primitives/rmrk-rpc", default-features = false }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
pallet-inflation = { path = '../../pallets/inflation', default-features = false }
pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
up-data-structs = { path = '../../primitives/data-structs', default-features = false }
@@ -479,11 +485,11 @@
pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
runtime/quartz/Cargo.tomldiffbeforeafterboth--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -80,7 +80,6 @@
'pallet-proxy-rmrk-equip/try-runtime',
'pallet-app-promotion/try-runtime',
'pallet-foreign-assets/try-runtime',
- 'pallet-evm/try-runtime',
'pallet-ethereum/try-runtime',
'pallet-evm-coder-substrate/try-runtime',
'pallet-evm-contract-helpers/try-runtime',
@@ -460,7 +459,7 @@
pallet-unique = { path = '../../pallets/unique', default-features = false }
up-rpc = { path = "../../primitives/rpc", default-features = false }
app-promotion-rpc = { path = "../../primitives/app_promotion_rpc", default-features = false }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
pallet-inflation = { path = '../../pallets/inflation', default-features = false }
pallet-app-promotion = { path = '../../pallets/app-promotion', default-features = false }
up-data-structs = { path = '../../primitives/data-structs', default-features = false }
@@ -478,11 +477,11 @@
pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
runtime/tests/Cargo.tomldiffbeforeafterboth--- a/runtime/tests/Cargo.toml
+++ b/runtime/tests/Cargo.toml
@@ -16,7 +16,7 @@
sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
@@ -25,8 +25,8 @@
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
pallet-common = { path = '../../pallets/common' }
pallet-structure = { path = '../../pallets/structure' }
runtime/tests/src/lib.rsdiffbeforeafterboth--- a/runtime/tests/src/lib.rs
+++ b/runtime/tests/src/lib.rs
@@ -21,6 +21,7 @@
parameter_types,
traits::{Everything, ConstU32, ConstU64},
weights::IdentityFee,
+ pallet_prelude::Weight,
};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
@@ -202,6 +203,7 @@
parameter_types! {
pub BlockGasLimit: U256 = 0u32.into();
+ pub WeightPerGas: Weight = Weight::from_ref_time(20);
}
impl pallet_ethereum::Config for Test {
@@ -210,11 +212,15 @@
}
impl pallet_evm::Config for Test {
+ type CrossAccountId = TestCrossAccountId;
+ type EvmAddressMapping = TestEvmAddressMapping;
+ type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
type RuntimeEvent = RuntimeEvent;
type FeeCalculator = ();
- type GasWeightMapping = ();
- type CallOrigin = EnsureAddressNever<Self::CrossAccountId>;
- type WithdrawOrigin = EnsureAddressNever<Self::CrossAccountId>;
+ type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
+ type WeightPerGas = WeightPerGas;
+ type CallOrigin = EnsureAddressNever<Self>;
+ type WithdrawOrigin = EnsureAddressNever<Self>;
type AddressMapping = TestEvmAddressMapping;
type Currency = Balances;
type PrecompilesType = ();
@@ -242,12 +248,6 @@
type EvmTokenAddressMapping = EvmTokenAddressMapping;
type CrossTokenAddressMapping = CrossTokenAddressMapping<Self::AccountId>;
type ContractAddress = EvmCollectionHelpersAddress;
-}
-
-impl pallet_evm::account::Config for Test {
- type CrossAccountId = TestCrossAccountId;
- type EvmAddressMapping = TestEvmAddressMapping;
- type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
}
impl pallet_structure::Config for Test {
runtime/unique/Cargo.tomldiffbeforeafterboth--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -81,7 +81,6 @@
'pallet-proxy-rmrk-equip/try-runtime',
'pallet-app-promotion/try-runtime',
'pallet-foreign-assets/try-runtime',
- 'pallet-evm/try-runtime',
'pallet-ethereum/try-runtime',
'pallet-evm-coder-substrate/try-runtime',
'pallet-evm-contract-helpers/try-runtime',
@@ -472,12 +471,12 @@
pallet-evm-contract-helpers = { path = '../../pallets/evm-contract-helpers', default-features = false }
pallet-evm-transaction-payment = { path = '../../pallets/evm-transaction-payment', default-features = false }
pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
-fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30" }
+pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+pallet-base-fee = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-rpc = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-self-contained = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
+fp-evm-mapping = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.30-2" }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
up-sponsorship = { default-features = false, git = "https://github.com/uniquenetwork/pallet-sponsoring", branch = 'polkadot-v0.9.30' }
pallet-foreign-assets = { default-features = false, path = "../../pallets/foreign-assets" }
tests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth--- a/tests/src/eth/contractSponsoring.test.ts
+++ b/tests/src/eth/contractSponsoring.test.ts
@@ -372,7 +372,7 @@
const originalFlipperBalance = await helper.balance.getEthereum(flipper.options.address);
expect(originalFlipperBalance).to.be.not.equal('0');
- await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);
+ await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/Returned error: insufficient funds for gas \* price \+ value/);
expect(await flipper.methods.getValue().call()).to.be.false;
// Balance should be taken from flipper instead of caller
tests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -265,6 +265,14 @@
**/
FeeOverflow: AugmentedError<ApiType>;
/**
+ * Gas limit is too high.
+ **/
+ GasLimitTooHigh: AugmentedError<ApiType>;
+ /**
+ * Gas limit is too low.
+ **/
+ GasLimitTooLow: AugmentedError<ApiType>;
+ /**
* Gas price is too low.
**/
GasPriceTooLow: AugmentedError<ApiType>;
@@ -277,6 +285,14 @@
**/
PaymentOverflow: AugmentedError<ApiType>;
/**
+ * EVM reentrancy
+ **/
+ Reentrancy: AugmentedError<ApiType>;
+ /**
+ * Undefined error.
+ **/
+ Undefined: AugmentedError<ApiType>;
+ /**
* Withdraw fee failed
**/
WithdrawFailed: AugmentedError<ApiType>;
tests/src/interfaces/augment-api-events.tsdiffbeforeafterboth--- a/tests/src/interfaces/augment-api-events.ts
+++ b/tests/src/interfaces/augment-api-events.ts
@@ -6,7 +6,7 @@
import '@polkadot/api-base/types/events';
import type { ApiTypes, AugmentedEvent } from '@polkadot/api-base/types';
-import type { Bytes, Null, Option, Result, U256, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';
+import type { Bytes, Null, Option, Result, U8aFixed, bool, u128, u32, u64, u8 } from '@polkadot/types-codec';
import type { ITuple } from '@polkadot/types-codec/types';
import type { AccountId32, H160, H256, Weight } from '@polkadot/types/interfaces/runtime';
import type { EthereumLog, EvmCoreErrorExitReason, FrameSupportDispatchDispatchInfo, FrameSupportScheduleLookupError, FrameSupportTokensMiscBalanceStatus, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, PalletForeignAssetsAssetIds, PalletForeignAssetsModuleAssetMetadata, RmrkTraitsNftAccountIdOrCollectionNftTuple, SpRuntimeDispatchError, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetMultiAssets, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation } from '@polkadot/types/lookup';
@@ -204,9 +204,9 @@
};
ethereum: {
/**
- * An ethereum transaction was successfully executed. [from, to/contract_address, transaction_hash, exit_reason]
+ * An ethereum transaction was successfully executed.
**/
- Executed: AugmentedEvent<ApiType, [H160, H160, H256, EvmCoreErrorExitReason]>;
+ Executed: AugmentedEvent<ApiType, [from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason], { from: H160, to: H160, transactionHash: H256, exitReason: EvmCoreErrorExitReason }>;
/**
* Generic event
**/
@@ -214,33 +214,25 @@
};
evm: {
/**
- * A deposit has been made at a given address. \[sender, address, value\]
+ * A contract has been created at given address.
**/
- BalanceDeposit: AugmentedEvent<ApiType, [AccountId32, H160, U256]>;
+ Created: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
/**
- * A withdrawal has been made from a given address. \[sender, address, value\]
+ * A contract was attempted to be created, but the execution failed.
**/
- BalanceWithdraw: AugmentedEvent<ApiType, [AccountId32, H160, U256]>;
+ CreatedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
/**
- * A contract has been created at given \[address\].
+ * A contract has been executed successfully with states applied.
**/
- Created: AugmentedEvent<ApiType, [H160]>;
+ Executed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
/**
- * A \[contract\] was attempted to be created, but the execution failed.
+ * A contract has been executed with errors. States are reverted with only gas fees applied.
**/
- CreatedFailed: AugmentedEvent<ApiType, [H160]>;
- /**
- * A \[contract\] has been executed successfully with states applied.
- **/
- Executed: AugmentedEvent<ApiType, [H160]>;
- /**
- * A \[contract\] has been executed with errors. States are reverted with only gas fees applied.
- **/
- ExecutedFailed: AugmentedEvent<ApiType, [H160]>;
+ ExecutedFailed: AugmentedEvent<ApiType, [address: H160], { address: H160 }>;
/**
* Ethereum events from contracts.
**/
- Log: AugmentedEvent<ApiType, [EthereumLog]>;
+ Log: AugmentedEvent<ApiType, [log: EthereumLog], { log: EthereumLog }>;
/**
* Generic event
**/
tests/src/interfaces/default/types.tsdiffbeforeafterboth--- a/tests/src/interfaces/default/types.ts
+++ b/tests/src/interfaces/default/types.ts
@@ -1347,7 +1347,12 @@
/** @name PalletEthereumEvent */
export interface PalletEthereumEvent extends Enum {
readonly isExecuted: boolean;
- readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
+ readonly asExecuted: {
+ readonly from: H160;
+ readonly to: H160;
+ readonly transactionHash: H256;
+ readonly exitReason: EvmCoreErrorExitReason;
+ } & Struct;
readonly type: 'Executed';
}
@@ -1457,26 +1462,36 @@
readonly isWithdrawFailed: boolean;
readonly isGasPriceTooLow: boolean;
readonly isInvalidNonce: boolean;
- readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
+ readonly isGasLimitTooLow: boolean;
+ readonly isGasLimitTooHigh: boolean;
+ readonly isUndefined: boolean;
+ readonly isReentrancy: boolean;
+ readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce' | 'GasLimitTooLow' | 'GasLimitTooHigh' | 'Undefined' | 'Reentrancy';
}
/** @name PalletEvmEvent */
export interface PalletEvmEvent extends Enum {
readonly isLog: boolean;
- readonly asLog: EthereumLog;
+ readonly asLog: {
+ readonly log: EthereumLog;
+ } & Struct;
readonly isCreated: boolean;
- readonly asCreated: H160;
+ readonly asCreated: {
+ readonly address: H160;
+ } & Struct;
readonly isCreatedFailed: boolean;
- readonly asCreatedFailed: H160;
+ readonly asCreatedFailed: {
+ readonly address: H160;
+ } & Struct;
readonly isExecuted: boolean;
- readonly asExecuted: H160;
+ readonly asExecuted: {
+ readonly address: H160;
+ } & Struct;
readonly isExecutedFailed: boolean;
- readonly asExecutedFailed: H160;
- readonly isBalanceDeposit: boolean;
- readonly asBalanceDeposit: ITuple<[AccountId32, H160, U256]>;
- readonly isBalanceWithdraw: boolean;
- readonly asBalanceWithdraw: ITuple<[AccountId32, H160, U256]>;
- readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
+ readonly asExecutedFailed: {
+ readonly address: H160;
+ } & Struct;
+ readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed';
}
/** @name PalletEvmMigrationCall */
tests/src/interfaces/lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1216,13 +1216,21 @@
**/
PalletEvmEvent: {
_enum: {
- Log: 'EthereumLog',
- Created: 'H160',
- CreatedFailed: 'H160',
- Executed: 'H160',
- ExecutedFailed: 'H160',
- BalanceDeposit: '(AccountId32,H160,U256)',
- BalanceWithdraw: '(AccountId32,H160,U256)'
+ Log: {
+ log: 'EthereumLog',
+ },
+ Created: {
+ address: 'H160',
+ },
+ CreatedFailed: {
+ address: 'H160',
+ },
+ Executed: {
+ address: 'H160',
+ },
+ ExecutedFailed: {
+ address: 'H160'
+ }
}
},
/**
@@ -1234,15 +1242,20 @@
data: 'Bytes'
},
/**
- * Lookup116: pallet_ethereum::pallet::Event
+ * Lookup114: pallet_ethereum::pallet::Event
**/
PalletEthereumEvent: {
_enum: {
- Executed: '(H160,H160,H256,EvmCoreErrorExitReason)'
+ Executed: {
+ from: 'H160',
+ to: 'H160',
+ transactionHash: 'H256',
+ exitReason: 'EvmCoreErrorExitReason'
+ }
}
},
/**
- * Lookup117: evm_core::error::ExitReason
+ * Lookup115: evm_core::error::ExitReason
**/
EvmCoreErrorExitReason: {
_enum: {
@@ -1253,13 +1266,13 @@
}
},
/**
- * Lookup118: evm_core::error::ExitSucceed
+ * Lookup116: evm_core::error::ExitSucceed
**/
EvmCoreErrorExitSucceed: {
_enum: ['Stopped', 'Returned', 'Suicided']
},
/**
- * Lookup119: evm_core::error::ExitError
+ * Lookup117: evm_core::error::ExitError
**/
EvmCoreErrorExitError: {
_enum: {
@@ -1281,13 +1294,13 @@
}
},
/**
- * Lookup122: evm_core::error::ExitRevert
+ * Lookup120: evm_core::error::ExitRevert
**/
EvmCoreErrorExitRevert: {
_enum: ['Reverted']
},
/**
- * Lookup123: evm_core::error::ExitFatal
+ * Lookup121: evm_core::error::ExitFatal
**/
EvmCoreErrorExitFatal: {
_enum: {
@@ -1298,7 +1311,7 @@
}
},
/**
- * Lookup124: pallet_evm_contract_helpers::pallet::Event<T>
+ * Lookup122: pallet_evm_contract_helpers::pallet::Event<T>
**/
PalletEvmContractHelpersEvent: {
_enum: {
@@ -1308,19 +1321,19 @@
}
},
/**
- * Lookup125: pallet_maintenance::pallet::Event<T>
+ * Lookup123: pallet_maintenance::pallet::Event<T>
**/
PalletMaintenanceEvent: {
_enum: ['MaintenanceEnabled', 'MaintenanceDisabled']
},
/**
- * Lookup126: pallet_test_utils::pallet::Event<T>
+ * Lookup124: pallet_test_utils::pallet::Event<T>
**/
PalletTestUtilsEvent: {
_enum: ['ValueIsSet', 'ShouldRollback']
},
/**
- * Lookup127: frame_system::Phase
+ * Lookup125: frame_system::Phase
**/
FrameSystemPhase: {
_enum: {
@@ -1330,14 +1343,14 @@
}
},
/**
- * Lookup129: frame_system::LastRuntimeUpgradeInfo
+ * Lookup127: frame_system::LastRuntimeUpgradeInfo
**/
FrameSystemLastRuntimeUpgradeInfo: {
specVersion: 'Compact<u32>',
specName: 'Text'
},
/**
- * Lookup130: frame_system::pallet::Call<T>
+ * Lookup128: frame_system::pallet::Call<T>
**/
FrameSystemCall: {
_enum: {
@@ -1375,7 +1388,7 @@
}
},
/**
- * Lookup135: frame_system::limits::BlockWeights
+ * Lookup133: frame_system::limits::BlockWeights
**/
FrameSystemLimitsBlockWeights: {
baseBlock: 'Weight',
@@ -1383,7 +1396,7 @@
perClass: 'FrameSupportDispatchPerDispatchClassWeightsPerClass'
},
/**
- * Lookup136: frame_support::dispatch::PerDispatchClass<frame_system::limits::WeightsPerClass>
+ * Lookup134: frame_support::dispatch::PerDispatchClass<frame_system::limits::WeightsPerClass>
**/
FrameSupportDispatchPerDispatchClassWeightsPerClass: {
normal: 'FrameSystemLimitsWeightsPerClass',
@@ -1391,7 +1404,7 @@
mandatory: 'FrameSystemLimitsWeightsPerClass'
},
/**
- * Lookup137: frame_system::limits::WeightsPerClass
+ * Lookup135: frame_system::limits::WeightsPerClass
**/
FrameSystemLimitsWeightsPerClass: {
baseExtrinsic: 'Weight',
@@ -1400,13 +1413,13 @@
reserved: 'Option<Weight>'
},
/**
- * Lookup139: frame_system::limits::BlockLength
+ * Lookup137: frame_system::limits::BlockLength
**/
FrameSystemLimitsBlockLength: {
max: 'FrameSupportDispatchPerDispatchClassU32'
},
/**
- * Lookup140: frame_support::dispatch::PerDispatchClass<T>
+ * Lookup138: frame_support::dispatch::PerDispatchClass<T>
**/
FrameSupportDispatchPerDispatchClassU32: {
normal: 'u32',
@@ -1414,14 +1427,14 @@
mandatory: 'u32'
},
/**
- * Lookup141: sp_weights::RuntimeDbWeight
+ * Lookup139: sp_weights::RuntimeDbWeight
**/
SpWeightsRuntimeDbWeight: {
read: 'u64',
write: 'u64'
},
/**
- * Lookup142: sp_version::RuntimeVersion
+ * Lookup140: sp_version::RuntimeVersion
**/
SpVersionRuntimeVersion: {
specName: 'Text',
@@ -1434,13 +1447,13 @@
stateVersion: 'u8'
},
/**
- * Lookup147: frame_system::pallet::Error<T>
+ * Lookup145: frame_system::pallet::Error<T>
**/
FrameSystemError: {
_enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered']
},
/**
- * Lookup148: polkadot_primitives::v2::PersistedValidationData<primitive_types::H256, N>
+ * Lookup146: polkadot_primitives::v2::PersistedValidationData<primitive_types::H256, N>
**/
PolkadotPrimitivesV2PersistedValidationData: {
parentHead: 'Bytes',
@@ -1449,19 +1462,19 @@
maxPovSize: 'u32'
},
/**
- * Lookup151: polkadot_primitives::v2::UpgradeRestriction
+ * Lookup149: polkadot_primitives::v2::UpgradeRestriction
**/
PolkadotPrimitivesV2UpgradeRestriction: {
_enum: ['Present']
},
/**
- * Lookup152: sp_trie::storage_proof::StorageProof
+ * Lookup150: sp_trie::storage_proof::StorageProof
**/
SpTrieStorageProof: {
trieNodes: 'BTreeSet<Bytes>'
},
/**
- * Lookup154: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot
+ * Lookup152: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot
**/
CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot: {
dmqMqcHead: 'H256',
@@ -1470,7 +1483,7 @@
egressChannels: 'Vec<(u32,PolkadotPrimitivesV2AbridgedHrmpChannel)>'
},
/**
- * Lookup157: polkadot_primitives::v2::AbridgedHrmpChannel
+ * Lookup155: polkadot_primitives::v2::AbridgedHrmpChannel
**/
PolkadotPrimitivesV2AbridgedHrmpChannel: {
maxCapacity: 'u32',
@@ -1481,7 +1494,7 @@
mqcHead: 'Option<H256>'
},
/**
- * Lookup158: polkadot_primitives::v2::AbridgedHostConfiguration
+ * Lookup156: polkadot_primitives::v2::AbridgedHostConfiguration
**/
PolkadotPrimitivesV2AbridgedHostConfiguration: {
maxCodeSize: 'u32',
@@ -1495,14 +1508,14 @@
validationUpgradeDelay: 'u32'
},
/**
- * Lookup164: polkadot_core_primitives::OutboundHrmpMessage<polkadot_parachain::primitives::Id>
+ * Lookup162: polkadot_core_primitives::OutboundHrmpMessage<polkadot_parachain::primitives::Id>
**/
PolkadotCorePrimitivesOutboundHrmpMessage: {
recipient: 'u32',
data: 'Bytes'
},
/**
- * Lookup165: cumulus_pallet_parachain_system::pallet::Call<T>
+ * Lookup163: cumulus_pallet_parachain_system::pallet::Call<T>
**/
CumulusPalletParachainSystemCall: {
_enum: {
@@ -1521,7 +1534,7 @@
}
},
/**
- * Lookup166: cumulus_primitives_parachain_inherent::ParachainInherentData
+ * Lookup164: cumulus_primitives_parachain_inherent::ParachainInherentData
**/
CumulusPrimitivesParachainInherentParachainInherentData: {
validationData: 'PolkadotPrimitivesV2PersistedValidationData',
@@ -1530,27 +1543,27 @@
horizontalMessages: 'BTreeMap<u32, Vec<PolkadotCorePrimitivesInboundHrmpMessage>>'
},
/**
- * Lookup168: polkadot_core_primitives::InboundDownwardMessage<BlockNumber>
+ * Lookup166: polkadot_core_primitives::InboundDownwardMessage<BlockNumber>
**/
PolkadotCorePrimitivesInboundDownwardMessage: {
sentAt: 'u32',
msg: 'Bytes'
},
/**
- * Lookup171: polkadot_core_primitives::InboundHrmpMessage<BlockNumber>
+ * Lookup169: polkadot_core_primitives::InboundHrmpMessage<BlockNumber>
**/
PolkadotCorePrimitivesInboundHrmpMessage: {
sentAt: 'u32',
data: 'Bytes'
},
/**
- * Lookup174: cumulus_pallet_parachain_system::pallet::Error<T>
+ * Lookup172: cumulus_pallet_parachain_system::pallet::Error<T>
**/
CumulusPalletParachainSystemError: {
_enum: ['OverlappingUpgrades', 'ProhibitedByPolkadot', 'TooBig', 'ValidationDataNotAvailable', 'HostConfigurationNotAvailable', 'NotScheduled', 'NothingAuthorized', 'Unauthorized']
},
/**
- * Lookup176: pallet_balances::BalanceLock<Balance>
+ * Lookup174: pallet_balances::BalanceLock<Balance>
**/
PalletBalancesBalanceLock: {
id: '[u8;8]',
@@ -1558,26 +1571,26 @@
reasons: 'PalletBalancesReasons'
},
/**
- * Lookup177: pallet_balances::Reasons
+ * Lookup175: pallet_balances::Reasons
**/
PalletBalancesReasons: {
_enum: ['Fee', 'Misc', 'All']
},
/**
- * Lookup180: pallet_balances::ReserveData<ReserveIdentifier, Balance>
+ * Lookup178: pallet_balances::ReserveData<ReserveIdentifier, Balance>
**/
PalletBalancesReserveData: {
id: '[u8;16]',
amount: 'u128'
},
/**
- * Lookup182: pallet_balances::Releases
+ * Lookup180: pallet_balances::Releases
**/
PalletBalancesReleases: {
_enum: ['V1_0_0', 'V2_0_0']
},
/**
- * Lookup183: pallet_balances::pallet::Call<T, I>
+ * Lookup181: pallet_balances::pallet::Call<T, I>
**/
PalletBalancesCall: {
_enum: {
@@ -1610,13 +1623,13 @@
}
},
/**
- * Lookup186: pallet_balances::pallet::Error<T, I>
+ * Lookup184: pallet_balances::pallet::Error<T, I>
**/
PalletBalancesError: {
_enum: ['VestingBalance', 'LiquidityRestrictions', 'InsufficientBalance', 'ExistentialDeposit', 'KeepAlive', 'ExistingVestingSchedule', 'DeadAccount', 'TooManyReserves']
},
/**
- * Lookup188: pallet_timestamp::pallet::Call<T>
+ * Lookup186: pallet_timestamp::pallet::Call<T>
**/
PalletTimestampCall: {
_enum: {
@@ -1626,13 +1639,13 @@
}
},
/**
- * Lookup190: pallet_transaction_payment::Releases
+ * Lookup188: pallet_transaction_payment::Releases
**/
PalletTransactionPaymentReleases: {
_enum: ['V1Ancient', 'V2']
},
/**
- * Lookup191: pallet_treasury::Proposal<sp_core::crypto::AccountId32, Balance>
+ * Lookup189: pallet_treasury::Proposal<sp_core::crypto::AccountId32, Balance>
**/
PalletTreasuryProposal: {
proposer: 'AccountId32',
@@ -1641,7 +1654,7 @@
bond: 'u128'
},
/**
- * Lookup194: pallet_treasury::pallet::Call<T, I>
+ * Lookup192: pallet_treasury::pallet::Call<T, I>
**/
PalletTreasuryCall: {
_enum: {
@@ -1665,17 +1678,17 @@
}
},
/**
- * Lookup197: frame_support::PalletId
+ * Lookup195: frame_support::PalletId
**/
FrameSupportPalletId: '[u8;8]',
/**
- * Lookup198: pallet_treasury::pallet::Error<T, I>
+ * Lookup196: pallet_treasury::pallet::Error<T, I>
**/
PalletTreasuryError: {
_enum: ['InsufficientProposersBalance', 'InvalidIndex', 'TooManyApprovals', 'InsufficientPermission', 'ProposalNotApproved']
},
/**
- * Lookup199: pallet_sudo::pallet::Call<T>
+ * Lookup197: pallet_sudo::pallet::Call<T>
**/
PalletSudoCall: {
_enum: {
@@ -1699,7 +1712,7 @@
}
},
/**
- * Lookup201: orml_vesting::module::Call<T>
+ * Lookup199: orml_vesting::module::Call<T>
**/
OrmlVestingModuleCall: {
_enum: {
@@ -1718,7 +1731,7 @@
}
},
/**
- * Lookup203: orml_xtokens::module::Call<T>
+ * Lookup201: orml_xtokens::module::Call<T>
**/
OrmlXtokensModuleCall: {
_enum: {
@@ -1761,7 +1774,7 @@
}
},
/**
- * Lookup204: xcm::VersionedMultiAsset
+ * Lookup202: xcm::VersionedMultiAsset
**/
XcmVersionedMultiAsset: {
_enum: {
@@ -1770,7 +1783,7 @@
}
},
/**
- * Lookup207: orml_tokens::module::Call<T>
+ * Lookup205: orml_tokens::module::Call<T>
**/
OrmlTokensModuleCall: {
_enum: {
@@ -1804,7 +1817,7 @@
}
},
/**
- * Lookup208: cumulus_pallet_xcmp_queue::pallet::Call<T>
+ * Lookup206: cumulus_pallet_xcmp_queue::pallet::Call<T>
**/
CumulusPalletXcmpQueueCall: {
_enum: {
@@ -1853,7 +1866,7 @@
}
},
/**
- * Lookup209: pallet_xcm::pallet::Call<T>
+ * Lookup207: pallet_xcm::pallet::Call<T>
**/
PalletXcmCall: {
_enum: {
@@ -1907,7 +1920,7 @@
}
},
/**
- * Lookup210: xcm::VersionedXcm<RuntimeCall>
+ * Lookup208: xcm::VersionedXcm<RuntimeCall>
**/
XcmVersionedXcm: {
_enum: {
@@ -1917,7 +1930,7 @@
}
},
/**
- * Lookup211: xcm::v0::Xcm<RuntimeCall>
+ * Lookup209: xcm::v0::Xcm<RuntimeCall>
**/
XcmV0Xcm: {
_enum: {
@@ -1971,7 +1984,7 @@
}
},
/**
- * Lookup213: xcm::v0::order::Order<RuntimeCall>
+ * Lookup211: xcm::v0::order::Order<RuntimeCall>
**/
XcmV0Order: {
_enum: {
@@ -2014,7 +2027,7 @@
}
},
/**
- * Lookup215: xcm::v0::Response
+ * Lookup213: xcm::v0::Response
**/
XcmV0Response: {
_enum: {
@@ -2022,7 +2035,7 @@
}
},
/**
- * Lookup216: xcm::v1::Xcm<RuntimeCall>
+ * Lookup214: xcm::v1::Xcm<RuntimeCall>
**/
XcmV1Xcm: {
_enum: {
@@ -2081,7 +2094,7 @@
}
},
/**
- * Lookup218: xcm::v1::order::Order<RuntimeCall>
+ * Lookup216: xcm::v1::order::Order<RuntimeCall>
**/
XcmV1Order: {
_enum: {
@@ -2126,7 +2139,7 @@
}
},
/**
- * Lookup220: xcm::v1::Response
+ * Lookup218: xcm::v1::Response
**/
XcmV1Response: {
_enum: {
@@ -2135,11 +2148,11 @@
}
},
/**
- * Lookup234: cumulus_pallet_xcm::pallet::Call<T>
+ * Lookup232: cumulus_pallet_xcm::pallet::Call<T>
**/
CumulusPalletXcmCall: 'Null',
/**
- * Lookup235: cumulus_pallet_dmp_queue::pallet::Call<T>
+ * Lookup233: cumulus_pallet_dmp_queue::pallet::Call<T>
**/
CumulusPalletDmpQueueCall: {
_enum: {
@@ -2150,7 +2163,7 @@
}
},
/**
- * Lookup236: pallet_inflation::pallet::Call<T>
+ * Lookup234: pallet_inflation::pallet::Call<T>
**/
PalletInflationCall: {
_enum: {
@@ -2160,7 +2173,7 @@
}
},
/**
- * Lookup237: pallet_unique::Call<T>
+ * Lookup235: pallet_unique::Call<T>
**/
PalletUniqueCall: {
_enum: {
@@ -2292,7 +2305,7 @@
}
},
/**
- * Lookup242: up_data_structs::CollectionMode
+ * Lookup240: up_data_structs::CollectionMode
**/
UpDataStructsCollectionMode: {
_enum: {
@@ -2302,7 +2315,7 @@
}
},
/**
- * Lookup243: up_data_structs::CreateCollectionData<sp_core::crypto::AccountId32>
+ * Lookup241: up_data_structs::CreateCollectionData<sp_core::crypto::AccountId32>
**/
UpDataStructsCreateCollectionData: {
mode: 'UpDataStructsCollectionMode',
@@ -2317,13 +2330,13 @@
properties: 'Vec<UpDataStructsProperty>'
},
/**
- * Lookup245: up_data_structs::AccessMode
+ * Lookup243: up_data_structs::AccessMode
**/
UpDataStructsAccessMode: {
_enum: ['Normal', 'AllowList']
},
/**
- * Lookup247: up_data_structs::CollectionLimits
+ * Lookup245: up_data_structs::CollectionLimits
**/
UpDataStructsCollectionLimits: {
accountTokenOwnershipLimit: 'Option<u32>',
@@ -2337,7 +2350,7 @@
transfersEnabled: 'Option<bool>'
},
/**
- * Lookup249: up_data_structs::SponsoringRateLimit
+ * Lookup247: up_data_structs::SponsoringRateLimit
**/
UpDataStructsSponsoringRateLimit: {
_enum: {
@@ -2346,7 +2359,7 @@
}
},
/**
- * Lookup252: up_data_structs::CollectionPermissions
+ * Lookup250: up_data_structs::CollectionPermissions
**/
UpDataStructsCollectionPermissions: {
access: 'Option<UpDataStructsAccessMode>',
@@ -2354,7 +2367,7 @@
nesting: 'Option<UpDataStructsNestingPermissions>'
},
/**
- * Lookup254: up_data_structs::NestingPermissions
+ * Lookup252: up_data_structs::NestingPermissions
**/
UpDataStructsNestingPermissions: {
tokenOwner: 'bool',
@@ -2362,18 +2375,18 @@
restricted: 'Option<UpDataStructsOwnerRestrictedSet>'
},
/**
- * Lookup256: up_data_structs::OwnerRestrictedSet
+ * Lookup254: up_data_structs::OwnerRestrictedSet
**/
UpDataStructsOwnerRestrictedSet: 'BTreeSet<u32>',
/**
- * Lookup261: up_data_structs::PropertyKeyPermission
+ * Lookup259: up_data_structs::PropertyKeyPermission
**/
UpDataStructsPropertyKeyPermission: {
key: 'Bytes',
permission: 'UpDataStructsPropertyPermission'
},
/**
- * Lookup262: up_data_structs::PropertyPermission
+ * Lookup260: up_data_structs::PropertyPermission
**/
UpDataStructsPropertyPermission: {
mutable: 'bool',
@@ -2381,14 +2394,14 @@
tokenOwner: 'bool'
},
/**
- * Lookup265: up_data_structs::Property
+ * Lookup263: up_data_structs::Property
**/
UpDataStructsProperty: {
key: 'Bytes',
value: 'Bytes'
},
/**
- * Lookup268: up_data_structs::CreateItemData
+ * Lookup266: up_data_structs::CreateItemData
**/
UpDataStructsCreateItemData: {
_enum: {
@@ -2398,26 +2411,26 @@
}
},
/**
- * Lookup269: up_data_structs::CreateNftData
+ * Lookup267: up_data_structs::CreateNftData
**/
UpDataStructsCreateNftData: {
properties: 'Vec<UpDataStructsProperty>'
},
/**
- * Lookup270: up_data_structs::CreateFungibleData
+ * Lookup268: up_data_structs::CreateFungibleData
**/
UpDataStructsCreateFungibleData: {
value: 'u128'
},
/**
- * Lookup271: up_data_structs::CreateReFungibleData
+ * Lookup269: up_data_structs::CreateReFungibleData
**/
UpDataStructsCreateReFungibleData: {
pieces: 'u128',
properties: 'Vec<UpDataStructsProperty>'
},
/**
- * Lookup274: up_data_structs::CreateItemExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+ * Lookup272: up_data_structs::CreateItemExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
**/
UpDataStructsCreateItemExData: {
_enum: {
@@ -2428,14 +2441,14 @@
}
},
/**
- * Lookup276: up_data_structs::CreateNftExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+ * Lookup274: up_data_structs::CreateNftExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
**/
UpDataStructsCreateNftExData: {
properties: 'Vec<UpDataStructsProperty>',
owner: 'PalletEvmAccountBasicCrossAccountIdRepr'
},
/**
- * Lookup283: up_data_structs::CreateRefungibleExSingleOwner<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+ * Lookup281: up_data_structs::CreateRefungibleExSingleOwner<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
**/
UpDataStructsCreateRefungibleExSingleOwner: {
user: 'PalletEvmAccountBasicCrossAccountIdRepr',
@@ -2443,14 +2456,14 @@
properties: 'Vec<UpDataStructsProperty>'
},
/**
- * Lookup285: up_data_structs::CreateRefungibleExMultipleOwners<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+ * Lookup283: up_data_structs::CreateRefungibleExMultipleOwners<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
**/
UpDataStructsCreateRefungibleExMultipleOwners: {
users: 'BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>',
properties: 'Vec<UpDataStructsProperty>'
},
/**
- * Lookup286: pallet_unique_scheduler::pallet::Call<T>
+ * Lookup284: pallet_unique_scheduler::pallet::Call<T>
**/
PalletUniqueSchedulerCall: {
_enum: {
@@ -2478,7 +2491,7 @@
}
},
/**
- * Lookup289: frame_support::traits::schedule::MaybeHashed<opal_runtime::RuntimeCall, primitive_types::H256>
+ * Lookup287: frame_support::traits::schedule::MaybeHashed<opal_runtime::RuntimeCall, primitive_types::H256>
**/
FrameSupportScheduleMaybeHashed: {
_enum: {
@@ -2487,7 +2500,7 @@
}
},
/**
- * Lookup290: pallet_configuration::pallet::Call<T>
+ * Lookup288: pallet_configuration::pallet::Call<T>
**/
PalletConfigurationCall: {
_enum: {
@@ -2500,15 +2513,15 @@
}
},
/**
- * Lookup292: pallet_template_transaction_payment::Call<T>
+ * Lookup290: pallet_template_transaction_payment::Call<T>
**/
PalletTemplateTransactionPaymentCall: 'Null',
/**
- * Lookup293: pallet_structure::pallet::Call<T>
+ * Lookup291: pallet_structure::pallet::Call<T>
**/
PalletStructureCall: 'Null',
/**
- * Lookup294: pallet_rmrk_core::pallet::Call<T>
+ * Lookup292: pallet_rmrk_core::pallet::Call<T>
**/
PalletRmrkCoreCall: {
_enum: {
@@ -2599,7 +2612,7 @@
}
},
/**
- * Lookup300: rmrk_traits::resource::ResourceTypes<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup298: rmrk_traits::resource::ResourceTypes<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsResourceResourceTypes: {
_enum: {
@@ -2609,7 +2622,7 @@
}
},
/**
- * Lookup302: rmrk_traits::resource::BasicResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup300: rmrk_traits::resource::BasicResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsResourceBasicResource: {
src: 'Option<Bytes>',
@@ -2618,7 +2631,7 @@
thumb: 'Option<Bytes>'
},
/**
- * Lookup304: rmrk_traits::resource::ComposableResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup302: rmrk_traits::resource::ComposableResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsResourceComposableResource: {
parts: 'Vec<u32>',
@@ -2629,7 +2642,7 @@
thumb: 'Option<Bytes>'
},
/**
- * Lookup305: rmrk_traits::resource::SlotResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup303: rmrk_traits::resource::SlotResource<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsResourceSlotResource: {
base: 'u32',
@@ -2640,7 +2653,7 @@
thumb: 'Option<Bytes>'
},
/**
- * Lookup308: pallet_rmrk_equip::pallet::Call<T>
+ * Lookup306: pallet_rmrk_equip::pallet::Call<T>
**/
PalletRmrkEquipCall: {
_enum: {
@@ -2661,7 +2674,7 @@
}
},
/**
- * Lookup311: rmrk_traits::part::PartType<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup309: rmrk_traits::part::PartType<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsPartPartType: {
_enum: {
@@ -2670,7 +2683,7 @@
}
},
/**
- * Lookup313: rmrk_traits::part::FixedPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup311: rmrk_traits::part::FixedPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsPartFixedPart: {
id: 'u32',
@@ -2678,7 +2691,7 @@
src: 'Bytes'
},
/**
- * Lookup314: rmrk_traits::part::SlotPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup312: rmrk_traits::part::SlotPart<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsPartSlotPart: {
id: 'u32',
@@ -2687,7 +2700,7 @@
z: 'u32'
},
/**
- * Lookup315: rmrk_traits::part::EquippableList<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup313: rmrk_traits::part::EquippableList<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsPartEquippableList: {
_enum: {
@@ -2697,7 +2710,7 @@
}
},
/**
- * Lookup317: rmrk_traits::theme::Theme<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>, S>>
+ * Lookup315: rmrk_traits::theme::Theme<sp_core::bounded::bounded_vec::BoundedVec<T, S>, sp_core::bounded::bounded_vec::BoundedVec<rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>, S>>
**/
RmrkTraitsTheme: {
name: 'Bytes',
@@ -2705,14 +2718,14 @@
inherit: 'bool'
},
/**
- * Lookup319: rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
+ * Lookup317: rmrk_traits::theme::ThemeProperty<sp_core::bounded::bounded_vec::BoundedVec<T, S>>
**/
RmrkTraitsThemeThemeProperty: {
key: 'Bytes',
value: 'Bytes'
},
/**
- * Lookup321: pallet_app_promotion::pallet::Call<T>
+ * Lookup319: pallet_app_promotion::pallet::Call<T>
**/
PalletAppPromotionCall: {
_enum: {
@@ -2741,7 +2754,7 @@
}
},
/**
- * Lookup322: pallet_foreign_assets::module::Call<T>
+ * Lookup320: pallet_foreign_assets::module::Call<T>
**/
PalletForeignAssetsModuleCall: {
_enum: {
@@ -2758,7 +2771,7 @@
}
},
/**
- * Lookup323: pallet_evm::pallet::Call<T>
+ * Lookup321: pallet_evm::pallet::Call<T>
**/
PalletEvmCall: {
_enum: {
@@ -3458,7 +3471,7 @@
* Lookup450: pallet_evm::pallet::Error<T>
**/
PalletEvmError: {
- _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce']
+ _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce', 'GasLimitTooLow', 'GasLimitTooHigh', 'Undefined', 'Reentrancy']
},
/**
* Lookup453: fp_rpc::TransactionStatus
tests/src/interfaces/types-lookup.tsdiffbeforeafterboth--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1371,20 +1371,26 @@
/** @name PalletEvmEvent (111) */
interface PalletEvmEvent extends Enum {
readonly isLog: boolean;
- readonly asLog: EthereumLog;
+ readonly asLog: {
+ readonly log: EthereumLog;
+ } & Struct;
readonly isCreated: boolean;
- readonly asCreated: H160;
+ readonly asCreated: {
+ readonly address: H160;
+ } & Struct;
readonly isCreatedFailed: boolean;
- readonly asCreatedFailed: H160;
+ readonly asCreatedFailed: {
+ readonly address: H160;
+ } & Struct;
readonly isExecuted: boolean;
- readonly asExecuted: H160;
+ readonly asExecuted: {
+ readonly address: H160;
+ } & Struct;
readonly isExecutedFailed: boolean;
- readonly asExecutedFailed: H160;
- readonly isBalanceDeposit: boolean;
- readonly asBalanceDeposit: ITuple<[AccountId32, H160, U256]>;
- readonly isBalanceWithdraw: boolean;
- readonly asBalanceWithdraw: ITuple<[AccountId32, H160, U256]>;
- readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
+ readonly asExecutedFailed: {
+ readonly address: H160;
+ } & Struct;
+ readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed';
}
/** @name EthereumLog (112) */
@@ -1394,14 +1400,19 @@
readonly data: Bytes;
}
- /** @name PalletEthereumEvent (116) */
+ /** @name PalletEthereumEvent (114) */
interface PalletEthereumEvent extends Enum {
readonly isExecuted: boolean;
- readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
+ readonly asExecuted: {
+ readonly from: H160;
+ readonly to: H160;
+ readonly transactionHash: H256;
+ readonly exitReason: EvmCoreErrorExitReason;
+ } & Struct;
readonly type: 'Executed';
}
- /** @name EvmCoreErrorExitReason (117) */
+ /** @name EvmCoreErrorExitReason (115) */
interface EvmCoreErrorExitReason extends Enum {
readonly isSucceed: boolean;
readonly asSucceed: EvmCoreErrorExitSucceed;
@@ -1414,7 +1425,7 @@
readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';
}
- /** @name EvmCoreErrorExitSucceed (118) */
+ /** @name EvmCoreErrorExitSucceed (116) */
interface EvmCoreErrorExitSucceed extends Enum {
readonly isStopped: boolean;
readonly isReturned: boolean;
@@ -1422,7 +1433,7 @@
readonly type: 'Stopped' | 'Returned' | 'Suicided';
}
- /** @name EvmCoreErrorExitError (119) */
+ /** @name EvmCoreErrorExitError (117) */
interface EvmCoreErrorExitError extends Enum {
readonly isStackUnderflow: boolean;
readonly isStackOverflow: boolean;
@@ -1443,13 +1454,13 @@
readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other' | 'InvalidCode';
}
- /** @name EvmCoreErrorExitRevert (122) */
+ /** @name EvmCoreErrorExitRevert (120) */
interface EvmCoreErrorExitRevert extends Enum {
readonly isReverted: boolean;
readonly type: 'Reverted';
}
- /** @name EvmCoreErrorExitFatal (123) */
+ /** @name EvmCoreErrorExitFatal (121) */
interface EvmCoreErrorExitFatal extends Enum {
readonly isNotSupported: boolean;
readonly isUnhandledInterrupt: boolean;
@@ -1460,7 +1471,7 @@
readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';
}
- /** @name PalletEvmContractHelpersEvent (124) */
+ /** @name PalletEvmContractHelpersEvent (122) */
interface PalletEvmContractHelpersEvent extends Enum {
readonly isContractSponsorSet: boolean;
readonly asContractSponsorSet: ITuple<[H160, AccountId32]>;
@@ -1471,21 +1482,21 @@
readonly type: 'ContractSponsorSet' | 'ContractSponsorshipConfirmed' | 'ContractSponsorRemoved';
}
- /** @name PalletMaintenanceEvent (125) */
+ /** @name PalletMaintenanceEvent (123) */
interface PalletMaintenanceEvent extends Enum {
readonly isMaintenanceEnabled: boolean;
readonly isMaintenanceDisabled: boolean;
readonly type: 'MaintenanceEnabled' | 'MaintenanceDisabled';
}
- /** @name PalletTestUtilsEvent (126) */
+ /** @name PalletTestUtilsEvent (124) */
interface PalletTestUtilsEvent extends Enum {
readonly isValueIsSet: boolean;
readonly isShouldRollback: boolean;
readonly type: 'ValueIsSet' | 'ShouldRollback';
}
- /** @name FrameSystemPhase (127) */
+ /** @name FrameSystemPhase (125) */
interface FrameSystemPhase extends Enum {
readonly isApplyExtrinsic: boolean;
readonly asApplyExtrinsic: u32;
@@ -1494,13 +1505,13 @@
readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';
}
- /** @name FrameSystemLastRuntimeUpgradeInfo (129) */
+ /** @name FrameSystemLastRuntimeUpgradeInfo (127) */
interface FrameSystemLastRuntimeUpgradeInfo extends Struct {
readonly specVersion: Compact<u32>;
readonly specName: Text;
}
- /** @name FrameSystemCall (130) */
+ /** @name FrameSystemCall (128) */
interface FrameSystemCall extends Enum {
readonly isFillBlock: boolean;
readonly asFillBlock: {
@@ -1542,21 +1553,21 @@
readonly type: 'FillBlock' | 'Remark' | 'SetHeapPages' | 'SetCode' | 'SetCodeWithoutChecks' | 'SetStorage' | 'KillStorage' | 'KillPrefix' | 'RemarkWithEvent';
}
- /** @name FrameSystemLimitsBlockWeights (135) */
+ /** @name FrameSystemLimitsBlockWeights (133) */
interface FrameSystemLimitsBlockWeights extends Struct {
readonly baseBlock: Weight;
readonly maxBlock: Weight;
readonly perClass: FrameSupportDispatchPerDispatchClassWeightsPerClass;
}
- /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (136) */
+ /** @name FrameSupportDispatchPerDispatchClassWeightsPerClass (134) */
interface FrameSupportDispatchPerDispatchClassWeightsPerClass extends Struct {
readonly normal: FrameSystemLimitsWeightsPerClass;
readonly operational: FrameSystemLimitsWeightsPerClass;
readonly mandatory: FrameSystemLimitsWeightsPerClass;
}
- /** @name FrameSystemLimitsWeightsPerClass (137) */
+ /** @name FrameSystemLimitsWeightsPerClass (135) */
interface FrameSystemLimitsWeightsPerClass extends Struct {
readonly baseExtrinsic: Weight;
readonly maxExtrinsic: Option<Weight>;
@@ -1564,25 +1575,25 @@
readonly reserved: Option<Weight>;
}
- /** @name FrameSystemLimitsBlockLength (139) */
+ /** @name FrameSystemLimitsBlockLength (137) */
interface FrameSystemLimitsBlockLength extends Struct {
readonly max: FrameSupportDispatchPerDispatchClassU32;
}
- /** @name FrameSupportDispatchPerDispatchClassU32 (140) */
+ /** @name FrameSupportDispatchPerDispatchClassU32 (138) */
interface FrameSupportDispatchPerDispatchClassU32 extends Struct {
readonly normal: u32;
readonly operational: u32;
readonly mandatory: u32;
}
- /** @name SpWeightsRuntimeDbWeight (141) */
+ /** @name SpWeightsRuntimeDbWeight (139) */
interface SpWeightsRuntimeDbWeight extends Struct {
readonly read: u64;
readonly write: u64;
}
- /** @name SpVersionRuntimeVersion (142) */
+ /** @name SpVersionRuntimeVersion (140) */
interface SpVersionRuntimeVersion extends Struct {
readonly specName: Text;
readonly implName: Text;
@@ -1594,7 +1605,7 @@
readonly stateVersion: u8;
}
- /** @name FrameSystemError (147) */
+ /** @name FrameSystemError (145) */
interface FrameSystemError extends Enum {
readonly isInvalidSpecName: boolean;
readonly isSpecVersionNeedsToIncrease: boolean;
@@ -1605,7 +1616,7 @@
readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';
}
- /** @name PolkadotPrimitivesV2PersistedValidationData (148) */
+ /** @name PolkadotPrimitivesV2PersistedValidationData (146) */
interface PolkadotPrimitivesV2PersistedValidationData extends Struct {
readonly parentHead: Bytes;
readonly relayParentNumber: u32;
@@ -1613,18 +1624,18 @@
readonly maxPovSize: u32;
}
- /** @name PolkadotPrimitivesV2UpgradeRestriction (151) */
+ /** @name PolkadotPrimitivesV2UpgradeRestriction (149) */
interface PolkadotPrimitivesV2UpgradeRestriction extends Enum {
readonly isPresent: boolean;
readonly type: 'Present';
}
- /** @name SpTrieStorageProof (152) */
+ /** @name SpTrieStorageProof (150) */
interface SpTrieStorageProof extends Struct {
readonly trieNodes: BTreeSet<Bytes>;
}
- /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (154) */
+ /** @name CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot (152) */
interface CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot extends Struct {
readonly dmqMqcHead: H256;
readonly relayDispatchQueueSize: ITuple<[u32, u32]>;
@@ -1632,7 +1643,7 @@
readonly egressChannels: Vec<ITuple<[u32, PolkadotPrimitivesV2AbridgedHrmpChannel]>>;
}
- /** @name PolkadotPrimitivesV2AbridgedHrmpChannel (157) */
+ /** @name PolkadotPrimitivesV2AbridgedHrmpChannel (155) */
interface PolkadotPrimitivesV2AbridgedHrmpChannel extends Struct {
readonly maxCapacity: u32;
readonly maxTotalSize: u32;
@@ -1642,7 +1653,7 @@
readonly mqcHead: Option<H256>;
}
- /** @name PolkadotPrimitivesV2AbridgedHostConfiguration (158) */
+ /** @name PolkadotPrimitivesV2AbridgedHostConfiguration (156) */
interface PolkadotPrimitivesV2AbridgedHostConfiguration extends Struct {
readonly maxCodeSize: u32;
readonly maxHeadDataSize: u32;
@@ -1655,13 +1666,13 @@
readonly validationUpgradeDelay: u32;
}
- /** @name PolkadotCorePrimitivesOutboundHrmpMessage (164) */
+ /** @name PolkadotCorePrimitivesOutboundHrmpMessage (162) */
interface PolkadotCorePrimitivesOutboundHrmpMessage extends Struct {
readonly recipient: u32;
readonly data: Bytes;
}
- /** @name CumulusPalletParachainSystemCall (165) */
+ /** @name CumulusPalletParachainSystemCall (163) */
interface CumulusPalletParachainSystemCall extends Enum {
readonly isSetValidationData: boolean;
readonly asSetValidationData: {
@@ -1682,7 +1693,7 @@
readonly type: 'SetValidationData' | 'SudoSendUpwardMessage' | 'AuthorizeUpgrade' | 'EnactAuthorizedUpgrade';
}
- /** @name CumulusPrimitivesParachainInherentParachainInherentData (166) */
+ /** @name CumulusPrimitivesParachainInherentParachainInherentData (164) */
interface CumulusPrimitivesParachainInherentParachainInherentData extends Struct {
readonly validationData: PolkadotPrimitivesV2PersistedValidationData;
readonly relayChainState: SpTrieStorageProof;
@@ -1690,19 +1701,19 @@
readonly horizontalMessages: BTreeMap<u32, Vec<PolkadotCorePrimitivesInboundHrmpMessage>>;
}
- /** @name PolkadotCorePrimitivesInboundDownwardMessage (168) */
+ /** @name PolkadotCorePrimitivesInboundDownwardMessage (166) */
interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {
readonly sentAt: u32;
readonly msg: Bytes;
}
- /** @name PolkadotCorePrimitivesInboundHrmpMessage (171) */
+ /** @name PolkadotCorePrimitivesInboundHrmpMessage (169) */
interface PolkadotCorePrimitivesInboundHrmpMessage extends Struct {
readonly sentAt: u32;
readonly data: Bytes;
}
- /** @name CumulusPalletParachainSystemError (174) */
+ /** @name CumulusPalletParachainSystemError (172) */
interface CumulusPalletParachainSystemError extends Enum {
readonly isOverlappingUpgrades: boolean;
readonly isProhibitedByPolkadot: boolean;
@@ -1715,14 +1726,14 @@
readonly type: 'OverlappingUpgrades' | 'ProhibitedByPolkadot' | 'TooBig' | 'ValidationDataNotAvailable' | 'HostConfigurationNotAvailable' | 'NotScheduled' | 'NothingAuthorized' | 'Unauthorized';
}
- /** @name PalletBalancesBalanceLock (176) */
+ /** @name PalletBalancesBalanceLock (174) */
interface PalletBalancesBalanceLock extends Struct {
readonly id: U8aFixed;
readonly amount: u128;
readonly reasons: PalletBalancesReasons;
}
- /** @name PalletBalancesReasons (177) */
+ /** @name PalletBalancesReasons (175) */
interface PalletBalancesReasons extends Enum {
readonly isFee: boolean;
readonly isMisc: boolean;
@@ -1730,20 +1741,20 @@
readonly type: 'Fee' | 'Misc' | 'All';
}
- /** @name PalletBalancesReserveData (180) */
+ /** @name PalletBalancesReserveData (178) */
interface PalletBalancesReserveData extends Struct {
readonly id: U8aFixed;
readonly amount: u128;
}
- /** @name PalletBalancesReleases (182) */
+ /** @name PalletBalancesReleases (180) */
interface PalletBalancesReleases extends Enum {
readonly isV100: boolean;
readonly isV200: boolean;
readonly type: 'V100' | 'V200';
}
- /** @name PalletBalancesCall (183) */
+ /** @name PalletBalancesCall (181) */
interface PalletBalancesCall extends Enum {
readonly isTransfer: boolean;
readonly asTransfer: {
@@ -1780,7 +1791,7 @@
readonly type: 'Transfer' | 'SetBalance' | 'ForceTransfer' | 'TransferKeepAlive' | 'TransferAll' | 'ForceUnreserve';
}
- /** @name PalletBalancesError (186) */
+ /** @name PalletBalancesError (184) */
interface PalletBalancesError extends Enum {
readonly isVestingBalance: boolean;
readonly isLiquidityRestrictions: boolean;
@@ -1793,7 +1804,7 @@
readonly type: 'VestingBalance' | 'LiquidityRestrictions' | 'InsufficientBalance' | 'ExistentialDeposit' | 'KeepAlive' | 'ExistingVestingSchedule' | 'DeadAccount' | 'TooManyReserves';
}
- /** @name PalletTimestampCall (188) */
+ /** @name PalletTimestampCall (186) */
interface PalletTimestampCall extends Enum {
readonly isSet: boolean;
readonly asSet: {
@@ -1802,14 +1813,14 @@
readonly type: 'Set';
}
- /** @name PalletTransactionPaymentReleases (190) */
+ /** @name PalletTransactionPaymentReleases (188) */
interface PalletTransactionPaymentReleases extends Enum {
readonly isV1Ancient: boolean;
readonly isV2: boolean;
readonly type: 'V1Ancient' | 'V2';
}
- /** @name PalletTreasuryProposal (191) */
+ /** @name PalletTreasuryProposal (189) */
interface PalletTreasuryProposal extends Struct {
readonly proposer: AccountId32;
readonly value: u128;
@@ -1817,7 +1828,7 @@
readonly bond: u128;
}
- /** @name PalletTreasuryCall (194) */
+ /** @name PalletTreasuryCall (192) */
interface PalletTreasuryCall extends Enum {
readonly isProposeSpend: boolean;
readonly asProposeSpend: {
@@ -1844,10 +1855,10 @@
readonly type: 'ProposeSpend' | 'RejectProposal' | 'ApproveProposal' | 'Spend' | 'RemoveApproval';
}
- /** @name FrameSupportPalletId (197) */
+ /** @name FrameSupportPalletId (195) */
interface FrameSupportPalletId extends U8aFixed {}
- /** @name PalletTreasuryError (198) */
+ /** @name PalletTreasuryError (196) */
interface PalletTreasuryError extends Enum {
readonly isInsufficientProposersBalance: boolean;
readonly isInvalidIndex: boolean;
@@ -1857,7 +1868,7 @@
readonly type: 'InsufficientProposersBalance' | 'InvalidIndex' | 'TooManyApprovals' | 'InsufficientPermission' | 'ProposalNotApproved';
}
- /** @name PalletSudoCall (199) */
+ /** @name PalletSudoCall (197) */
interface PalletSudoCall extends Enum {
readonly isSudo: boolean;
readonly asSudo: {
@@ -1880,7 +1891,7 @@
readonly type: 'Sudo' | 'SudoUncheckedWeight' | 'SetKey' | 'SudoAs';
}
- /** @name OrmlVestingModuleCall (201) */
+ /** @name OrmlVestingModuleCall (199) */
interface OrmlVestingModuleCall extends Enum {
readonly isClaim: boolean;
readonly isVestedTransfer: boolean;
@@ -1900,7 +1911,7 @@
readonly type: 'Claim' | 'VestedTransfer' | 'UpdateVestingSchedules' | 'ClaimFor';
}
- /** @name OrmlXtokensModuleCall (203) */
+ /** @name OrmlXtokensModuleCall (201) */
interface OrmlXtokensModuleCall extends Enum {
readonly isTransfer: boolean;
readonly asTransfer: {
@@ -1947,7 +1958,7 @@
readonly type: 'Transfer' | 'TransferMultiasset' | 'TransferWithFee' | 'TransferMultiassetWithFee' | 'TransferMulticurrencies' | 'TransferMultiassets';
}
- /** @name XcmVersionedMultiAsset (204) */
+ /** @name XcmVersionedMultiAsset (202) */
interface XcmVersionedMultiAsset extends Enum {
readonly isV0: boolean;
readonly asV0: XcmV0MultiAsset;
@@ -1956,7 +1967,7 @@
readonly type: 'V0' | 'V1';
}
- /** @name OrmlTokensModuleCall (207) */
+ /** @name OrmlTokensModuleCall (205) */
interface OrmlTokensModuleCall extends Enum {
readonly isTransfer: boolean;
readonly asTransfer: {
@@ -1993,7 +2004,7 @@
readonly type: 'Transfer' | 'TransferAll' | 'TransferKeepAlive' | 'ForceTransfer' | 'SetBalance';
}
- /** @name CumulusPalletXcmpQueueCall (208) */
+ /** @name CumulusPalletXcmpQueueCall (206) */
interface CumulusPalletXcmpQueueCall extends Enum {
readonly isServiceOverweight: boolean;
readonly asServiceOverweight: {
@@ -2029,7 +2040,7 @@
readonly type: 'ServiceOverweight' | 'SuspendXcmExecution' | 'ResumeXcmExecution' | 'UpdateSuspendThreshold' | 'UpdateDropThreshold' | 'UpdateResumeThreshold' | 'UpdateThresholdWeight' | 'UpdateWeightRestrictDecay' | 'UpdateXcmpMaxIndividualWeight';
}
- /** @name PalletXcmCall (209) */
+ /** @name PalletXcmCall (207) */
interface PalletXcmCall extends Enum {
readonly isSend: boolean;
readonly asSend: {
@@ -2091,7 +2102,7 @@
readonly type: 'Send' | 'TeleportAssets' | 'ReserveTransferAssets' | 'Execute' | 'ForceXcmVersion' | 'ForceDefaultXcmVersion' | 'ForceSubscribeVersionNotify' | 'ForceUnsubscribeVersionNotify' | 'LimitedReserveTransferAssets' | 'LimitedTeleportAssets';
}
- /** @name XcmVersionedXcm (210) */
+ /** @name XcmVersionedXcm (208) */
interface XcmVersionedXcm extends Enum {
readonly isV0: boolean;
readonly asV0: XcmV0Xcm;
@@ -2102,7 +2113,7 @@
readonly type: 'V0' | 'V1' | 'V2';
}
- /** @name XcmV0Xcm (211) */
+ /** @name XcmV0Xcm (209) */
interface XcmV0Xcm extends Enum {
readonly isWithdrawAsset: boolean;
readonly asWithdrawAsset: {
@@ -2165,7 +2176,7 @@
readonly type: 'WithdrawAsset' | 'ReserveAssetDeposit' | 'TeleportAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom';
}
- /** @name XcmV0Order (213) */
+ /** @name XcmV0Order (211) */
interface XcmV0Order extends Enum {
readonly isNull: boolean;
readonly isDepositAsset: boolean;
@@ -2213,14 +2224,14 @@
readonly type: 'Null' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';
}
- /** @name XcmV0Response (215) */
+ /** @name XcmV0Response (213) */
interface XcmV0Response extends Enum {
readonly isAssets: boolean;
readonly asAssets: Vec<XcmV0MultiAsset>;
readonly type: 'Assets';
}
- /** @name XcmV1Xcm (216) */
+ /** @name XcmV1Xcm (214) */
interface XcmV1Xcm extends Enum {
readonly isWithdrawAsset: boolean;
readonly asWithdrawAsset: {
@@ -2289,7 +2300,7 @@
readonly type: 'WithdrawAsset' | 'ReserveAssetDeposited' | 'ReceiveTeleportedAsset' | 'QueryResponse' | 'TransferAsset' | 'TransferReserveAsset' | 'Transact' | 'HrmpNewChannelOpenRequest' | 'HrmpChannelAccepted' | 'HrmpChannelClosing' | 'RelayedFrom' | 'SubscribeVersion' | 'UnsubscribeVersion';
}
- /** @name XcmV1Order (218) */
+ /** @name XcmV1Order (216) */
interface XcmV1Order extends Enum {
readonly isNoop: boolean;
readonly isDepositAsset: boolean;
@@ -2339,7 +2350,7 @@
readonly type: 'Noop' | 'DepositAsset' | 'DepositReserveAsset' | 'ExchangeAsset' | 'InitiateReserveWithdraw' | 'InitiateTeleport' | 'QueryHolding' | 'BuyExecution';
}
- /** @name XcmV1Response (220) */
+ /** @name XcmV1Response (218) */
interface XcmV1Response extends Enum {
readonly isAssets: boolean;
readonly asAssets: XcmV1MultiassetMultiAssets;
@@ -2348,10 +2359,10 @@
readonly type: 'Assets' | 'Version';
}
- /** @name CumulusPalletXcmCall (234) */
+ /** @name CumulusPalletXcmCall (232) */
type CumulusPalletXcmCall = Null;
- /** @name CumulusPalletDmpQueueCall (235) */
+ /** @name CumulusPalletDmpQueueCall (233) */
interface CumulusPalletDmpQueueCall extends Enum {
readonly isServiceOverweight: boolean;
readonly asServiceOverweight: {
@@ -2361,7 +2372,7 @@
readonly type: 'ServiceOverweight';
}
- /** @name PalletInflationCall (236) */
+ /** @name PalletInflationCall (234) */
interface PalletInflationCall extends Enum {
readonly isStartInflation: boolean;
readonly asStartInflation: {
@@ -2370,7 +2381,7 @@
readonly type: 'StartInflation';
}
- /** @name PalletUniqueCall (237) */
+ /** @name PalletUniqueCall (235) */
interface PalletUniqueCall extends Enum {
readonly isCreateCollection: boolean;
readonly asCreateCollection: {
@@ -2528,7 +2539,7 @@
readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetTokenPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetCollectionLimits' | 'SetCollectionPermissions' | 'Repartition';
}
- /** @name UpDataStructsCollectionMode (242) */
+ /** @name UpDataStructsCollectionMode (240) */
interface UpDataStructsCollectionMode extends Enum {
readonly isNft: boolean;
readonly isFungible: boolean;
@@ -2537,7 +2548,7 @@
readonly type: 'Nft' | 'Fungible' | 'ReFungible';
}
- /** @name UpDataStructsCreateCollectionData (243) */
+ /** @name UpDataStructsCreateCollectionData (241) */
interface UpDataStructsCreateCollectionData extends Struct {
readonly mode: UpDataStructsCollectionMode;
readonly access: Option<UpDataStructsAccessMode>;
@@ -2551,14 +2562,14 @@
readonly properties: Vec<UpDataStructsProperty>;
}
- /** @name UpDataStructsAccessMode (245) */
+ /** @name UpDataStructsAccessMode (243) */
interface UpDataStructsAccessMode extends Enum {
readonly isNormal: boolean;
readonly isAllowList: boolean;
readonly type: 'Normal' | 'AllowList';
}
- /** @name UpDataStructsCollectionLimits (247) */
+ /** @name UpDataStructsCollectionLimits (245) */
interface UpDataStructsCollectionLimits extends Struct {
readonly accountTokenOwnershipLimit: Option<u32>;
readonly sponsoredDataSize: Option<u32>;
@@ -2571,7 +2582,7 @@
readonly transfersEnabled: Option<bool>;
}
- /** @name UpDataStructsSponsoringRateLimit (249) */
+ /** @name UpDataStructsSponsoringRateLimit (247) */
interface UpDataStructsSponsoringRateLimit extends Enum {
readonly isSponsoringDisabled: boolean;
readonly isBlocks: boolean;
@@ -2579,43 +2590,43 @@
readonly type: 'SponsoringDisabled' | 'Blocks';
}
- /** @name UpDataStructsCollectionPermissions (252) */
+ /** @name UpDataStructsCollectionPermissions (250) */
interface UpDataStructsCollectionPermissions extends Struct {
readonly access: Option<UpDataStructsAccessMode>;
readonly mintMode: Option<bool>;
readonly nesting: Option<UpDataStructsNestingPermissions>;
}
- /** @name UpDataStructsNestingPermissions (254) */
+ /** @name UpDataStructsNestingPermissions (252) */
interface UpDataStructsNestingPermissions extends Struct {
readonly tokenOwner: bool;
readonly collectionAdmin: bool;
readonly restricted: Option<UpDataStructsOwnerRestrictedSet>;
}
- /** @name UpDataStructsOwnerRestrictedSet (256) */
+ /** @name UpDataStructsOwnerRestrictedSet (254) */
interface UpDataStructsOwnerRestrictedSet extends BTreeSet<u32> {}
- /** @name UpDataStructsPropertyKeyPermission (261) */
+ /** @name UpDataStructsPropertyKeyPermission (259) */
interface UpDataStructsPropertyKeyPermission extends Struct {
readonly key: Bytes;
readonly permission: UpDataStructsPropertyPermission;
}
- /** @name UpDataStructsPropertyPermission (262) */
+ /** @name UpDataStructsPropertyPermission (260) */
interface UpDataStructsPropertyPermission extends Struct {
readonly mutable: bool;
readonly collectionAdmin: bool;
readonly tokenOwner: bool;
}
- /** @name UpDataStructsProperty (265) */
+ /** @name UpDataStructsProperty (263) */
interface UpDataStructsProperty extends Struct {
readonly key: Bytes;
readonly value: Bytes;
}
- /** @name UpDataStructsCreateItemData (268) */
+ /** @name UpDataStructsCreateItemData (266) */
interface UpDataStructsCreateItemData extends Enum {
readonly isNft: boolean;
readonly asNft: UpDataStructsCreateNftData;
@@ -2626,23 +2637,23 @@
readonly type: 'Nft' | 'Fungible' | 'ReFungible';
}
- /** @name UpDataStructsCreateNftData (269) */
+ /** @name UpDataStructsCreateNftData (267) */
interface UpDataStructsCreateNftData extends Struct {
readonly properties: Vec<UpDataStructsProperty>;
}
- /** @name UpDataStructsCreateFungibleData (270) */
+ /** @name UpDataStructsCreateFungibleData (268) */
interface UpDataStructsCreateFungibleData extends Struct {
readonly value: u128;
}
- /** @name UpDataStructsCreateReFungibleData (271) */
+ /** @name UpDataStructsCreateReFungibleData (269) */
interface UpDataStructsCreateReFungibleData extends Struct {
readonly pieces: u128;
readonly properties: Vec<UpDataStructsProperty>;
}
- /** @name UpDataStructsCreateItemExData (274) */
+ /** @name UpDataStructsCreateItemExData (272) */
interface UpDataStructsCreateItemExData extends Enum {
readonly isNft: boolean;
readonly asNft: Vec<UpDataStructsCreateNftExData>;
@@ -2655,26 +2666,26 @@
readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';
}
- /** @name UpDataStructsCreateNftExData (276) */
+ /** @name UpDataStructsCreateNftExData (274) */
interface UpDataStructsCreateNftExData extends Struct {
readonly properties: Vec<UpDataStructsProperty>;
readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
}
- /** @name UpDataStructsCreateRefungibleExSingleOwner (283) */
+ /** @name UpDataStructsCreateRefungibleExSingleOwner (281) */
interface UpDataStructsCreateRefungibleExSingleOwner extends Struct {
readonly user: PalletEvmAccountBasicCrossAccountIdRepr;
readonly pieces: u128;
readonly properties: Vec<UpDataStructsProperty>;
}
- /** @name UpDataStructsCreateRefungibleExMultipleOwners (285) */
+ /** @name UpDataStructsCreateRefungibleExMultipleOwners (283) */
interface UpDataStructsCreateRefungibleExMultipleOwners extends Struct {
readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;
readonly properties: Vec<UpDataStructsProperty>;
}
- /** @name PalletUniqueSchedulerCall (286) */
+ /** @name PalletUniqueSchedulerCall (284) */
interface PalletUniqueSchedulerCall extends Enum {
readonly isScheduleNamed: boolean;
readonly asScheduleNamed: {
@@ -2704,7 +2715,7 @@
readonly type: 'ScheduleNamed' | 'CancelNamed' | 'ScheduleNamedAfter' | 'ChangeNamedPriority';
}
- /** @name FrameSupportScheduleMaybeHashed (289) */
+ /** @name FrameSupportScheduleMaybeHashed (287) */
interface FrameSupportScheduleMaybeHashed extends Enum {
readonly isValue: boolean;
readonly asValue: Call;
@@ -2713,7 +2724,7 @@
readonly type: 'Value' | 'Hash';
}
- /** @name PalletConfigurationCall (290) */
+ /** @name PalletConfigurationCall (288) */
interface PalletConfigurationCall extends Enum {
readonly isSetWeightToFeeCoefficientOverride: boolean;
readonly asSetWeightToFeeCoefficientOverride: {
@@ -2726,13 +2737,13 @@
readonly type: 'SetWeightToFeeCoefficientOverride' | 'SetMinGasPriceOverride';
}
- /** @name PalletTemplateTransactionPaymentCall (292) */
+ /** @name PalletTemplateTransactionPaymentCall (290) */
type PalletTemplateTransactionPaymentCall = Null;
- /** @name PalletStructureCall (293) */
+ /** @name PalletStructureCall (291) */
type PalletStructureCall = Null;
- /** @name PalletRmrkCoreCall (294) */
+ /** @name PalletRmrkCoreCall (292) */
interface PalletRmrkCoreCall extends Enum {
readonly isCreateCollection: boolean;
readonly asCreateCollection: {
@@ -2838,7 +2849,7 @@
readonly type: 'CreateCollection' | 'DestroyCollection' | 'ChangeCollectionIssuer' | 'LockCollection' | 'MintNft' | 'BurnNft' | 'Send' | 'AcceptNft' | 'RejectNft' | 'AcceptResource' | 'AcceptResourceRemoval' | 'SetProperty' | 'SetPriority' | 'AddBasicResource' | 'AddComposableResource' | 'AddSlotResource' | 'RemoveResource';
}
- /** @name RmrkTraitsResourceResourceTypes (300) */
+ /** @name RmrkTraitsResourceResourceTypes (298) */
interface RmrkTraitsResourceResourceTypes extends Enum {
readonly isBasic: boolean;
readonly asBasic: RmrkTraitsResourceBasicResource;
@@ -2849,7 +2860,7 @@
readonly type: 'Basic' | 'Composable' | 'Slot';
}
- /** @name RmrkTraitsResourceBasicResource (302) */
+ /** @name RmrkTraitsResourceBasicResource (300) */
interface RmrkTraitsResourceBasicResource extends Struct {
readonly src: Option<Bytes>;
readonly metadata: Option<Bytes>;
@@ -2857,7 +2868,7 @@
readonly thumb: Option<Bytes>;
}
- /** @name RmrkTraitsResourceComposableResource (304) */
+ /** @name RmrkTraitsResourceComposableResource (302) */
interface RmrkTraitsResourceComposableResource extends Struct {
readonly parts: Vec<u32>;
readonly base: u32;
@@ -2867,7 +2878,7 @@
readonly thumb: Option<Bytes>;
}
- /** @name RmrkTraitsResourceSlotResource (305) */
+ /** @name RmrkTraitsResourceSlotResource (303) */
interface RmrkTraitsResourceSlotResource extends Struct {
readonly base: u32;
readonly src: Option<Bytes>;
@@ -2877,7 +2888,7 @@
readonly thumb: Option<Bytes>;
}
- /** @name PalletRmrkEquipCall (308) */
+ /** @name PalletRmrkEquipCall (306) */
interface PalletRmrkEquipCall extends Enum {
readonly isCreateBase: boolean;
readonly asCreateBase: {
@@ -2899,7 +2910,7 @@
readonly type: 'CreateBase' | 'ThemeAdd' | 'Equippable';
}
- /** @name RmrkTraitsPartPartType (311) */
+ /** @name RmrkTraitsPartPartType (309) */
interface RmrkTraitsPartPartType extends Enum {
readonly isFixedPart: boolean;
readonly asFixedPart: RmrkTraitsPartFixedPart;
@@ -2908,14 +2919,14 @@
readonly type: 'FixedPart' | 'SlotPart';
}
- /** @name RmrkTraitsPartFixedPart (313) */
+ /** @name RmrkTraitsPartFixedPart (311) */
interface RmrkTraitsPartFixedPart extends Struct {
readonly id: u32;
readonly z: u32;
readonly src: Bytes;
}
- /** @name RmrkTraitsPartSlotPart (314) */
+ /** @name RmrkTraitsPartSlotPart (312) */
interface RmrkTraitsPartSlotPart extends Struct {
readonly id: u32;
readonly equippable: RmrkTraitsPartEquippableList;
@@ -2923,7 +2934,7 @@
readonly z: u32;
}
- /** @name RmrkTraitsPartEquippableList (315) */
+ /** @name RmrkTraitsPartEquippableList (313) */
interface RmrkTraitsPartEquippableList extends Enum {
readonly isAll: boolean;
readonly isEmpty: boolean;
@@ -2932,20 +2943,20 @@
readonly type: 'All' | 'Empty' | 'Custom';
}
- /** @name RmrkTraitsTheme (317) */
+ /** @name RmrkTraitsTheme (315) */
interface RmrkTraitsTheme extends Struct {
readonly name: Bytes;
readonly properties: Vec<RmrkTraitsThemeThemeProperty>;
readonly inherit: bool;
}
- /** @name RmrkTraitsThemeThemeProperty (319) */
+ /** @name RmrkTraitsThemeThemeProperty (317) */
interface RmrkTraitsThemeThemeProperty extends Struct {
readonly key: Bytes;
readonly value: Bytes;
}
- /** @name PalletAppPromotionCall (321) */
+ /** @name PalletAppPromotionCall (319) */
interface PalletAppPromotionCall extends Enum {
readonly isSetAdminAddress: boolean;
readonly asSetAdminAddress: {
@@ -2979,7 +2990,7 @@
readonly type: 'SetAdminAddress' | 'Stake' | 'Unstake' | 'SponsorCollection' | 'StopSponsoringCollection' | 'SponsorContract' | 'StopSponsoringContract' | 'PayoutStakers';
}
- /** @name PalletForeignAssetsModuleCall (322) */
+ /** @name PalletForeignAssetsModuleCall (320) */
interface PalletForeignAssetsModuleCall extends Enum {
readonly isRegisterForeignAsset: boolean;
readonly asRegisterForeignAsset: {
@@ -2996,7 +3007,7 @@
readonly type: 'RegisterForeignAsset' | 'UpdateForeignAsset';
}
- /** @name PalletEvmCall (323) */
+ /** @name PalletEvmCall (321) */
interface PalletEvmCall extends Enum {
readonly isWithdraw: boolean;
readonly asWithdraw: {
@@ -3708,7 +3719,11 @@
readonly isWithdrawFailed: boolean;
readonly isGasPriceTooLow: boolean;
readonly isInvalidNonce: boolean;
- readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
+ readonly isGasLimitTooLow: boolean;
+ readonly isGasLimitTooHigh: boolean;
+ readonly isUndefined: boolean;
+ readonly isReentrancy: boolean;
+ readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce' | 'GasLimitTooLow' | 'GasLimitTooHigh' | 'Undefined' | 'Reentrancy';
}
/** @name FpRpcTransactionStatus (453) */
tests/src/maintenanceMode.seqtest.tsdiffbeforeafterboth--- a/tests/src/maintenanceMode.seqtest.ts
+++ b/tests/src/maintenanceMode.seqtest.ts
@@ -237,7 +237,7 @@
expect(tokenId).to.be.equal('1');
await expect(contract.methods.mintWithTokenURI(receiver, 'Test URI').send())
- .to.be.rejectedWith(/submit transaction to pool failed: Pool\(InvalidTransaction\(InvalidTransaction::Call\)\)/);
+ .to.be.rejectedWith(/Returned error: unknown error/);
await expect(contract.methods.ownerOf(tokenId).call()).rejectedWith(/token not found/);