diff --git a/.github/workflows/actions.yaml b/.github/workflows/actions.yaml index cfd16a0..659f44b 100644 --- a/.github/workflows/actions.yaml +++ b/.github/workflows/actions.yaml @@ -5,6 +5,7 @@ on: branches: - main - potlock-sc + - nft-escrow pull_request: permissions: diff --git a/.gitignore b/.gitignore index 689061e..1219f8f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ **/*.interaction.json #Zone identifier WSL stuff -*Zone.Identifier \ No newline at end of file +*Zone.Identifier + +#pems +*.pem \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 6810148..6262280 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1133,6 +1133,22 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nft-escrow" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "multiversx-sc-scenario", +] + +[[package]] +name = "nft-escrow-meta" +version = "0.0.0" +dependencies = [ + "multiversx-sc-meta-lib", + "nft-escrow", +] + [[package]] name = "nibble_vec" version = "0.1.0" @@ -1583,6 +1599,18 @@ dependencies = [ "toml", ] +[[package]] +name = "rust-interact-nft-escrow" +version = "0.0.0" +dependencies = [ + "clap", + "multiversx-sc", + "multiversx-sc-snippets", + "nft-escrow", + "serde", + "toml", +] + [[package]] name = "rustc-demangle" version = "0.1.24" diff --git a/Cargo.toml b/Cargo.toml index 3588d5e..11bc8d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,7 @@ members = [ "contracts/potlock", "contracts/potlock/meta", "contracts/potlock/interact-rs", + "contracts/nft-escrow", + "contracts/nft-escrow/meta", + "contracts/nft-escrow/interactor", ] \ No newline at end of file diff --git a/contracts/nft-escrow/.gitignore b/contracts/nft-escrow/.gitignore new file mode 100644 index 0000000..9f97022 --- /dev/null +++ b/contracts/nft-escrow/.gitignore @@ -0,0 +1 @@ +target/ \ No newline at end of file diff --git a/contracts/nft-escrow/Cargo.lock b/contracts/nft-escrow/Cargo.lock new file mode 100644 index 0000000..b5d73e6 --- /dev/null +++ b/contracts/nft-escrow/Cargo.lock @@ -0,0 +1,2471 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "unicode-normalization", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fca2be1d5c43812bae364ee3f30b3afcb7877cf59f4aeb94c66f313a41d2fac9" + +[[package]] +name = "cc" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "serde", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +dependencies = [ + "hermit-abi", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "multiversx-chain-scenario-format" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921a66f6db5ffff311e355d42a49fd49baf72d7a6a6215b0484dcd9d8dd512a3" +dependencies = [ + "bech32", + "hex", + "num-bigint", + "num-traits", + "serde", + "serde_json", + "sha3", +] + +[[package]] +name = "multiversx-chain-vm" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d91b6ce610a3ac1272f0813284a3f03a34d55db2f86cddaff357bf651074ee" +dependencies = [ + "bitflags 2.6.0", + "colored", + "ed25519-dalek", + "hex", + "hex-literal", + "itertools", + "multiversx-chain-vm-executor", + "num-bigint", + "num-traits", + "rand 0.8.5", + "rand_seeder", + "sha2 0.10.8", + "sha3", +] + +[[package]] +name = "multiversx-chain-vm-executor" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b59072fa0624b55ae5ae3fa6bfa91515bbeb4ac440214bc4a509e2c8806d6e9f" + +[[package]] +name = "multiversx-sc" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236f7890b2208796df8b5ac73b8572ffaf5e2b1531c7ad549d669328b715b657" +dependencies = [ + "bitflags 2.6.0", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcecd449ea708b72f92edaa17158fe4859c1780aed9b52b14de45f26124ccb8b" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "num-bigint", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f7fa25402e5e8054d719951289306fd79e481f7c21b2565b5549b6bc359772" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb683bc78d0e2eb43c16cac790144f53cc2ab27912aeb1484433895742ce698d" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-meta-lib" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb12232450627cb0e9f3ba9493b0bd7445a40066f0e311e19e84de812bbffd56" +dependencies = [ + "clap", + "colored", + "convert_case", + "hex", + "lazy_static", + "multiversx-sc", + "rustc_version", + "semver", + "serde", + "serde_json", + "toml", + "wasmparser", + "wasmprinter", +] + +[[package]] +name = "multiversx-sc-scenario" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7a5e1289d021c89c44688d77110d78edf83ea52b2eff40481a8119ad2f0411" +dependencies = [ + "base64", + "bech32", + "colored", + "hex", + "itertools", + "log", + "multiversx-chain-scenario-format", + "multiversx-chain-vm", + "multiversx-chain-vm-executor", + "multiversx-sc", + "multiversx-sc-meta-lib", + "num-bigint", + "num-traits", + "pathdiff", + "serde", + "serde_json", + "sha2 0.10.8", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-snippets" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2eed6d36d163c03d18858c62959a1f3c6f26999b89d6d9595c35531f3f7783" +dependencies = [ + "base64", + "env_logger", + "futures", + "hex", + "log", + "multiversx-chain-scenario-format", + "multiversx-sc-scenario", + "multiversx-sdk", + "tokio", +] + +[[package]] +name = "multiversx-sdk" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139f1ac6d82e743dd3ae303e47134ab17b7c3e3c4306f09bed11a6054822596c" +dependencies = [ + "anyhow", + "base64", + "bech32", + "bip39", + "hex", + "hmac", + "itertools", + "log", + "pbkdf2", + "pem", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "sha3", + "tokio", + "zeroize", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nft-escrow" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "multiversx-sc-scenario", +] + +[[package]] +name = "nft-escrow-meta" +version = "0.0.0" +dependencies = [ + "multiversx-sc-meta-lib", + "nft-escrow", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "ppv-lite86" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee4364d9f3b902ef14fab8a1ddffb783a1cb6b4bba3bfc1fa3922732c7de97f" +dependencies = [ + "zerocopy 0.6.6", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_seeder" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2890aaef0aa82719a50e808de264f9484b74b442e1a3a0e5ee38243ac40bdb" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "reqwest" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rust-interact" +version = "0.0.0" +dependencies = [ + "clap", + "multiversx-sc", + "multiversx-sc-snippets", + "nft-escrow", + "serde", + "toml", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + +[[package]] +name = "rustls-webpki" +version = "0.102.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +dependencies = [ + "indexmap", + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasmparser" +version = "0.212.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d28bc49ba1e5c5b61ffa7a2eace10820443c4b7d1c0b144109261d14570fdf8" +dependencies = [ + "ahash", + "bitflags 2.6.0", + "hashbrown", + "indexmap", + "semver", + "serde", +] + +[[package]] +name = "wasmprinter" +version = "0.212.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfac65326cc561112af88c3028f6dfdb140acff67ede33a8e86be2dc6b8956f7" +dependencies = [ + "anyhow", + "termcolor", + "wasmparser", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "zerocopy" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" +dependencies = [ + "byteorder", + "zerocopy-derive 0.6.6", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy-derive" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/contracts/nft-escrow/Cargo.toml b/contracts/nft-escrow/Cargo.toml new file mode 100644 index 0000000..67055da --- /dev/null +++ b/contracts/nft-escrow/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "nft-escrow" +version = "0.0.0" +authors = ["you"] +edition = "2018" +publish = false + +[lib] +path = "src/lib.rs" + +[dependencies.multiversx-sc] +version = "0.52.3" + +[dev-dependencies.multiversx-sc-scenario] +version = "0.52.3" + diff --git a/contracts/nft-escrow/interactor/.gitignore b/contracts/nft-escrow/interactor/.gitignore new file mode 100644 index 0000000..5a64d09 --- /dev/null +++ b/contracts/nft-escrow/interactor/.gitignore @@ -0,0 +1,2 @@ +# Pem files are used for interactions, but shouldn't be committed +*.pem diff --git a/contracts/nft-escrow/interactor/Cargo.toml b/contracts/nft-escrow/interactor/Cargo.toml new file mode 100644 index 0000000..b5e3637 --- /dev/null +++ b/contracts/nft-escrow/interactor/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "rust-interact-nft-escrow" +version = "0.0.0" +authors = ["you"] +edition = "2021" +publish = false + +[[bin]] +name = "rust-interact-nft-escrow" +path = "src/interactor_main.rs" + +[dependencies.nft-escrow] +path = ".." + +[dependencies.multiversx-sc-snippets] +version = "0.52.3" + +[dependencies.multiversx-sc] +version = "0.52.3" + +[dependencies] +clap = { version = "4.4.7", features = ["derive"] } +serde = { version = "1.0", features = ["derive"] } +toml = "0.8.6" + +# [workspace] + diff --git a/contracts/nft-escrow/interactor/src/interactor_main.rs b/contracts/nft-escrow/interactor/src/interactor_main.rs new file mode 100644 index 0000000..9ad5a01 --- /dev/null +++ b/contracts/nft-escrow/interactor/src/interactor_main.rs @@ -0,0 +1,651 @@ +#![allow(non_snake_case)] +#![allow(dead_code)] + +mod proxy; + +use multiversx_sc_snippets::imports::*; +use multiversx_sc_snippets::sdk; +use serde::{Deserialize, Serialize}; +use std::{ + io::{Read, Write}, + path::Path, +}; + + +const GATEWAY: &str = sdk::gateway::DEVNET_GATEWAY; +const STATE_FILE: &str = "state.toml"; +const IVAN_ADDRESS: &str = "erd13x29rvmp4qlgn4emgztd8jgvyzdj0p6vn37tqxas3v9mfhq4dy7shalqrx"; +const WANTED_ADDRESS_STRING: &str = "erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx"; +const TOKEN_ID: &str = "INTERNS-c9325f"; + + +#[tokio::main] +async fn main() { + env_logger::init(); + + let mut args = std::env::args(); + let _ = args.next(); + let _cmd = args.next().expect("at least one argument required"); + let _interact = ContractInteract::new().await; + // match cmd.as_str() { + // "deploy" => interact.deploy().await, + // "escrow" => interact.escrow().await, + // "cancel" => interact.cancel().await, + // "accept" => interact.accept().await, + // "getCreatedOffers" => interact.get_created_offers().await, + // "getWantedOffers" => interact.get_wanted_offers().await, + // "created_offers" => interact.created_offers().await, + // "wanted_offers" => interact.wanted_offers().await, + // "offers" => interact.offers().await, + // _ => panic!("unknown command: {}", &cmd), + // } +} + + +#[derive(Debug, Default, Serialize, Deserialize)] +struct State { + contract_address: Option +} + +impl State { + // Deserializes state from file + pub fn load_state() -> Self { + if Path::new(STATE_FILE).exists() { + let mut file = std::fs::File::open(STATE_FILE).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + toml::from_str(&content).unwrap() + } else { + Self::default() + } + } + + /// Sets the contract address + pub fn set_address(&mut self, address: Bech32Address) { + self.contract_address = Some(address); + } + + /// Returns the contract address + pub fn current_address(&self) -> &Bech32Address { + self.contract_address + .as_ref() + .expect("no known contract, deploy first") + } + } + + impl Drop for State { + // Serializes state to file + fn drop(&mut self) { + let mut file = std::fs::File::create(STATE_FILE).unwrap(); + file.write_all(toml::to_string(self).unwrap().as_bytes()) + .unwrap(); + } + } + +struct ContractInteract { + interactor: Interactor, + wallet_address: Address, + contract_code: BytesValue, + state: State +} + +impl ContractInteract { + async fn new() -> Self { + let mut interactor = Interactor::new(GATEWAY).await; + let wallet_address = interactor.register_wallet(test_wallets::ivan()); + + let contract_code = BytesValue::interpret_from( + "mxsc:../output/nft-escrow.mxsc.json", + &InterpreterContext::default(), + ); + + ContractInteract { + interactor, + wallet_address, + contract_code, + state: State::load_state() + } + } + + async fn deploy(&mut self) { + let new_address = self + .interactor + .tx() + .from(&self.wallet_address) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .init() + .code(&self.contract_code) + .returns(ReturnsNewAddress) + .prepare_async() + .run() + .await; + let new_address_bech32 = bech32::encode(&new_address); + self.state + .set_address(Bech32Address::from_bech32_string(new_address_bech32.clone())); + + println!("new address: {new_address_bech32}"); + } + + async fn escrow_succes(&mut self, token_id: String, token_nonce: u64, token_amount: BigUint, + wanted_nft: TokenIdentifier, wanted_nonce: u64, wanted_address: &Bech32Address) -> u32 { + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .escrow(wanted_nft, wanted_nonce, wanted_address) + .payment((TokenIdentifier::from(token_id.as_str()), token_nonce, token_amount)) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result Escrow Success: {:?}", response); + response + } + + async fn escrow_fail(&mut self, token_id: String, token_nonce: u64, token_amount: BigUint, + wanted_nft: TokenIdentifier, wanted_nonce: u64, wanted_address: &Bech32Address, expected_result: ExpectError<'_>) { + self.interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .escrow(wanted_nft, wanted_nonce, wanted_address) + .payment((TokenIdentifier::from(token_id.as_str()), token_nonce, token_amount)) + .returns(expected_result) + .prepare_async() + .run() + .await; + } + + async fn cancel(&mut self, offer_id: u32) { + + self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .cancel(offer_id) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + } + + async fn cancel_failed(&mut self, offer_id: u32, expected_result: ExpectError<'_>) { + + self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .cancel(offer_id) + .returns(expected_result) + .prepare_async() + .run() + .await; + + } + + async fn cancel_failed_adress(&mut self, offer_id: u32, expected_result: ExpectError<'_>) { + + let wallet_address = self.interactor.register_wallet(test_wallets::carol()); + self + .interactor + .tx() + .from(wallet_address) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .cancel(offer_id) + .returns(expected_result) + .prepare_async() + .run() + .await; + + } + + async fn accept_success(&mut self, token_id: String, token_nonce: u64, token_amount: BigUint, offer_id: u32) { + let user = self.interactor.register_wallet(test_wallets::bob()); + let response = self + .interactor + .tx() + .from(user) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .accept(offer_id) + .payment((TokenIdentifier::from(token_id.as_str()), token_nonce, BigUint::from(token_amount))) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result: {response:?}"); + } + + async fn accept_fail(&mut self, token_id: String, token_nonce: u64, token_amount: BigUint, offer_id: u32, expected_result: ExpectError<'_>) { + let response = self + .interactor + .tx() + .from(&self.wallet_address) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .accept(offer_id) + .payment((TokenIdentifier::from(token_id.as_str()), token_nonce, BigUint::from(token_amount))) + .returns(expected_result) + .prepare_async() + .run() + .await; + + println!("Result: {response:?}"); + } + + async fn accept_fail_address(&mut self, token_id: String, token_nonce: u64, token_amount:u128, offer_id: u32, expected_result: ExpectError<'_>) { + //let wallet_address = self.interactor.register_wallet(test_wallets::bob()); + let user = self.interactor.register_wallet(test_wallets::alice()); + let response = self + .interactor + .tx() + .from(user) + .to(self.state.current_address()) + .gas(NumExpr("30,000,000")) + .typed(proxy::NftEscrowContractProxy) + .accept(offer_id) + .payment((TokenIdentifier::from(token_id.as_str()), token_nonce, BigUint::from(token_amount))) + .returns(expected_result) + .prepare_async() + .run() + .await; + + println!("Result: {response:?}"); + } + + async fn get_created_offers(&mut self, address: Bech32Address) { + // let address = bech32::decode("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::NftEscrowContractProxy) + .get_created_offers(address) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result created offers: {result_value:?}"); + } + + async fn get_wanted_offers(&mut self, address: Bech32Address) { + // let address = bech32::decode("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th"); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::NftEscrowContractProxy) + .get_wanted_offers(address) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result wanted offers: {result_value:?}"); + } + + async fn created_offers(&mut self) { + let address = bech32::decode(""); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::NftEscrowContractProxy) + .created_offers(address) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result: {result_value:?}"); + } + + async fn wanted_offers(&mut self) { + let address = bech32::decode(""); + + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::NftEscrowContractProxy) + .wanted_offers(address) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result: {result_value:?}"); + } + + async fn offers(&mut self, id: u32) { + let result_value = self + .interactor + .query() + .to(self.state.current_address()) + .typed(proxy::NftEscrowContractProxy) + .offers(id) + .returns(ReturnsResultUnmanaged) + .prepare_async() + .run() + .await; + + println!("Result: {result_value:?}"); + } + +} + +#[tokio::test] +async fn test_deploy() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; +} + +#[tokio::test] +async fn test_escrow_nonce_zero() { + let mut interact = ContractInteract::new().await; + let token_id = String::from("NICU-970292"); + let token_nonce = 0u64; + let token_amount = BigUint::::from(5u128); + let wanted_nft = TokenIdentifier::from_esdt_bytes(&b""[..]); + let wanted_nonce = 10u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + interact.escrow_fail(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address, ExpectError(4, "ESDT is not an NFT")).await; +} + +#[tokio::test] +async fn test_escrow_value_diff_one() { + let mut interact = ContractInteract::new().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(2u128); + let wanted_nft = TokenIdentifier::from_esdt_bytes(&b""[..]); + let wanted_nonce = 10u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + interact.escrow_fail(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address, ExpectError(4, "ESDT is not an NFT")).await; +} + +#[tokio::test] +async fn test_escrow_wanted_nonce_zero() { + let mut interact = ContractInteract::new().await; + let token_id = String::from(TOKEN_ID); // "BSK-476470" + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::from_esdt_bytes(&b""[..]); + let wanted_nonce = 0u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + interact.escrow_fail(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address, ExpectError(4, "Wanted ESDT is not an NFT")).await; +} + +#[tokio::test] +async fn test_escrow_diff_addresses() { + let mut interact = ContractInteract::new().await; + let token_id = String::from(TOKEN_ID); // "BSK-476470" + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::from_esdt_bytes(&b""[..]); + let wanted_nonce = 10u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(test_wallets::ivan().address().to_string())); + interact.escrow_fail(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address, ExpectError(4, "Wanted address should not be the same as the caller")).await; +} + +#[tokio::test] +async fn test_escrow_success() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&b"MICE-9e007a"[..]); + let wanted_nonce = 106u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + interact.escrow_succes(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address).await; + + let ivan_address = Bech32Address::from_bech32_string(String::from(IVAN_ADDRESS)); + let wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + + interact.get_created_offers(ivan_address).await; + interact.get_wanted_offers(wanted_address).await; +} + +#[tokio::test] +async fn test_escrow_success_twice() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&b"MICE-9e007a"[..]); + let wanted_nonce = 106u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + interact.escrow_succes(token_id.clone(), token_nonce, token_amount.clone(), wanted_nft.clone(), wanted_nonce, wanted_address).await; + interact.escrow_succes(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address).await; + + let ivan_address = Bech32Address::from_bech32_string(String::from(IVAN_ADDRESS)); + let wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + + interact.get_created_offers(ivan_address).await; + interact.get_wanted_offers(wanted_address).await; +} + +#[tokio::test] +async fn test_accept_fail_offer_does_not_exist(){ + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(2u128); + let offer_id = 9999; + interact.accept_fail(token_id, token_nonce, token_amount, offer_id, ExpectError(4, "Offer does not exist")).await; +} + +#[tokio::test] +async fn test_unauthorized_acceptance() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&b"MICE-9e007a"[..]); + let wanted_nonce = 106u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx")); + let offer_id = interact.escrow_succes( + token_id.clone(), token_nonce, token_amount.clone(), wanted_nft, wanted_nonce, wanted_address + ).await; + + println!("Offer id: {offer_id}"); + + let expected_error = ExpectError(4, "Can not accept this offer"); + interact + .accept_fail( + token_id, token_nonce, token_amount, offer_id, expected_error + ) + .await; +} + +#[tokio::test] +async fn test_nft_does_not_match() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount =BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&"INTERNS-c9325f"[..]); + let wanted_nonce = 1u64; + let wanted_address = Bech32Address::from_bech32_string(String::from("erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th")); + let offer_id = interact.escrow_succes( + token_id.clone(), token_nonce, token_amount, wanted_nft.clone(), wanted_nonce, &wanted_address + ).await; + + + println!("Offer id: {}", offer_id); + let token_amount = 2u128; + let expected_error = ExpectError(4, "NFT does not match"); + interact + .accept_fail_address( + token_id.clone(), token_nonce, token_amount, offer_id, expected_error + ).await; + + let toke_nonce_diff = 2u64; + interact + .accept_fail_address( + token_id, toke_nonce_diff, token_amount, offer_id, ExpectError(4, "NFT does not match") + ).await; + + let token_id_diff = "INTERNS-123456"; + interact + .accept_fail_address( + token_id_diff.to_string(), token_nonce, token_amount, offer_id, ExpectError(4, "NFT does not match") + ).await; + +} + +#[tokio::test] +async fn test_accept_success() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount =BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&"MICE-9e007a"[..]); + let wanted_nonce = 2u64; + let wanted_address = Bech32Address::from_bech32_string(String::from("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx")); + let offer_id = interact.escrow_succes( + token_id.clone(), token_nonce, token_amount.clone(), wanted_nft.clone(), wanted_nonce, &wanted_address + ).await; + println!("Offer id: {}", offer_id); + + interact + .accept_success( + token_id, token_nonce, token_amount, offer_id + ).await; +} + + +#[tokio::test] +async fn test_cancel_offer_not_exists() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let offer_id = 123u32; + interact.cancel_failed(offer_id, ExpectError(4, "Offer does not exist")).await; +} + +#[tokio::test] +async fn test_cancel_offer_not_owner() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&b"MICE-9e007a"[..]); + let wanted_nonce = 106u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + let offer_id = interact.escrow_succes(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address).await; + interact.cancel_failed_adress(offer_id, ExpectError(4, "Only the offer creator can cancel it")).await; +} + +#[tokio::test] +async fn test_cancel_offer_success() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount = BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&b"MICE-9e007a"[..]); + let wanted_nonce = 106u64; + let ref wanted_address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + let offer_id = interact.escrow_succes(token_id, token_nonce, token_amount, wanted_nft, wanted_nonce, wanted_address).await; + + interact.cancel(offer_id).await; + + let ivan_address = Bech32Address::from_bech32_string(String::from(IVAN_ADDRESS)); + interact.get_created_offers(ivan_address).await; + +} + +#[tokio::test] +async fn test_created_offers_not_exists() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let address = Bech32Address::from_bech32_string(String::from(IVAN_ADDRESS)); + interact.get_created_offers(address).await; +} + +#[tokio::test] +async fn test_wanted_offers_not_exists() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let address = Bech32Address::from_bech32_string(String::from(WANTED_ADDRESS_STRING)); + interact.get_wanted_offers(address).await; +} + +#[tokio::test] +async fn test_multiple_accept_offer() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount =BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&"MICE-9e007a"[..]); + let wanted_nonce = 2u64; + let wanted_address = Bech32Address::from_bech32_string(String::from("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx")); + let offer_id = interact.escrow_succes( + token_id.clone(), token_nonce, token_amount.clone(), wanted_nft.clone(), wanted_nonce, &wanted_address + ).await; + println!("Offer id: {}", offer_id); + + interact + .accept_success( + token_id.clone(), token_nonce, token_amount.clone(), offer_id + ).await; + + interact.accept_fail(token_id, token_nonce, token_amount, offer_id, ExpectError(4, "Can not accept this offer")).await; +} + +#[tokio::test] +async fn test_multiple_offers_interaction() { + let mut interact = ContractInteract::new().await; + interact.deploy().await; + let token_id = String::from(TOKEN_ID); + let token_nonce = 1u64; + let token_amount =BigUint::::from(1u128); + let wanted_nft = TokenIdentifier::::from_esdt_bytes(&"MICE-9e007a"[..]); + let wanted_nonce = 2u64; + let wanted_address = Bech32Address::from_bech32_string(String::from("erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx")); + let offer_id = interact.escrow_succes( + token_id.clone(), token_nonce, token_amount.clone(), wanted_nft.clone(), wanted_nonce, &wanted_address + ).await; + let offer_id_2 = interact.escrow_succes( + token_id.clone(), token_nonce, token_amount.clone(), wanted_nft.clone(), wanted_nonce, &wanted_address + ).await; + + interact + .accept_success( + token_id, token_nonce, token_amount, offer_id + ).await; + + interact.cancel(offer_id_2).await; +} \ No newline at end of file diff --git a/contracts/nft-escrow/interactor/src/proxy.rs b/contracts/nft-escrow/interactor/src/proxy.rs new file mode 100644 index 0000000..d7c8461 --- /dev/null +++ b/contracts/nft-escrow/interactor/src/proxy.rs @@ -0,0 +1,186 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct NftEscrowContractProxy; + +impl TxProxyTrait for NftEscrowContractProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = NftEscrowContractProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + NftEscrowContractProxyMethods { wrapped_tx: tx } + } +} + +pub struct NftEscrowContractProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl NftEscrowContractProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl NftEscrowContractProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn escrow< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + wanted_nft: Arg0, + wanted_nonce: Arg1, + wanted_address: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("escrow") + .argument(&wanted_nft) + .argument(&wanted_nonce) + .argument(&wanted_address) + .original_result() + } + + pub fn cancel< + Arg0: ProxyArg, + >( + self, + offer_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("cancel") + .argument(&offer_id) + .original_result() + } + + pub fn accept< + Arg0: ProxyArg, + >( + self, + offer_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept") + .argument(&offer_id) + .original_result() + } + + pub fn get_created_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCreatedOffers") + .argument(&address) + .original_result() + } + + pub fn get_wanted_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWantedOffers") + .argument(&address) + .original_result() + } + + pub fn created_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("created_offers") + .argument(&address) + .original_result() + } + + pub fn wanted_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("wanted_offers") + .argument(&address) + .original_result() + } + + pub fn offers< + Arg0: ProxyArg, + >( + self, + id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("offers") + .argument(&id) + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Debug)] +pub struct Offer +where + Api: ManagedTypeApi, +{ + pub creator: ManagedAddress, + pub nft: TokenIdentifier, + pub nonce: u64, + pub wanted_nft: TokenIdentifier, + pub wanted_nonce: u64, + pub wanted_address: ManagedAddress, +} diff --git a/contracts/nft-escrow/interactor/state.toml b/contracts/nft-escrow/interactor/state.toml new file mode 100644 index 0000000..2693d4d --- /dev/null +++ b/contracts/nft-escrow/interactor/state.toml @@ -0,0 +1 @@ +contract_address = "erd1qqqqqqqqqqqqqpgqs3r48rwgeq0zgmug42hcgs5w5qtccl2hdy7s95l56u" diff --git a/contracts/nft-escrow/meta/Cargo.lock b/contracts/nft-escrow/meta/Cargo.lock new file mode 100644 index 0000000..1d5f315 --- /dev/null +++ b/contracts/nft-escrow/meta/Cargo.lock @@ -0,0 +1,753 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "serde", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "indexmap" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "multiversx-sc" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236f7890b2208796df8b5ac73b8572ffaf5e2b1531c7ad549d669328b715b657" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcecd449ea708b72f92edaa17158fe4859c1780aed9b52b14de45f26124ccb8b" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "num-bigint", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f7fa25402e5e8054d719951289306fd79e481f7c21b2565b5549b6bc359772" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb683bc78d0e2eb43c16cac790144f53cc2ab27912aeb1484433895742ce698d" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-meta-lib" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb12232450627cb0e9f3ba9493b0bd7445a40066f0e311e19e84de812bbffd56" +dependencies = [ + "clap", + "colored", + "convert_case", + "hex", + "lazy_static", + "multiversx-sc", + "rustc_version", + "semver", + "serde", + "serde_json", + "toml", + "wasmparser", + "wasmprinter", +] + +[[package]] +name = "nft-escrow" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nft-escrow-meta" +version = "0.0.0" +dependencies = [ + "multiversx-sc-meta-lib", + "nft-escrow", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.204" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.121" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasmparser" +version = "0.212.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d28bc49ba1e5c5b61ffa7a2eace10820443c4b7d1c0b144109261d14570fdf8" +dependencies = [ + "ahash", + "bitflags", + "hashbrown", + "indexmap", + "semver", + "serde", +] + +[[package]] +name = "wasmprinter" +version = "0.212.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfac65326cc561112af88c3028f6dfdb140acff67ede33a8e86be2dc6b8956f7" +dependencies = [ + "anyhow", + "termcolor", + "wasmparser", +] + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/contracts/nft-escrow/meta/Cargo.toml b/contracts/nft-escrow/meta/Cargo.toml new file mode 100644 index 0000000..3668094 --- /dev/null +++ b/contracts/nft-escrow/meta/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "nft-escrow-meta" +version = "0.0.0" +edition = "2018" +publish = false +authors = ["you"] + +[dev-dependencies] + +[dependencies.nft-escrow] +path = ".." + +[dependencies.multiversx-sc-meta-lib] +version = "0.52.3" +default-features = false diff --git a/contracts/nft-escrow/meta/src/main.rs b/contracts/nft-escrow/meta/src/main.rs new file mode 100644 index 0000000..bf12d89 --- /dev/null +++ b/contracts/nft-escrow/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta_lib::cli_main::(); +} diff --git a/contracts/nft-escrow/multiversx.json b/contracts/nft-escrow/multiversx.json new file mode 100644 index 0000000..7365539 --- /dev/null +++ b/contracts/nft-escrow/multiversx.json @@ -0,0 +1,3 @@ +{ + "language": "rust" +} \ No newline at end of file diff --git a/contracts/nft-escrow/mxsc-template.toml b/contracts/nft-escrow/mxsc-template.toml new file mode 100644 index 0000000..441addd --- /dev/null +++ b/contracts/nft-escrow/mxsc-template.toml @@ -0,0 +1,18 @@ +name = "empty" +contract_trait = "EmptyContract" +src_file = "empty.rs" +rename_pairs = [ + [ + "blockchain.set_current_dir_from_workspace(\"contracts/examples/empty\");", + "// blockchain.set_current_dir_from_workspace(\"relative path to your workspace, if applicable\");", + ], +] +files_include = [ + "meta", + "scenarios", + "src", + "tests", + "wasm/Cargo.toml", + "Cargo.toml", + "multiversx.json", +] diff --git a/contracts/nft-escrow/output/nft-escrow.abi.json b/contracts/nft-escrow/output/nft-escrow.abi.json new file mode 100644 index 0000000..d1f8ff7 --- /dev/null +++ b/contracts/nft-escrow/output/nft-escrow.abi.json @@ -0,0 +1,189 @@ +{ + "buildInfo": { + "rustc": { + "version": "1.80.0", + "commitHash": "051478957371ee0084a7c0913941d2a8c4757bb9", + "commitDate": "2024-07-21", + "channel": "Stable", + "short": "rustc 1.80.0 (051478957 2024-07-21)" + }, + "contractCrate": { + "name": "nft-escrow", + "version": "0.0.0" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.51.1" + } + }, + "name": "NftEscrowContract", + "constructor": { + "inputs": [], + "outputs": [] + }, + "endpoints": [ + { + "name": "escrow", + "mutability": "mutable", + "payableInTokens": [ + "*" + ], + "inputs": [ + { + "name": "wanted_nft", + "type": "TokenIdentifier" + }, + { + "name": "wanted_nonce", + "type": "u64" + }, + { + "name": "wanted_address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "u32" + } + ] + }, + { + "name": "cancel", + "mutability": "mutable", + "inputs": [ + { + "name": "offer_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "accept", + "mutability": "mutable", + "payableInTokens": [ + "*" + ], + "inputs": [ + { + "name": "offer_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "getCreatedOffers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic>", + "multi_result": true + } + ] + }, + { + "name": "getWantedOffers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic>", + "multi_result": true + } + ] + }, + { + "name": "created_offers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic", + "multi_result": true + } + ] + }, + { + "name": "wanted_offers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic", + "multi_result": true + } + ] + }, + { + "name": "offers", + "mutability": "readonly", + "inputs": [ + { + "name": "id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "Offer" + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": { + "Offer": { + "type": "struct", + "fields": [ + { + "name": "creator", + "type": "Address" + }, + { + "name": "nft", + "type": "TokenIdentifier" + }, + { + "name": "nonce", + "type": "u64" + }, + { + "name": "wanted_nft", + "type": "TokenIdentifier" + }, + { + "name": "wanted_nonce", + "type": "u64" + }, + { + "name": "wanted_address", + "type": "Address" + } + ] + } + } +} diff --git a/contracts/nft-escrow/output/nft-escrow.imports.json b/contracts/nft-escrow/output/nft-escrow.imports.json new file mode 100644 index 0000000..0b22a88 --- /dev/null +++ b/contracts/nft-escrow/output/nft-escrow.imports.json @@ -0,0 +1,26 @@ +[ + "bigIntAdd", + "bigIntCmp", + "bigIntSetInt64", + "checkNoPayment", + "getNumArguments", + "mBufferAppend", + "mBufferAppendBytes", + "mBufferCopyByteSlice", + "mBufferEq", + "mBufferFinish", + "mBufferGetArgument", + "mBufferGetByteSlice", + "mBufferGetLength", + "mBufferNew", + "mBufferSetBytes", + "mBufferStorageLoad", + "mBufferStorageStore", + "managedCaller", + "managedGetMultiESDTCallValue", + "managedMultiTransferESDTNFTExecute", + "managedSignalError", + "signalError", + "smallIntFinishUnsigned", + "smallIntGetUnsignedArgument" +] \ No newline at end of file diff --git a/contracts/nft-escrow/output/nft-escrow.mxsc.json b/contracts/nft-escrow/output/nft-escrow.mxsc.json new file mode 100644 index 0000000..96d7410 --- /dev/null +++ b/contracts/nft-escrow/output/nft-escrow.mxsc.json @@ -0,0 +1,231 @@ +{ + "buildInfo": { + "rustc": { + "version": "1.80.0", + "commitHash": "051478957371ee0084a7c0913941d2a8c4757bb9", + "commitDate": "2024-07-21", + "channel": "Stable", + "short": "rustc 1.80.0 (051478957 2024-07-21)" + }, + "contractCrate": { + "name": "nft-escrow", + "version": "0.0.0" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.51.1" + } + }, + "abi": { + "name": "NftEscrowContract", + "constructor": { + "inputs": [], + "outputs": [] + }, + "endpoints": [ + { + "name": "escrow", + "mutability": "mutable", + "payableInTokens": [ + "*" + ], + "inputs": [ + { + "name": "wanted_nft", + "type": "TokenIdentifier" + }, + { + "name": "wanted_nonce", + "type": "u64" + }, + { + "name": "wanted_address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "u32" + } + ] + }, + { + "name": "cancel", + "mutability": "mutable", + "inputs": [ + { + "name": "offer_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "accept", + "mutability": "mutable", + "payableInTokens": [ + "*" + ], + "inputs": [ + { + "name": "offer_id", + "type": "u32" + } + ], + "outputs": [] + }, + { + "name": "getCreatedOffers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic>", + "multi_result": true + } + ] + }, + { + "name": "getWantedOffers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic>", + "multi_result": true + } + ] + }, + { + "name": "created_offers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic", + "multi_result": true + } + ] + }, + { + "name": "wanted_offers", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "variadic", + "multi_result": true + } + ] + }, + { + "name": "offers", + "mutability": "readonly", + "inputs": [ + { + "name": "id", + "type": "u32" + } + ], + "outputs": [ + { + "type": "Offer" + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": { + "Offer": { + "type": "struct", + "fields": [ + { + "name": "creator", + "type": "Address" + }, + { + "name": "nft", + "type": "TokenIdentifier" + }, + { + "name": "nonce", + "type": "u64" + }, + { + "name": "wanted_nft", + "type": "TokenIdentifier" + }, + { + "name": "wanted_nonce", + "type": "u64" + }, + { + "name": "wanted_address", + "type": "Address" + } + ] + } + } + }, + "code": "0061736d0100000001601160027f7f0060027f7f017f60000060017f0060017f017f6000017f60037f7f7f0060037f7f7f017f60047f7f7f7f017f60027f7e0060047f7f7f7f0060017f017e60017e0060057f7f7e7f7f017f60037f7e7f0060027e7f0060027f7f017e02bb041803656e760b7369676e616c4572726f72000003656e760a6d4275666665724e6577000503656e760d6d427566666572417070656e64000103656e76096d4275666665724571000103656e760e626967496e74536574496e743634000903656e760d6d616e6167656443616c6c6572000303656e761c6d616e616765644765744d756c74694553445443616c6c56616c7565000303656e76106d4275666665724765744c656e677468000403656e76126d427566666572417070656e644279746573000703656e76126d616e616765645369676e616c4572726f72000303656e761b736d616c6c496e74476574556e7369676e6564417267756d656e74000b03656e760f6765744e756d417267756d656e7473000503656e7616736d616c6c496e7446696e697368556e7369676e6564000c03656e760d6d42756666657246696e697368000403656e7609626967496e74416464000603656e76226d616e616765644d756c74695472616e73666572455344544e465445786563757465000d03656e76146d427566666572436f707942797465536c696365000803656e760f6d4275666665725365744279746573000703656e76136d42756666657247657442797465536c696365000803656e7609626967496e74436d70000103656e76126d42756666657253746f726167654c6f6164000103656e76136d42756666657253746f7261676553746f7265000103656e76126d427566666572476574417267756d656e74000103656e760e636865636b4e6f5061796d656e74000203434200040004010505000100050308020a010107040303030305070606000e0000000f04040300090104000101100400010601000a00000002020202020202020202020605030100030616037f01418080080b7f0041f5d1080b7f004180d2080b07a1010d066d656d6f7279020004696e6974004e06657363726f77004f0663616e63656c005006616363657074005110676574437265617465644f666665727300520f67657457616e7465644f666665727300530e637265617465645f6f666665727300540d77616e7465645f6f66666572730055066f666665727300560863616c6c4261636b00570a5f5f646174615f656e6403010b5f5f686561705f6261736503020adf26427101017f230041d0006b22022400200241086a20011019101a200241c8006a200241206a290300370200200241406b200241186a290300370200200241386a200241106a2903003702002000200136020020022002290308370230200041046a2002412c6a41241059200241d0006a24000b1200200041b08308410610272200104020000bdf0102057f027e230041206b220224002001103a220510072103200241003a001c2002200336021820022005360214200220033602102002410036020c2002410c6a2204200110412103200420011042210520042001104321072002410c6a2001104221042002410c6a2001104321082002410c6a2001104121062002280210200228020c46044020022d001c044041ecd108410036020041f0d10841003a00000b2000200636021c2000200436021820002005360214200020033602102000200837030820002007370300200241206a24000f0b200141b58208410e1031000b0f01017f10012201200010021a20010b0b0020002001100341004a0b0e01017f101e22004201100420000b1901017f41d8830841d8830828020041016b220036020020000b4101017f2001280204220220012802084b047f4100052001200241016a360204200128020028020020021020210141010b210220002001360204200020023602000b0a0020002001103e103f0b0900200020011000000b0c01017f101e2200100520000bf002020a7f017e230041106b22022400416b2103024041f4d1082d000022010440416b41ffffffff0720011b21030c010b41f4d10841013a0000416b10060b024020031007417071411046044041002101200310072106200241086a2107410121040340200141106a220820064b0d022007420037030020024200370300200320012002411010241a200404402002290204220b423886200b4280fe038342288684200b428080fc0783421886200b42808080f80f834208868484200b42088842808080f80f83200b421888428080fc078384200b4228884280fe0383200b423888848484210b2002280200220141187420014180fe03714108747220014108764180fe0371200141187672722109200228020c220141187420014180fe03714108747220014108764180fe037120014118767272210a4101210541002104200821010c010b0b1025000b41e0810841221000000b2000200a36020c200020093602082000200b370300200241106a24000b0f00200020012003200210124100470b05001058000b2e01017f418282084117102722042000200110081a200441998208410310081a20042002200310081a20041009000b1101017f101e22022000200110111a20020b2401017e4100100a22024280808080105a04402000200141b58208410e1026000b2002a70b1f002000102a2200100741204704402001200241fc820841101026000b20000b0d002000101e220010161a20000b1400100b20004604400f0b419c820841191000000b4e01017f230041206b2201240020012000280204103f36021c20014101360218200120003602140340200141086a200141146a101f20012802080440200135020c100c0c010b0b200141206a24000b6e01047f230041106b2202240020001007210303402003200141046a22044f04402002410036020c200020012002410c6a410410241a200228020c220141187420014180fe03714108747220014108764180fe037120014118767272100d1a200421010c010b0b200241106a24000b890202017e077f230041106b22022400200028021020002903002101200028020c21062000280208102f2107102f2108102f2104101b2103101e220042001004200020002006100e2002200142388620014280fe0383422886842001428080fc0783421886200142808080f80f834208868484200142088842808080f80f832001421888428080fc07838420014228884280fe038320014238888484843702042002200341187420034180fe03714108747220034108764180fe0371200341187672723602002002200041187420004180fe03714108747220004108764180fe03712000411876727236020c20042002411010081a2802002004420020072008100f1a200241106a24000b1101017f101e22004101410010111a20000b3801027f2000280200210310012104200028020820032001200410104504402000200120036a36020020040f0b200241c38208410f1031000b2c01017f41dd8208411b10272203200010021a200341998208410310081a20032001200210081a20031009000b0b0020002001200210081a0b880102027f017e230041106b22032400102f2102200135020021042003420037030820032004200341086a103420022003280200200328020410111a200020021035102f101b220220012802181036200128021c20021037200129030820021038200128022020021037200129031020021038200220012802241036200020021035200341106a24000b7c01037f200220013c00072002410036000020022001420888a722053a000620022001421088a722043a000520022001421888a722033a000420004108200320047241ff017145220441044105200341ff01711b6a41002004200541ff01711b22036a200341002001501b6a22036b3602042000200220036a3602000b4601017f230041106b220224002002200141187420014180fe03714108747220014108764180fe03712001411876727236020c20002002410c6a410410081a200241106a24000b09002000200110021a0b4f01027f230041106b22022400200220001007220341187420034180fe03714108747220034108764180fe03712003411876727236020c20012002410c6a41041032200120001036200241106a24000b7701017f230041106b220224002002200042388620004280fe0383422886842000428080fc0783421886200042808080f80f834208868484200042088842808080f80f832000421888428080fc07838420004228884280fe038320004238888484843703082001200241086a41081032200241106a24000b0f00417242011004200041721013450b0d002000101e220010141a20000b1200416c4101410010111a2000416c10151a0b090020002001ad103d0b3701017f230041106b220224002002420037030820022001200241086a1034200020022802002002280204102710151a200241106a24000b19002000101b220041d28208410510081a20012000104020000bbe0102017e037f230041106b220224002002420037030802402000103a220410072203410949044020044100200220036b41106a200310241a2002290308220142388620014280fe0383422886842001428080fc0783421886200142808080f80f834208868484200142088842808080f80f832001421888428080fc07838420014228884280fe0383200142388884848422014280808080105a0d01200241106a24002001a70f0b200041b58208410e1031000b200041b58208410e1031000b4501017f230041106b220224002002200041187420004180fe03714108747220004108764180fe03712000411876727236020c20012002410c6a41041032200241106a24000b0a0020004120200110300b5401017f230041106b220224002002410036020c20002002410c6a41042001104a2000200228020c220041187420004180fe03714108747220004108764180fe03712000411876727220011030200241106a24000b840102017e017f230041106b22032400200342003703082000200341086a41082001104a20032903082102200341106a2400200242388620024280fe0383422886842002428080fc0783421886200242808080f80f834208868484200242088842808080f80f832002421888428080fc07838420024228884280fe038320024238888484840b0e002000416710141a41671007450b9f0101067f02402000280208220520011046220304400240200320002802042204103f22024d044020022003460d012004103f2002490d03200028020022072002102021062004103f2003490d0320072003103e2006ad103d0c010b0c020b2004103f2002490d0120002802002002103e103b2004200241016b103c2002200347044020052006200310470b200520011048103b0b0f0b41b6830841121000000b0a00200020011048103f0b0d002000200110482002ad103d0b19002000101b220041d78208410610081a20012000104020000b4101037f200028020822032001104645044020002802042202103f21042000280200200441016a2200103e2001ad103d20022000103c200320012002103f10470b0bcc0101037f2000280200210502400240024002400240024020002d001045044020002802082204100722064190ce004b0d0141f0d1082d00000d0141ecd108200636020041f0d10841013a00002004410041dc8308200610241a200041013a00100b200220056a220441ecd1082802004d0d010c050b200041003a0010200420052001200210240d04200220056a21040c010b20042005490d0120044190ce004b0d022001200541dc83086a200210590b200020043602000f0b1058000b1025000b200341c38208410f1031000b2e01027f2001101b21022001101b220341f88208410410081a2000200336020420002001360200200020023602080b1801017f41978308410c102722022001103620002002104b0b1801017f41a38308410d102722022001103620002002104b0b080010174100102b0bf30102077f037e230041206b220124004103102b4100102a21054101100a2107410241888008410e102921032001102302400240024020012903002208500d00200128020c1039450d002007500d01102222042003101c0d02418c8308410b102722002000103f41016a2200ad2209103d200141146a22022004104d20022000104920022003104c20022000104920012802082000101921064101410010272200200410021a200010372008200010382005200010372007200010382000200310021a2006200010151a2009100c200141206a24000f0b4182810841121021000b4194810841191021000b41ad810841331021000bb60102047f017e230041406a2200240010174101102b02404180800841081028220210192201104445044010222103200041086a2001101a20002802182003101c450d01200041286a22012003104d20012002104520012000280224104c20012002104520021019103b20002903082104200028021c21022000101d36023420002002360230200020043703282000200041186a3602382001102e200041406b24000f0b41ca800841141021000b41de800841241021000b980202057f017e230041d0006b220024004101102b0240024041808008410810282201101922021044450440200041086a2002101a10222102200028022422042002101c450d01200041286a102320002802302000280220101c450d0220002903282000290310520d0220002802341039450d02200041386a22032000280218104d20032001104520032004104c20032001104520011019103b200041406b200041306a290300370300200020002903283703382000200041186a22013602482003102e20002903082105200028021c21022000101d3602442000200236024020002005370338200020013602482003102e200041d0006a24000f0b41ca800841141021000b419f800841191021000b41b8800841121021000b820101047f230041d0006b2200240010174101102b410041988008410710292101102f2102200041106a22032001104d20002000280214103f360224200041013602202000200336021c0340200041086a2000411c6a101f20002802080440200041286a2201200028020c10182002200110330c010b0b2002102d200041d0006a24000b820101047f230041d0006b2200240010174101102b410041988008410710292101102f2102200041106a22032001104c20002000280214103f360224200041013602202000200336021c0340200041086a2000411c6a101f20002802080440200041286a2201200028020c10182002200110330c010b0b2002102d200041d0006a24000b3101027f230041106b2200240010174101102b200041046a220141004198800841071029104d2001102c200041106a24000b3101027f230041106b2200240010174101102b200041046a220141004198800841071029104c2001102c200041106a24000b6b01027f230041206b2200240010174101102b200041968008410210281019101a4101410010272201200028021010021a2000280214200110372000290300200110382000280218200110372000290308200110382001200028021c10021a2001100d1a200041206a24000b02000b0b0041c88308410e1000000bab0201067f20002103200241104f04402003410020006b41037122006a210420000440200121050340200320052d00003a0000200541016a2105200341016a22032004490d000b0b2004200220006b2207417c7122066a21030240200020016a22004103710440200641004c0d012000410374220241187121082000417c71220541046a2101410020026b4118712102200528020021050340200420052008762001280200220520027472360200200141046a2101200441046a22042003490d000b0c010b200641004c0d0020002101034020042001280200360200200141046a2101200441046a22042003490d000b0b20074103712102200020066a21010b20020440200220036a21000340200320012d00003a0000200141016a2101200341016a22032000490d000b0b0b0bea030200418080080bd6036f666665725f696477616e7465645f6164647265737369646164647265737343616e206e6f74206163636570742074686973206f666665724e465420646f6573206e6f74206d617463684f6666657220646f6573206e6f742065786973744f6e6c7920746865206f666665722063726561746f722063616e2063616e63656c20697445534454206973206e6f7420616e204e465457616e7465642045534454206973206e6f7420616e204e465457616e74656420616464726573732073686f756c64206e6f74206265207468652073616d65206173207468652063616c6c6572696e636f7272656374206e756d626572206f662045534454207472616e7366657273617267756d656e74206465636f6465206572726f722028293a2077726f6e67206e756d626572206f6620617267756d656e7473696e70757420746f6f206c6f6e67696e70757420746f6f2073686f72742e6974656d2e696e64657873746f72616765206465636f6465206572726f7220286b65793a202e6c656e626164206172726179206c656e6774686c6173744f66666572496477616e7465644f6666657273637265617465644f66666572736f6666657273696e646578206f7574206f662072616e676570616e6963206f636375727265640041d883080b0438ffffff", + "report": { + "imports": [ + "bigIntAdd", + "bigIntCmp", + "bigIntSetInt64", + "checkNoPayment", + "getNumArguments", + "mBufferAppend", + "mBufferAppendBytes", + "mBufferCopyByteSlice", + "mBufferEq", + "mBufferFinish", + "mBufferGetArgument", + "mBufferGetByteSlice", + "mBufferGetLength", + "mBufferNew", + "mBufferSetBytes", + "mBufferStorageLoad", + "mBufferStorageStore", + "managedCaller", + "managedGetMultiESDTCallValue", + "managedMultiTransferESDTNFTExecute", + "managedSignalError", + "signalError", + "smallIntFinishUnsigned", + "smallIntGetUnsignedArgument" + ], + "isMemGrow": true, + "eiCheck": { + "eiVersion": "1.3", + "ok": true + }, + "codeReport": { + "path": "../output/nft-escrow.wasm", + "size": 6397, + "hasAllocator": false, + "hasPanic": "without message" + } + } +} diff --git a/contracts/nft-escrow/output/nft-escrow.wasm b/contracts/nft-escrow/output/nft-escrow.wasm new file mode 100644 index 0000000..e900761 Binary files /dev/null and b/contracts/nft-escrow/output/nft-escrow.wasm differ diff --git a/contracts/nft-escrow/output/proxy.rs b/contracts/nft-escrow/output/proxy.rs new file mode 100644 index 0000000..d7c8461 --- /dev/null +++ b/contracts/nft-escrow/output/proxy.rs @@ -0,0 +1,186 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct NftEscrowContractProxy; + +impl TxProxyTrait for NftEscrowContractProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = NftEscrowContractProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + NftEscrowContractProxyMethods { wrapped_tx: tx } + } +} + +pub struct NftEscrowContractProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl NftEscrowContractProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl NftEscrowContractProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn escrow< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + wanted_nft: Arg0, + wanted_nonce: Arg1, + wanted_address: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("escrow") + .argument(&wanted_nft) + .argument(&wanted_nonce) + .argument(&wanted_address) + .original_result() + } + + pub fn cancel< + Arg0: ProxyArg, + >( + self, + offer_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("cancel") + .argument(&offer_id) + .original_result() + } + + pub fn accept< + Arg0: ProxyArg, + >( + self, + offer_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept") + .argument(&offer_id) + .original_result() + } + + pub fn get_created_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCreatedOffers") + .argument(&address) + .original_result() + } + + pub fn get_wanted_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWantedOffers") + .argument(&address) + .original_result() + } + + pub fn created_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("created_offers") + .argument(&address) + .original_result() + } + + pub fn wanted_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("wanted_offers") + .argument(&address) + .original_result() + } + + pub fn offers< + Arg0: ProxyArg, + >( + self, + id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("offers") + .argument(&id) + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Debug)] +pub struct Offer +where + Api: ManagedTypeApi, +{ + pub creator: ManagedAddress, + pub nft: TokenIdentifier, + pub nonce: u64, + pub wanted_nft: TokenIdentifier, + pub wanted_nonce: u64, + pub wanted_address: ManagedAddress, +} diff --git a/contracts/nft-escrow/sc-config.toml b/contracts/nft-escrow/sc-config.toml new file mode 100644 index 0000000..b9e5d7a --- /dev/null +++ b/contracts/nft-escrow/sc-config.toml @@ -0,0 +1,4 @@ + +[[proxy]] +path = "interactor/src/proxy.rs" + diff --git a/contracts/nft-escrow/scenarios/accept.scen.json b/contracts/nft-escrow/scenarios/accept.scen.json new file mode 100644 index 0000000..55e0e3d --- /dev/null +++ b/contracts/nft-escrow/scenarios/accept.scen.json @@ -0,0 +1,258 @@ +{ + "name": "buy nft", + "steps": [ + { + "step": "externalSteps", + "path": "escrow.scen.json" + }, + { + "step": "scCall", + "id": "accept-offer-not-exists", + "tx": { + "from": "address:second", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "accept", + "arguments": [ + "2" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:Offer does not exist", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "accept-offer-only-wanted", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "accept", + "arguments": [ + "1" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:Can not accept this offer", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "accept-other-token", + "tx": { + "from": "address:second", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "accept", + "arguments": [ + "1" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:SEMIFUNG-123456", + "value": "1000", + "nonce": "1" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:NFT does not match", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "accept-other-nonce", + "tx": { + "from": "address:second", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "accept", + "arguments": [ + "1" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT2-654321", + "value": "1", + "nonce": "1" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:NFT does not match", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "accept-other-amount", + "tx": { + "from": "address:second", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "accept", + "arguments": [ + "1" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT2-654321", + "value": "2", + "nonce": "2" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:NFT does not match", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "accept", + "tx": { + "from": "address:second", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "accept", + "arguments": [ + "1" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT2-654321", + "value": "1", + "nonce": "2" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:first": { + "nonce": "6", + "balance": "0", + "esdt": { + "str:FUNG-123456": "1000", + "str:SEMIFUNG-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1000" + } + ] + }, + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + }, + { + "nonce": "2", + "balance": "1" + } + ] + }, + "str:NFT2-654321": { + "instances": [ + { + "nonce": "2", + "balance": "1" + } + ] + } + } + }, + "address:second": { + "nonce": "5", + "balance": "0", + "esdt": { + "str:FUNG-123456": "1000", + "str:SEMIFUNG-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1000" + } + ] + }, + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "0" + } + ] + }, + "str:NFT2-654321": { + "instances": [ + { + "nonce": "1", + "balance": "1" + }, + { + "nonce": "2", + "balance": "1" + } + ] + } + } + }, + "sc:nft-escrow": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:NFT-123456": { + "instances": [] + } + }, + "storage": { + "str:lastOfferId": "1" + }, + "code": "mxsc:../output/nft-escrow.mxsc.json", + "owner": "address:owner" + }, + "+": "" + } + } + ] +} \ No newline at end of file diff --git a/contracts/nft-escrow/scenarios/cancel.scen.json b/contracts/nft-escrow/scenarios/cancel.scen.json new file mode 100644 index 0000000..c9ce020 --- /dev/null +++ b/contracts/nft-escrow/scenarios/cancel.scen.json @@ -0,0 +1,121 @@ +{ + "name": "buy nft", + "steps": [ + { + "step": "externalSteps", + "path": "escrow.scen.json" + }, + { + "step": "scCall", + "id": "cancel-offer-not-exists", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "cancel", + "arguments": [ + "2" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:Offer does not exist", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "cancel-offer-only-creator", + "tx": { + "from": "address:second", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "cancel", + "arguments": [ + "1" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:Only the offer creator can cancel it", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "cancel", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "cancel", + "arguments": [ + "1" + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:first": { + "nonce": "7", + "balance": "0", + "esdt": { + "str:FUNG-123456": "1000", + "str:SEMIFUNG-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1000" + } + ] + }, + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + }, + { + "nonce": "2", + "balance": "1" + } + ] + } + } + }, + "sc:nft-escrow": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:NFT-123456": { + "instances": [] + } + }, + "storage": { + "str:lastOfferId": "1" + }, + "code": "mxsc:../output/nft-escrow.mxsc.json", + "owner": "address:owner" + }, + "+": "" + } + } + ] +} \ No newline at end of file diff --git a/contracts/nft-escrow/scenarios/escrow.scen.json b/contracts/nft-escrow/scenarios/escrow.scen.json new file mode 100644 index 0000000..77325bc --- /dev/null +++ b/contracts/nft-escrow/scenarios/escrow.scen.json @@ -0,0 +1,226 @@ +{ + "name": "buy nft", + "steps": [ + { + "step": "externalSteps", + "path": "init.scen.json" + }, + { + "step": "scCall", + "id": "escrow-fungible", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "escrow", + "arguments": [ + "str:NFT2-654321", + "2", + "address:second" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:FUNG-123456", + "value": "1000" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:ESDT is not an NFT", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "escrow-semi-fungible", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "escrow", + "arguments": [ + "str:NFT2-654321", + "2", + "address:second" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:SEMIFUNG-123456", + "value": "1000", + "nonce": "1" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "4", + "message": "str:ESDT is not an NFT", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "escrow-wanted-not-nft", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "escrow", + "arguments": [ + "str:NFT2-654321", + "0", + "address:second" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT-123456", + "value": "1", + "nonce": "1" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "message": "str:Wanted ESDT is not an NFT", + "status": "4", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "escrow-same-as-caller", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "escrow", + "arguments": [ + "str:NFT2-654321", + "2", + "address:first" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT-123456", + "value": "1", + "nonce": "1" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "message": "str:Wanted address should not be the same as the caller", + "status": "4", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scCall", + "id": "escrow", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "escrow", + "arguments": [ + "str:NFT2-654321", + "2", + "address:second" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT-123456", + "value": "1", + "nonce": "1" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [ + "1" + ], + "status": "0", + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "address:first": { + "nonce": "5", + "balance": "0", + "esdt": { + "str:FUNG-123456": "1000", + "str:SEMIFUNG-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1000" + } + ] + }, + "str:NFT-123456": { + "instances": [ + { + "nonce": "2", + "balance": "1" + } + ] + } + } + }, + "sc:nft-escrow": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + } + ] + } + }, + "storage": { + "str:createdOffers|address:first|``.len": "1", + "str:createdOffers|address:first|``.item|u32:1": "1", + "str:createdOffers|address:first|``.index|u32:1": "1", + "str:wantedOffers|address:second|``.len": "1", + "str:wantedOffers|address:second|``.item|u32:1": "1", + "str:wantedOffers|address:second|``.index|u32:1": "1", + "str:offers|u32:1": { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:1", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:2", + "06-wanted_address": "address:second" + }, + "str:lastOfferId": "1" + }, + "code": "mxsc:../output/nft-escrow.mxsc.json", + "owner": "address:owner" + }, + "+": "" + } + } + ] +} \ No newline at end of file diff --git a/contracts/nft-escrow/scenarios/init.scen.json b/contracts/nft-escrow/scenarios/init.scen.json new file mode 100644 index 0000000..d9c21de --- /dev/null +++ b/contracts/nft-escrow/scenarios/init.scen.json @@ -0,0 +1,105 @@ +{ + "name": "init", + "steps": [ + { + "step": "setState", + "accounts": { + "address:owner": { + "nonce": "0", + "balance": "0" + }, + "address:first": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:FUNG-123456": "1000", + "str:SEMIFUNG-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1000" + } + ] + }, + "str:NFT-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1" + }, + { + "nonce": "2", + "balance": "1" + } + ] + } + } + }, + "address:second": { + "nonce": "0", + "balance": "0", + "esdt": { + "str:FUNG-123456": "1000", + "str:SEMIFUNG-123456": { + "instances": [ + { + "nonce": "1", + "balance": "1000" + } + ] + }, + "str:NFT2-654321": { + "instances": [ + { + "nonce": "1", + "balance": "1" + }, + { + "nonce": "2", + "balance": "2" + } + ] + } + } + } + }, + "newAddresses": [ + { + "creatorAddress": "address:owner", + "creatorNonce": "0", + "newAddress": "sc:nft-escrow" + } + ] + }, + { + "step": "scDeploy", + "id": "deploy", + "tx": { + "from": "address:owner", + "contractCode": "mxsc:../output/nft-escrow.mxsc.json", + "arguments": [], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": [], + "status": "0", + "logs": [], + "gas": "*", + "refund": "*" + } + }, + { + "step": "checkState", + "accounts": { + "sc:nft-escrow": { + "nonce": "0", + "balance": "0", + "storage": {}, + "code": "mxsc:../output/nft-escrow.mxsc.json" + }, + "+": "" + } + } + ] +} \ No newline at end of file diff --git a/contracts/nft-escrow/scenarios/views.scen.json b/contracts/nft-escrow/scenarios/views.scen.json new file mode 100644 index 0000000..10d3512 --- /dev/null +++ b/contracts/nft-escrow/scenarios/views.scen.json @@ -0,0 +1,209 @@ +{ + "name": "buy nft", + "steps": [ + { + "step": "externalSteps", + "path": "escrow.scen.json" + }, + { + "step": "scQuery", + "id": "getCreatedOffersFirst", + "tx": { + "to": "sc:nft-escrow", + "function": "getCreatedOffers", + "arguments": [ + "address:first" + ] + }, + "expect": { + "out": [ + "1", + { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:1", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:2", + "06-wanted_address": "address:second" + } + ] + } + }, + { + "step": "scQuery", + "id": "getCreatedOffersSecond", + "tx": { + "to": "sc:nft-escrow", + "function": "getCreatedOffers", + "arguments": [ + "address:second" + ] + }, + "expect": { + "out": [] + } + }, + { + "step": "scQuery", + "id": "getWantedOffersFirst", + "tx": { + "to": "sc:nft-escrow", + "function": "getWantedOffers", + "arguments": [ + "address:first" + ] + }, + "expect": { + "out": [] + } + }, + { + "step": "scQuery", + "id": "getWantedOffersSecond", + "tx": { + "to": "sc:nft-escrow", + "function": "getWantedOffers", + "arguments": [ + "address:second" + ] + }, + "expect": { + "out": [ + "1", + { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:1", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:2", + "06-wanted_address": "address:second" + } + ] + } + }, + { + "step": "scCall", + "id": "escrow", + "tx": { + "from": "address:first", + "to": "sc:nft-escrow", + "egldValue": "0", + "function": "escrow", + "arguments": [ + "str:NFT2-654321", + "1", + "address:second" + ], + "esdtValue": [ + { + "tokenIdentifier": "str:NFT-123456", + "value": "1", + "nonce": "2" + } + ], + "gasLimit": "10,000,000", + "gasPrice": "0" + }, + "expect": { + "out": ["2"], + "status": "0", + "gas": "*", + "refund": "*" + } + }, + { + "step": "scQuery", + "id": "getCreatedOffersFirstAgain", + "tx": { + "to": "sc:nft-escrow", + "function": "getCreatedOffers", + "arguments": [ + "address:first" + ] + }, + "expect": { + "out": [ + "1", + { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:1", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:2", + "06-wanted_address": "address:second" + }, + "2", + { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:2", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:1", + "06-wanted_address": "address:second" + } + ] + } + }, + { + "step": "scQuery", + "id": "getCreatedOffersSecond", + "tx": { + "to": "sc:nft-escrow", + "function": "getCreatedOffers", + "arguments": [ + "address:second" + ] + }, + "expect": { + "out": [] + } + }, + { + "step": "scQuery", + "id": "getWantedOffersFirst", + "tx": { + "to": "sc:nft-escrow", + "function": "getWantedOffers", + "arguments": [ + "address:first" + ] + }, + "expect": { + "out": [] + } + }, + { + "step": "scQuery", + "id": "getWantedOffersSecond", + "tx": { + "to": "sc:nft-escrow", + "function": "getWantedOffers", + "arguments": [ + "address:second" + ] + }, + "expect": { + "out": [ + "1", + { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:1", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:2", + "06-wanted_address": "address:second" + }, + "2", + { + "01-creator": "address:first", + "02-nft": "nested:str:NFT-123456", + "03-nonce": "u64:2", + "04-wanted_nft": "nested:str:NFT2-654321", + "05-wanted_nonce": "u64:1", + "06-wanted_address": "address:second" + } + ] + } + } + ] +} diff --git a/contracts/nft-escrow/src/lib.rs b/contracts/nft-escrow/src/lib.rs new file mode 100644 index 0000000..b2bbbda --- /dev/null +++ b/contracts/nft-escrow/src/lib.rs @@ -0,0 +1,186 @@ +#![no_std] + +use multiversx_sc::derive_imports::*; +use multiversx_sc::imports::*; + +#[type_abi] +#[derive(TopEncode, TopDecode, Debug)] +pub struct Offer { + pub creator: ManagedAddress, + pub nft: TokenIdentifier, + pub nonce: u64, + pub wanted_nft: TokenIdentifier, + pub wanted_nonce: u64, + pub wanted_address: ManagedAddress, +} + +#[multiversx_sc::contract] +pub trait NftEscrowContract { + #[init] + fn init(&self) {} + + #[payable("*")] + #[endpoint] + fn escrow( + &self, + wanted_nft: TokenIdentifier, + wanted_nonce: u64, + wanted_address: ManagedAddress, + ) -> u32 { + let payment = self.call_value().single_esdt(); + + require!( + payment.token_nonce > 0 && payment.amount == 1, + "ESDT is not an NFT" + ); + require!(wanted_nonce > 0, "Wanted ESDT is not an NFT"); + + let creator = self.blockchain().get_caller(); + + require!( + creator != wanted_address, + "Wanted address should not be the same as the caller" + ); + + let offer_id = self.last_offer_id().update(|v| { + *v += 1; + + *v + }); + + self.created_offers(&creator).insert(offer_id); + self.wanted_offers(&wanted_address).insert(offer_id); + + let offer = Offer { + creator, + nft: payment.token_identifier, + nonce: payment.token_nonce, + wanted_nft, + wanted_nonce, + wanted_address, + }; + + self.offers(offer_id).set(offer); + + offer_id + } + + #[endpoint] + fn cancel(&self, offer_id: u32) { + let offers_mapper = self.offers(offer_id); + + require!(!offers_mapper.is_empty(), "Offer does not exist"); + + let caller = self.blockchain().get_caller(); + + let offer = offers_mapper.get(); + + require!( + offer.creator == caller, + "Only the offer creator can cancel it" + ); + + self.created_offers(&caller).swap_remove(&offer_id); + self.wanted_offers(&offer.wanted_address) + .swap_remove(&offer_id); + + self.offers(offer_id).clear(); + + self.tx() + .to(&offer.creator) + .payment(EsdtTokenPayment::new( + offer.nft, + offer.nonce, + BigUint::from(1u64), + )) + .transfer(); + } + + #[payable("*")] + #[endpoint] + fn accept(&self, offer_id: u32) { + let offers_mapper = self.offers(offer_id); + + require!(!offers_mapper.is_empty(), "Offer does not exist"); + + let offer = offers_mapper.get(); + + let caller = self.blockchain().get_caller(); + + require!(offer.wanted_address == caller, "Can not accept this offer"); + + let payment = self.call_value().single_esdt(); + + require!( + payment.token_identifier == offer.wanted_nft + && payment.token_nonce == offer.wanted_nonce + && payment.amount == 1, + "NFT does not match" + ); + + self.created_offers(&offer.creator).swap_remove(&offer_id); + self.wanted_offers(&offer.wanted_address) + .swap_remove(&offer_id); + + self.offers(offer_id).clear(); + + self.tx().to(&offer.creator).payment(payment).transfer(); + self.tx() + .to(&offer.wanted_address) + .payment(EsdtTokenPayment::new( + offer.nft, + offer.nonce, + BigUint::from(1u64), + )) + .transfer(); + } + + #[view(getCreatedOffers)] + fn get_created_offers( + &self, + address: ManagedAddress, + ) -> MultiValueEncoded>> { + let mut result = MultiValueEncoded::new(); + + for offer_id in self.created_offers(&address).iter() { + result.push(self.get_offer_result(offer_id)); + } + + result + } + + #[view(getWantedOffers)] + fn get_wanted_offers( + &self, + address: ManagedAddress, + ) -> MultiValueEncoded>> { + let mut result = MultiValueEncoded::new(); + + for offer_id in self.wanted_offers(&address).iter() { + result.push(self.get_offer_result(offer_id)); + } + + result + } + + fn get_offer_result(&self, offer_id: u32) -> MultiValue2> { + let offer = self.offers(offer_id).get(); + + MultiValue2::from((offer_id, offer)) + } + + #[view] + #[storage_mapper("createdOffers")] + fn created_offers(&self, address: &ManagedAddress) -> UnorderedSetMapper; + + #[view] + #[storage_mapper("wantedOffers")] + fn wanted_offers(&self, address: &ManagedAddress) -> UnorderedSetMapper; + + #[view] + #[storage_mapper("offers")] + fn offers(&self, id: u32) -> SingleValueMapper>; + + #[storage_mapper("lastOfferId")] + fn last_offer_id(&self) -> SingleValueMapper; +} diff --git a/contracts/nft-escrow/tests/nft-escrow_blackbox.rs b/contracts/nft-escrow/tests/nft-escrow_blackbox.rs new file mode 100644 index 0000000..3204c5d --- /dev/null +++ b/contracts/nft-escrow/tests/nft-escrow_blackbox.rs @@ -0,0 +1,438 @@ +use multiversx_sc_scenario::imports::*; + +mod proxy; + +const OWNER_ADDRESS: TestAddress = TestAddress::new("OWNER_ADDRESS"); +const BUYER_ADDRESS: TestAddress = TestAddress::new("BUYER_ADDRESS"); +const TOKEN_IDENTIFIER: TestTokenIdentifier = TestTokenIdentifier::new("TOKEN_IDENTIFIER"); +const WANTED_NFT: TestTokenIdentifier = TestTokenIdentifier::new("WANTED_NFT"); +const DIFFERENT_TOKEN: TestTokenIdentifier = TestTokenIdentifier::new("DIFFERENT_TOKEN"); +const SC_ADDRESS: TestSCAddress = TestSCAddress::new("SC_ADDRESS"); + + +const CODE_PATH: MxscPath = MxscPath::new("../output/nft-escrow.mxsc.json"); + +fn world() -> ScenarioWorld { + let mut blockchain = ScenarioWorld::new(); + + blockchain.register_contract(CODE_PATH, nft_escrow::ContractBuilder); + blockchain +} + +struct NftEscrowTestState { + world: ScenarioWorld, +} + +impl NftEscrowTestState { + fn new(world: ScenarioWorld) -> Self { + + let mut world = world; + + world + .account(OWNER_ADDRESS) + .esdt_nft_balance(TOKEN_IDENTIFIER, 1, 10, ManagedBuffer::new()) + .esdt_nft_balance(TOKEN_IDENTIFIER, 0, 10, ManagedBuffer::new()); + + world + .account(BUYER_ADDRESS) + .esdt_nft_balance(WANTED_NFT, 1, 10,ManagedBuffer::new()) + .esdt_nft_balance(WANTED_NFT, 2, 10, ManagedBuffer::new()) + .esdt_nft_balance(DIFFERENT_TOKEN, 1, 10, ManagedBuffer::new()); + + Self { world } + } + + fn deploy(&mut self) { + self.world + .tx() + .from(OWNER_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .init() + .code(CODE_PATH) + .code_metadata(CodeMetadata::PAYABLE) + .returns(ReturnsNewAddress) + .new_address(SC_ADDRESS) + .run(); + } + + fn escrow(&mut self) { + self.world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .escrow(WANTED_NFT, 1u64, BUYER_ADDRESS) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TOKEN_IDENTIFIER), + 1u64, + &BigUint::from(1u64), + ) + .returns(ReturnsResult) + .run(); + } + + fn accept_offer(&mut self, offer_id: u32) { + self.world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(offer_id) + .egld_or_single_esdt(&EgldOrEsdtTokenIdentifier::esdt(WANTED_NFT), 1u64, &BigUint::from(1u64)) + .returns(ReturnsResult) + .run(); + } + + fn cancel_offer(&mut self, offer_id: u32) { + self.world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .cancel(offer_id) + .returns(ReturnsResult) + .run(); + } + + fn get_created_offers(&mut self, address: TestAddress) -> usize { + let result = self.world + .tx() + .from(address) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .get_created_offers(address) + .returns(ReturnsResult) + .run(); + + result.len() + } + + fn get_wanted_offers(&mut self, address: TestAddress) -> usize { + let result = self.world + .tx() + .from(address) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .get_wanted_offers(address) + .returns(ReturnsResult) + .run(); + + result.len() + } + +} + +#[test] +fn test_deploy() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); +} + +#[test] +fn test_escrow_success() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); +} + +#[test] +fn test_escrow_success_twice() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + state.escrow(); +} + +#[test] +fn test_accept_offer_success() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + state.accept_offer(1u32); +} + +#[test] +fn test_cancel_offer_success() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + state.cancel_offer(1u32); +} + +#[test] +fn test_multiple_offers_interaction(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + state.escrow(); + state.accept_offer(1u32); + state.cancel_offer(2u32); +} + +#[test] +fn test_get_created_offers(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + let len = state.get_created_offers(OWNER_ADDRESS); + assert_eq!(len, 0); +} + +#[test] +fn test_get_wanted_offers(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + let len = state.get_wanted_offers(BUYER_ADDRESS); + assert_eq!(len, 0); +} + +//Negative tests + +#[test] +fn test_fail_escrow_nonce_zero() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .escrow(WANTED_NFT, 1u64, BUYER_ADDRESS) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TOKEN_IDENTIFIER), + 0u64, + &BigUint::from(1u64), + ) + .returns(ExpectError(4, "ESDT is not an NFT")) + .run(); +} + +#[test] +fn test_fail_escrow_token_payment_value_not_1() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .escrow(WANTED_NFT, 1u64, BUYER_ADDRESS) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TOKEN_IDENTIFIER), + 1u64, + &BigUint::from(2u64), + ) + .returns(ExpectError(4, "ESDT is not an NFT")) + .run(); +} + +#[test] +fn test_fail_escrow_wanted_token_nonce_0() { + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .escrow(WANTED_NFT, 0u64, BUYER_ADDRESS) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TOKEN_IDENTIFIER), + 1u64, + &BigUint::from(1u64), + ) + .returns(ExpectError(4, "Wanted ESDT is not an NFT")) + .run(); +} + +#[test] +fn test_fail_escrow_same_address(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .escrow(WANTED_NFT, 1u64, OWNER_ADDRESS) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(TOKEN_IDENTIFIER), + 1u64, + &BigUint::from(1u64), + ) + .returns(ExpectError(4, "Wanted address should not be the same as the caller")) + .run(); +} + +#[test] +fn test_fail_accept_offer_non_existent() +{ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state + .world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(1u32) + .returns(ExpectError(4, "Offer does not exist")) + .run(); +} + +#[test] +fn test_fail_accept_unauthorized_acceptance() +{ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(1u32) + .returns(ExpectError(4, "Can not accept this offer")) + .run(); +} + +#[test] +fn test_fail_accept_token_amount_not_1() +{ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + + state + .world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(1u32) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(WANTED_NFT), + 1u64, + &BigUint::from(2u64), + ) + .returns(ExpectError(4, "NFT does not match")) + .run(); +} + +#[test] +fn test_fail_accept_nft_does_not_match_nonce(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + + state + .world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(1u32) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(WANTED_NFT), + 2u64, + &BigUint::from(1u64), + ) + .returns(ExpectError(4, "NFT does not match")) + .run(); +} + +#[test] +fn test_fail_nft_does_not_match_token(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + + state + .world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(1u32) + .egld_or_single_esdt( + &EgldOrEsdtTokenIdentifier::esdt(DIFFERENT_TOKEN), + 1u64, + &BigUint::from(1u64), + ) + .returns(ExpectError(4, "NFT does not match")) + .run(); +} + +#[test] +fn test_cancel_offer_non_existent(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state + .world + .tx() + .from(OWNER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .cancel(1u32) + .returns(ExpectError(4, "Offer does not exist")) + .run(); +} + +#[test] +fn test_cancel_offer_different_address(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + + state + .world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .cancel(1u32) + .returns(ExpectError(4, "Only the offer creator can cancel it")) + .run(); +} + +#[test] +fn test_fail_accept_offer_twice(){ + let mut state = NftEscrowTestState::new(world()); + state.deploy(); + + state.escrow(); + state.accept_offer(1u32); + + state + .world + .tx() + .from(BUYER_ADDRESS) + .to(SC_ADDRESS) + .typed(proxy::NftEscrowContractProxy) + .accept(1u32) + .returns(ExpectError(4, "Offer does not exist")) + .run(); +} diff --git a/contracts/nft-escrow/tests/proxy.rs b/contracts/nft-escrow/tests/proxy.rs new file mode 100644 index 0000000..d7c8461 --- /dev/null +++ b/contracts/nft-escrow/tests/proxy.rs @@ -0,0 +1,186 @@ +// Code generated by the multiversx-sc proxy generator. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +#![allow(dead_code)] +#![allow(clippy::all)] + +use multiversx_sc::proxy_imports::*; + +pub struct NftEscrowContractProxy; + +impl TxProxyTrait for NftEscrowContractProxy +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + type TxProxyMethods = NftEscrowContractProxyMethods; + + fn proxy_methods(self, tx: Tx) -> Self::TxProxyMethods { + NftEscrowContractProxyMethods { wrapped_tx: tx } + } +} + +pub struct NftEscrowContractProxyMethods +where + Env: TxEnv, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + wrapped_tx: Tx, +} + +#[rustfmt::skip] +impl NftEscrowContractProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + Gas: TxGas, +{ + pub fn init( + self, + ) -> TxTypedDeploy { + self.wrapped_tx + .payment(NotPayable) + .raw_deploy() + .original_result() + } +} + +#[rustfmt::skip] +impl NftEscrowContractProxyMethods +where + Env: TxEnv, + Env::Api: VMApi, + From: TxFrom, + To: TxTo, + Gas: TxGas, +{ + pub fn escrow< + Arg0: ProxyArg>, + Arg1: ProxyArg, + Arg2: ProxyArg>, + >( + self, + wanted_nft: Arg0, + wanted_nonce: Arg1, + wanted_address: Arg2, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("escrow") + .argument(&wanted_nft) + .argument(&wanted_nonce) + .argument(&wanted_address) + .original_result() + } + + pub fn cancel< + Arg0: ProxyArg, + >( + self, + offer_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .payment(NotPayable) + .raw_call("cancel") + .argument(&offer_id) + .original_result() + } + + pub fn accept< + Arg0: ProxyArg, + >( + self, + offer_id: Arg0, + ) -> TxTypedCall { + self.wrapped_tx + .raw_call("accept") + .argument(&offer_id) + .original_result() + } + + pub fn get_created_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getCreatedOffers") + .argument(&address) + .original_result() + } + + pub fn get_wanted_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall>>> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("getWantedOffers") + .argument(&address) + .original_result() + } + + pub fn created_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("created_offers") + .argument(&address) + .original_result() + } + + pub fn wanted_offers< + Arg0: ProxyArg>, + >( + self, + address: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("wanted_offers") + .argument(&address) + .original_result() + } + + pub fn offers< + Arg0: ProxyArg, + >( + self, + id: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("offers") + .argument(&id) + .original_result() + } +} + +#[type_abi] +#[derive(TopEncode, TopDecode, Debug)] +pub struct Offer +where + Api: ManagedTypeApi, +{ + pub creator: ManagedAddress, + pub nft: TokenIdentifier, + pub nonce: u64, + pub wanted_nft: TokenIdentifier, + pub wanted_nonce: u64, + pub wanted_address: ManagedAddress, +} diff --git a/contracts/nft-escrow/wasm/Cargo.lock b/contracts/nft-escrow/wasm/Cargo.lock new file mode 100644 index 0000000..be385cd --- /dev/null +++ b/contracts/nft-escrow/wasm/Cargo.lock @@ -0,0 +1,188 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "multiversx-sc" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "236f7890b2208796df8b5ac73b8572ffaf5e2b1531c7ad549d669328b715b657" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcecd449ea708b72f92edaa17158fe4859c1780aed9b52b14de45f26124ccb8b" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f7fa25402e5e8054d719951289306fd79e481f7c21b2565b5549b6bc359772" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb683bc78d0e2eb43c16cac790144f53cc2ab27912aeb1484433895742ce698d" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f0d6be22f911ce45427491a9bec94612a1678eab2769dd08c9c9731d13da53" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nft-escrow" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nft-escrow-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "nft-escrow", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" diff --git a/contracts/nft-escrow/wasm/Cargo.toml b/contracts/nft-escrow/wasm/Cargo.toml new file mode 100644 index 0000000..581b470 --- /dev/null +++ b/contracts/nft-escrow/wasm/Cargo.toml @@ -0,0 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "nft-escrow-wasm" +version = "0.0.0" +edition = "2018" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.nft-escrow] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "0.51.1" + +[workspace] +members = ["."] diff --git a/contracts/nft-escrow/wasm/src/lib.rs b/contracts/nft-escrow/wasm/src/lib.rs new file mode 100644 index 0000000..323a0d7 --- /dev/null +++ b/contracts/nft-escrow/wasm/src/lib.rs @@ -0,0 +1,32 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 8 +// Async Callback (empty): 1 +// Total number of exported functions: 10 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + nft_escrow + ( + init => init + escrow => escrow + cancel => cancel + accept => accept + getCreatedOffers => get_created_offers + getWantedOffers => get_wanted_offers + created_offers => created_offers + wanted_offers => wanted_offers + offers => offers + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {}