From f3b6b429133d79582bb0fe640641d2057212222a Mon Sep 17 00:00:00 2001 From: veeso Date: Tue, 16 Apr 2024 13:37:12 +0200 Subject: [PATCH] fix: integration tests --- Cargo.lock | 1130 ++++++++++++++++- Cargo.toml | 26 +- Makefile.toml | 2 +- dfx.json | 4 +- integration-tests/Cargo.toml | 21 + integration-tests/src/actor.rs | 17 + integration-tests/src/client.rs | 3 + integration-tests/src/client/dip721.rs | 384 ++++++ integration-tests/src/lib.rs | 141 ++ integration-tests/src/wasm.rs | 28 + integration-tests/tests/inspect.rs | 27 + integration-tests/tests/integration_tests.rs | 10 + integration-tests/tests/nft.rs | 86 ++ scripts/deploy_functions.sh | 130 +- scripts/deploy_ic.sh | 54 +- scripts/deploy_local.sh | 20 +- .../dip721-canister/dip721-canister.did | 2 +- .../dip721-canister/dip721-canister.did.d.ts | 2 +- .../dip721-canister/dip721-canister.did.js | 4 +- src/dip721_canister/Cargo.toml | 36 + .../dip721-canister}/dip721-canister.did | 0 .../dip721-canister/dip721-canister.did.d.ts | 131 ++ .../dip721-canister/dip721-canister.did.js | 179 +++ .../declarations/dip721-canister/index.d.ts | 50 + .../declarations/dip721-canister/index.js | 42 + src/dip721_canister/dip721-canister.did | 115 ++ src/{ => dip721_canister/src}/app.rs | 6 +- .../src}/app/configuration.rs | 0 src/{ => dip721_canister/src}/app/inspect.rs | 0 src/{ => dip721_canister/src}/app/memory.rs | 0 src/{ => dip721_canister/src}/app/storage.rs | 0 .../src}/app/storage/tokens.rs | 0 .../src}/app/storage/tx_history.rs | 0 .../src}/app/test_utils.rs | 0 src/{ => dip721_canister/src}/did.rs | 2 +- src/{ => dip721_canister/src}/inspect.rs | 0 src/{ => dip721_canister/src}/lib.rs | 0 src/{ => dip721_canister/src}/storable.rs | 0 src/{ => dip721_canister/src}/utils.rs | 0 39 files changed, 2426 insertions(+), 226 deletions(-) create mode 100644 integration-tests/Cargo.toml create mode 100644 integration-tests/src/actor.rs create mode 100644 integration-tests/src/client.rs create mode 100644 integration-tests/src/client/dip721.rs create mode 100644 integration-tests/src/lib.rs create mode 100644 integration-tests/src/wasm.rs create mode 100644 integration-tests/tests/inspect.rs create mode 100644 integration-tests/tests/integration_tests.rs create mode 100644 integration-tests/tests/nft.rs create mode 100644 src/dip721_canister/Cargo.toml rename src/{ => dip721_canister/declarations/dip721-canister}/dip721-canister.did (100%) create mode 100644 src/dip721_canister/declarations/dip721-canister/dip721-canister.did.d.ts create mode 100644 src/dip721_canister/declarations/dip721-canister/dip721-canister.did.js create mode 100644 src/dip721_canister/declarations/dip721-canister/index.d.ts create mode 100644 src/dip721_canister/declarations/dip721-canister/index.js create mode 100644 src/dip721_canister/dip721-canister.did rename src/{ => dip721_canister/src}/app.rs (99%) rename src/{ => dip721_canister/src}/app/configuration.rs (100%) rename src/{ => dip721_canister/src}/app/inspect.rs (100%) rename src/{ => dip721_canister/src}/app/memory.rs (100%) rename src/{ => dip721_canister/src}/app/storage.rs (100%) rename src/{ => dip721_canister/src}/app/storage/tokens.rs (100%) rename src/{ => dip721_canister/src}/app/storage/tx_history.rs (100%) rename src/{ => dip721_canister/src}/app/test_utils.rs (100%) rename src/{ => dip721_canister/src}/did.rs (91%) rename src/{ => dip721_canister/src}/inspect.rs (100%) rename src/{ => dip721_canister/src}/lib.rs (100%) rename src/{ => dip721_canister/src}/storable.rs (100%) rename src/{ => dip721_canister/src}/utils.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index f6ad0d4..b7191a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "anyhow" version = "1.0.82" @@ -61,6 +70,18 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "binread" version = "2.2.0" @@ -99,6 +120,12 @@ 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" @@ -158,6 +185,22 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[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" @@ -176,6 +219,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-common" version = "0.1.6" @@ -186,12 +244,34 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "diff" version = "0.1.13" @@ -209,7 +289,21 @@ dependencies = [ ] [[package]] -name = "dip721-canister" +name = "dip721-rs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b145a95894c59eb7fb9d094389cb2cfb347db9f9af7f64d015c921c591328969" +dependencies = [ + "async-trait", + "candid", + "ic-cdk", + "ic-stable-structures", + "serde", + "thiserror", +] + +[[package]] +name = "dip721_canister" version = "0.1.0" dependencies = [ "async-trait", @@ -229,18 +323,10 @@ dependencies = [ ] [[package]] -name = "dip721-rs" -version = "0.1.1" +name = "dyn-clone" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a72fae060c9440e7fa227bd053a20474317ed796386630721aca9b6e71446f60" -dependencies = [ - "async-trait", - "candid", - "ic-cdk", - "ic-stable-structures", - "serde", - "thiserror", -] +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "either" @@ -248,6 +334,125 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +[[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 = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[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 2.0.59", +] + +[[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" @@ -275,6 +480,31 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -287,11 +517,83 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "ic-cdk" -version = "0.12.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3d204af0b11c45715169c997858edb58fa8407d08f4fae78a6b415dd39a362" +checksum = "e4ec8231f413b8a4d74b99d7df26d6e917d6528a6245abde27f251210dcf9b72" dependencies = [ "candid", "ic-cdk-macros", @@ -342,6 +644,48 @@ dependencies = [ "thiserror", ] +[[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.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "integration-tests" +version = "0.1.0" +dependencies = [ + "anyhow", + "candid", + "dip721-rs", + "pocket-ic", + "pretty_assertions", + "serde", + "serde_bytes", + "serde_json", + "serial_test", + "tokio", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + [[package]] name = "itertools" version = "0.12.1" @@ -351,6 +695,21 @@ 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 = "lazy_static" version = "1.4.0" @@ -379,12 +738,43 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -405,6 +795,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -417,6 +817,12 @@ dependencies = [ "serde", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" version = "0.1.46" @@ -454,6 +860,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.1" @@ -483,6 +901,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -490,21 +914,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] -name = "pretty" -version = "0.12.3" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" -dependencies = [ - "arrayvec", - "typed-arena", - "unicode-width", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pretty_assertions" -version = "1.4.0" +name = "pocket-ic" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "07c030c06d9d1b3fb0055f41b4b12ecaa5c8e1c60818d2541c3d3e64a9f55ea3" +dependencies = [ + "async-trait", + "base64 0.13.1", + "candid", + "hex", + "ic-cdk", + "reqwest", + "schemars", + "serde", + "serde_bytes", + "serde_json", + "tracing", + "tracing-appender", + "tracing-subscriber", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "pretty" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579" +dependencies = [ + "arrayvec", + "typed-arena", + "unicode-width", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" dependencies = [ "diff", "yansi", @@ -546,24 +1003,198 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "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", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "serde" version = "1.0.197" @@ -593,6 +1224,28 @@ dependencies = [ "syn 2.0.59", ] +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_tokenstream" version = "0.1.7" @@ -604,6 +1257,43 @@ dependencies = [ "syn 1.0.109", ] +[[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 = "serial_test" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ad9342b3aaca7cb43c45c097dd008d4907070394bd0751a0aa8817e5a018d" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93fb4adc70021ac1b47f7d45e8cc4169baaa7ea58483bc5b721d19a26202212" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + [[package]] name = "sha2" version = "0.10.8" @@ -615,6 +1305,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -624,6 +1323,15 @@ dependencies = [ "libc", ] +[[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" @@ -640,6 +1348,12 @@ dependencies = [ "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 = "stacker" version = "0.1.15" @@ -675,6 +1389,33 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags", + "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 = "thiserror" version = "1.0.58" @@ -695,6 +1436,62 @@ dependencies = [ "syn 2.0.59", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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.37.0" @@ -725,6 +1522,128 @@ dependencies = [ "syn 2.0.59", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[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-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.59", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typed-arena" version = "2.0.2" @@ -737,30 +1656,181 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-width" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[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.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 2.0.59", + "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 2.0.59", + "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 = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[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 = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "winapi" version = "0.3.9" @@ -922,6 +1992,16 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "yansi" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 9fb356c..a147315 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,20 +1,16 @@ -[package] -name = "dip721-canister" +[workspace] +members = ["integration-tests", "src/dip721_canister"] +resolver = "2" + +[workspace.package] authors = ["Christian Visintin "] edition = "2021" license = "MIT" readme = "README.md" -repository = "https://github.com/veeso-dev/dip721-template-canister" +repository = "https://github.com/EKOKEtoken/ekoke" version = "0.1.0" -[[bin]] -name = "dip721-canister-did" -path = "src/lib.rs" - -[lib] -crate-type = ["cdylib"] - -[dependencies] +[workspace.dependencies] async-trait = "0.1" candid = "0.10" dip721-rs = "0.1" @@ -28,14 +24,6 @@ num-traits = "0.2" serde = { version = "1", features = ["derive"] } thiserror = "1.0" -[dev-dependencies] -pretty_assertions = "1" -tokio = { version = "1", features = ["full"] } - -[features] -default = [] -did = [] - [profile.dev] debug = false diff --git a/Makefile.toml b/Makefile.toml index accb989..7fdb258 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -56,7 +56,7 @@ workspace = false [tasks.dip721-canister-did] description = "Generate did files for dip721-canister" -script = "cargo run --bin dip721-canister-did --features did > src/dip721-canister.did" +script = "cargo run --bin dip721-canister-did --features did > src/dip721_canister/dip721-canister.did" workspace = false [tasks.dfx-generate] diff --git a/dfx.json b/dfx.json index fb729bf..d778a05 100644 --- a/dfx.json +++ b/dfx.json @@ -1,8 +1,8 @@ { "canisters": { "dip721-canister": { - "candid": "src/dip721-canister.did", - "package": "dip721-canister", + "candid": "src/dip721_canister/dip721-canister.did", + "package": "dip721_canister", "type": "rust" } }, diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml new file mode 100644 index 0000000..b1869f3 --- /dev/null +++ b/integration-tests/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "integration-tests" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } + +[dependencies] +anyhow = "1" +candid = { workspace = true } +dip721-rs = { workspace = true } +pocket-ic = "2" +serde = { workspace = true } +serde_bytes = "0.11" +serde_json = "1" + +[dev-dependencies] +pretty_assertions = "1" +serial_test = "3" +tokio = { version = "1", features = ["full"] } diff --git a/integration-tests/src/actor.rs b/integration-tests/src/actor.rs new file mode 100644 index 0000000..be70d8b --- /dev/null +++ b/integration-tests/src/actor.rs @@ -0,0 +1,17 @@ +use candid::Principal; + +pub fn alice() -> Principal { + Principal::from_text("be2us-64aaa-aaaaa-qaabq-cai").unwrap() +} + +pub fn admin() -> Principal { + Principal::from_text("rrkah-fqaaa-aaaaa-aaaaq-cai").unwrap() +} + +pub fn bob() -> Principal { + Principal::from_text("bs5l3-6b3zu-dpqyj-p2x4a-jyg4k-goneb-afof2-y5d62-skt67-3756q-dqe").unwrap() +} + +pub fn charlie() -> Principal { + Principal::from_text("bkyz2-fmaaa-aaaaa-qaaaq-cai").unwrap() +} diff --git a/integration-tests/src/client.rs b/integration-tests/src/client.rs new file mode 100644 index 0000000..1195385 --- /dev/null +++ b/integration-tests/src/client.rs @@ -0,0 +1,3 @@ +mod dip721; + +pub use dip721::Dip721Client; diff --git a/integration-tests/src/client/dip721.rs b/integration-tests/src/client/dip721.rs new file mode 100644 index 0000000..b139e82 --- /dev/null +++ b/integration-tests/src/client/dip721.rs @@ -0,0 +1,384 @@ +use candid::{Encode, Nat, Principal}; +use dip721_rs::{ + GenericValue, Metadata, NftError, Stats, SupportedInterface, TokenIdentifier, TokenMetadata, + TxEvent, +}; + +use crate::actor::alice; +use crate::TestEnv; + +pub struct Dip721Client<'a> { + pub env: &'a TestEnv, +} + +impl<'a> Dip721Client<'a> { + pub fn new(env: &'a TestEnv) -> Self { + Self { env } + } + + pub fn metadata(&self) -> Metadata { + self.env + .query( + self.env.dip721_id, + alice(), + "metadata", + Encode!(&()).unwrap(), + ) + .expect("query failed") + } + + pub fn stats(&self) -> Stats { + self.env + .query(self.env.dip721_id, alice(), "stats", Encode!(&()).unwrap()) + .expect("query failed") + } + + pub fn logo(&self) -> Option { + self.env + .query(self.env.dip721_id, alice(), "logo", Encode!(&()).unwrap()) + .expect("query failed") + } + + pub fn set_logo(&self, caller: Principal, logo: String) { + self.env + .update( + self.env.dip721_id, + caller, + "set_logo", + Encode!(&logo).unwrap(), + ) + .expect("update failed") + } + + pub fn name(&self) -> Option { + self.env + .query(self.env.dip721_id, alice(), "name", Encode!(&()).unwrap()) + .expect("query failed") + } + + pub fn set_name(&self, caller: Principal, name: String) { + self.env + .update( + self.env.dip721_id, + caller, + "set_name", + Encode!(&name).unwrap(), + ) + .expect("update failed") + } + + pub fn symbol(&self) -> Option { + self.env + .query(self.env.dip721_id, alice(), "symbol", Encode!(&()).unwrap()) + .expect("query failed") + } + + pub fn set_symbol(&self, caller: Principal, symbol: String) { + self.env + .update( + self.env.dip721_id, + caller, + "set_symbol", + Encode!(&symbol).unwrap(), + ) + .expect("update failed") + } + + pub fn custodians(&self) -> Vec { + self.env + .query( + self.env.dip721_id, + alice(), + "custodians", + Encode!(&()).unwrap(), + ) + .expect("query failed") + } + + pub fn set_custodians(&self, caller: Principal, custodians: Vec) { + self.env + .update( + self.env.dip721_id, + caller, + "set_custodians", + Encode!(&(custodians,)).unwrap(), + ) + .expect("update failed") + } + + pub fn cycles(&self) -> Nat { + self.env + .query(self.env.dip721_id, alice(), "cycles", Encode!(&()).unwrap()) + .expect("query failed") + } + + pub fn total_unique_holders(&self) -> Nat { + self.env + .query( + self.env.dip721_id, + alice(), + "total_unique_holders", + Encode!(&()).unwrap(), + ) + .expect("query failed") + } + + pub fn token_metadata( + &self, + token_identifier: TokenIdentifier, + ) -> Result { + self.env + .query( + self.env.dip721_id, + alice(), + "token_metadata", + Encode!(&token_identifier).unwrap(), + ) + .expect("query failed") + } + + pub fn balance_of(&self, owner: Principal) -> Result { + self.env + .query( + self.env.dip721_id, + alice(), + "balance_of", + Encode!(&owner).unwrap(), + ) + .expect("query failed") + } + + pub fn owner_of( + &self, + token_identifier: TokenIdentifier, + ) -> Result, NftError> { + self.env + .query( + self.env.dip721_id, + alice(), + "owner_of", + Encode!(&token_identifier).unwrap(), + ) + .expect("query failed") + } + + pub fn owner_token_identifiers( + &self, + owner: Principal, + ) -> Result, NftError> { + self.env + .query( + self.env.dip721_id, + alice(), + "owner_token_identifiers", + Encode!(&owner).unwrap(), + ) + .expect("query failed") + } + + pub fn owner_token_metadata(&self, owner: Principal) -> Result, NftError> { + self.env + .query( + self.env.dip721_id, + alice(), + "owner_token_metadata", + Encode!(&owner).unwrap(), + ) + .expect("query failed") + } + + pub fn operator_of(&self, owner: Principal) -> Result, NftError> { + self.env + .query( + self.env.dip721_id, + alice(), + "operator_of", + Encode!(&owner).unwrap(), + ) + .expect("query failed") + } + + pub fn operator_token_identifiers( + &self, + operator: Principal, + ) -> Result, NftError> { + self.env + .query( + self.env.dip721_id, + alice(), + "operator_token_identifiers", + Encode!(&operator).unwrap(), + ) + .expect("query failed") + } + + pub fn operator_token_metadata( + &self, + operator: Principal, + ) -> Result, NftError> { + self.env + .query( + self.env.dip721_id, + alice(), + "operator_token_metadata", + Encode!(&operator).unwrap(), + ) + .expect("query failed") + } + + pub fn supported_interfaces(&self) -> Vec { + self.env + .query( + self.env.dip721_id, + alice(), + "supported_interfaces", + Encode!(&()).unwrap(), + ) + .expect("query failed") + } + + pub fn total_supply(&self) -> Nat { + self.env + .query( + self.env.dip721_id, + alice(), + "total_supply", + Encode!(&()).unwrap(), + ) + .expect("query failed") + } + + pub fn approve( + &self, + caller: Principal, + operator: Principal, + token_identifier: TokenIdentifier, + ) -> Result { + self.env + .update( + self.env.dip721_id, + caller, + "approve", + Encode!(&operator, &token_identifier).unwrap(), + ) + .expect("update failed") + } + + pub fn set_approval_for_all( + &self, + caller: Principal, + operator: Principal, + approved: bool, + ) -> Nat { + self.env + .update( + self.env.dip721_id, + caller, + "set_approval_for_all", + Encode!(&(operator, approved)).unwrap(), + ) + .expect("query failed") + } + + pub fn is_approved_for_all( + &self, + owner: Principal, + operator: Principal, + ) -> Result { + self.env + .query( + self.env.dip721_id, + alice(), + "is_approved_for_all", + Encode!(&(owner, operator)).unwrap(), + ) + .expect("query failed") + } + + pub fn transfer( + &self, + caller: Principal, + to: Principal, + token_identifier: TokenIdentifier, + ) -> Result { + self.env + .update( + self.env.dip721_id, + caller, + "transfer", + Encode!(&to, &token_identifier).unwrap(), + ) + .expect("query failed") + } + + pub fn transfer_from( + &self, + caller: Principal, + owner: Principal, + to: Principal, + token_identifier: TokenIdentifier, + ) -> Result { + self.env + .update( + self.env.dip721_id, + caller, + "transfer_from", + Encode!(&owner, &to, &token_identifier).unwrap(), + ) + .expect("query failed") + } + + pub fn mint( + &self, + caller: Principal, + to: Principal, + token_identifier: TokenIdentifier, + properties: Vec<(String, GenericValue)>, + ) -> Result { + self.env + .update( + self.env.dip721_id, + caller, + "mint", + Encode!(&to, &token_identifier, &properties).unwrap(), + ) + .expect("query failed") + } + + pub fn burn( + &self, + caller: Principal, + token_identifier: TokenIdentifier, + ) -> Result { + self.env + .update( + self.env.dip721_id, + caller, + "burn", + Encode!(&token_identifier).unwrap(), + ) + .expect("query failed") + } + + pub fn transaction(&self, tx_id: Nat) -> Result { + self.env + .query( + self.env.dip721_id, + alice(), + "transaction", + Encode!(&tx_id).unwrap(), + ) + .expect("query failed") + } + + pub fn total_transactions(&self) -> Nat { + self.env + .query( + self.env.dip721_id, + alice(), + "total_transactions", + Encode!(&()).unwrap(), + ) + .expect("query failed") + } +} diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs new file mode 100644 index 0000000..219efd8 --- /dev/null +++ b/integration-tests/src/lib.rs @@ -0,0 +1,141 @@ +//! # Integration tests +//! +//! This is a test module that is compiled as a separate crate for testing + +pub mod actor; +pub mod client; +mod wasm; + +use std::io::Read as _; +use std::path::PathBuf; +use std::vec; + +use actor::admin; +use candid::{CandidType, Decode, Encode, Principal}; +use dip721_rs::SupportedInterface; +use pocket_ic::common::rest::SubnetConfigSet; +use pocket_ic::{PocketIc, WasmResult}; +use serde::de::DeserializeOwned; +use wasm::Dip721InitArgs; + +use self::wasm::Canister; + +const DEFAULT_CYCLES: u128 = 2_000_000_000_000_000; + +/// Test environment +pub struct TestEnv { + pub pic: PocketIc, + pub dip721_id: Principal, +} + +impl TestEnv { + pub fn query( + &self, + canister: Principal, + caller: Principal, + method: &str, + payload: Vec, + ) -> anyhow::Result + where + R: DeserializeOwned + CandidType, + { + let result = match self.pic.query_call(canister, caller, method, payload) { + Ok(result) => result, + Err(e) => anyhow::bail!("Error calling {}: {:?}", method, e), + }; + let reply = match result { + WasmResult::Reply(r) => r, + WasmResult::Reject(r) => anyhow::bail!("{} was rejected: {:?}", method, r), + }; + let ret_type = Decode!(&reply, R)?; + + Ok(ret_type) + } + + pub fn update( + &self, + canister: Principal, + caller: Principal, + method: &str, + payload: Vec, + ) -> anyhow::Result + where + R: DeserializeOwned + CandidType, + { + let result = match self.pic.update_call(canister, caller, method, payload) { + Ok(result) => result, + Err(e) => anyhow::bail!("Error calling {}: {:?}", method, e), + }; + + let reply = match result { + WasmResult::Reply(r) => r, + WasmResult::Reject(r) => anyhow::bail!("{} was rejected: {:?}", method, r), + }; + let ret_type = Decode!(&reply, R)?; + + Ok(ret_type) + } + + /// Install the canisters needed for the tests + pub fn init() -> TestEnv { + let config = SubnetConfigSet { + nns: true, + sns: true, + application: 1, + ..Default::default() + }; + let pic = PocketIc::from_config(config); + + // create canisters + let dip721_id = pic.create_canister(); + + // install deferred canister + Self::install_dip721(&pic, dip721_id, "DIP", "DIP721"); + + TestEnv { pic, dip721_id } + } + + fn install_dip721(pic: &PocketIc, id: Principal, symbol: &str, name: &str) { + pic.add_cycles(id, DEFAULT_CYCLES); + let wasm_bytes = Self::load_wasm(Canister::Dip721); + + let init_arg = Dip721InitArgs { + custodians: vec![admin()], + supported_interfaces: vec![ + SupportedInterface::Approval, + SupportedInterface::Burn, + SupportedInterface::Mint, + SupportedInterface::TransactionHistory, + ], + symbol: symbol.to_string(), + name: name.to_string(), + logo: None, + }; + let init_arg = Encode!(&init_arg).unwrap(); + + pic.install_canister(id, wasm_bytes, init_arg, None); + } + + fn load_wasm(canister: Canister) -> Vec { + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push(canister.as_path()); + + let mut file = std::fs::File::open(path).unwrap(); + let mut wasm_bytes = Vec::new(); + file.read_to_end(&mut wasm_bytes).unwrap(); + + wasm_bytes + } +} + +impl Drop for TestEnv { + fn drop(&mut self) { + // NOTE: execute test one by one + for tempdir in std::fs::read_dir(std::path::Path::new("/tmp")).unwrap() { + let tempdir = tempdir.unwrap(); + if tempdir.file_name().to_string_lossy().starts_with(".tmp") { + std::fs::remove_dir_all(tempdir.path()).unwrap(); + } + } + } +} diff --git a/integration-tests/src/wasm.rs b/integration-tests/src/wasm.rs new file mode 100644 index 0000000..cd3263a --- /dev/null +++ b/integration-tests/src/wasm.rs @@ -0,0 +1,28 @@ +use std::path::Path; + +use candid::{CandidType, Principal}; +use dip721_rs::SupportedInterface; +use serde::Deserialize; + +#[derive(Debug, Clone, CandidType, Deserialize)] +pub struct Dip721InitArgs { + pub custodians: Vec, + pub supported_interfaces: Vec, + pub name: String, + pub symbol: String, + pub logo: Option, +} + +pub enum Canister { + Dip721, +} + +impl Canister { + pub fn as_path(&self) -> &'static Path { + match self { + Canister::Dip721 => { + Path::new("../.dfx/local/canisters/dip721-canister/dip721-canister.wasm") + } + } + } +} diff --git a/integration-tests/tests/inspect.rs b/integration-tests/tests/inspect.rs new file mode 100644 index 0000000..d7775e5 --- /dev/null +++ b/integration-tests/tests/inspect.rs @@ -0,0 +1,27 @@ +use candid::Encode; +use integration_tests::actor::{admin, alice}; +use integration_tests::TestEnv; + +#[test] +#[serial_test::serial] +fn test_should_inspect_is_custodian() { + let env = TestEnv::init(); + + assert!(env + .update::<()>( + env.dip721_id, + admin(), + "set_name", + Encode!(&"test").unwrap() + ) + .is_ok()); + + assert!(env + .update::<()>( + env.dip721_id, + alice(), + "set_name", + Encode!(&"test").unwrap() + ) + .is_err()); +} diff --git a/integration-tests/tests/integration_tests.rs b/integration-tests/tests/integration_tests.rs new file mode 100644 index 0000000..f130855 --- /dev/null +++ b/integration-tests/tests/integration_tests.rs @@ -0,0 +1,10 @@ +mod inspect; +mod nft; + +use integration_tests::TestEnv; + +#[test] +#[serial_test::serial] +fn test_should_install_canisters() { + TestEnv::init(); +} diff --git a/integration-tests/tests/nft.rs b/integration-tests/tests/nft.rs new file mode 100644 index 0000000..adf0f05 --- /dev/null +++ b/integration-tests/tests/nft.rs @@ -0,0 +1,86 @@ +use integration_tests::actor::{admin, alice, bob}; +use integration_tests::client::Dip721Client; +use integration_tests::TestEnv; + +#[test] +#[serial_test::serial] +fn test_should_mint() { + let env = TestEnv::init(); + let client = Dip721Client::new(&env); + + assert!(client.mint(admin(), alice(), 1_u64.into(), vec![]).is_ok()); + + let token = client.token_metadata(1u64.into()).unwrap(); + assert_eq!(token.owner, Some(alice())); +} + +#[test] +#[serial_test::serial] +fn test_should_transfer() { + let env = TestEnv::init(); + let client = Dip721Client::new(&env); + + assert!(client.mint(admin(), admin(), 1_u64.into(), vec![]).is_ok()); + + assert!(client.transfer(admin(), alice(), 1_u64.into()).is_ok()); + let token = client.token_metadata(1u64.into()).unwrap(); + assert_eq!(token.owner, Some(alice())); +} + +#[test] +#[serial_test::serial] +fn test_should_not_allow_transfer() { + let env = TestEnv::init(); + let client = Dip721Client::new(&env); + + assert!(client.mint(admin(), admin(), 1_u64.into(), vec![]).is_ok()); + + assert!(client.transfer(alice(), alice(), 1_u64.into()).is_err()); +} + +#[test] +#[serial_test::serial] +fn test_should_approve_transfer_from() { + let env = TestEnv::init(); + let client = Dip721Client::new(&env); + + assert!(client.mint(admin(), admin(), 1_u64.into(), vec![]).is_ok()); + + assert!(client.approve(admin(), bob(), 1_u64.into()).is_ok()); + + let token = client.token_metadata(1u64.into()).unwrap(); + assert_eq!(token.operator, Some(bob())); + + assert!(client + .transfer_from(bob(), admin(), alice(), 1_u64.into()) + .is_ok()); + let token = client.token_metadata(1u64.into()).unwrap(); + assert_eq!(token.owner, Some(alice())); +} + +#[test] +#[serial_test::serial] +#[should_panic] +fn test_should_not_approve_transfer_from() { + let env = TestEnv::init(); + let client = Dip721Client::new(&env); + + assert!(client.mint(admin(), admin(), 1_u64.into(), vec![]).is_ok()); + + assert!(client.approve(bob(), bob(), 1_u64.into()).is_err()); +} + +#[test] +#[serial_test::serial] +fn test_should_burn() { + let env = TestEnv::init(); + let client = Dip721Client::new(&env); + + assert!(client.mint(admin(), admin(), 1_u64.into(), vec![]).is_ok()); + + assert!(client.burn(admin(), 1_u64.into()).is_ok()); + + let token = client.token_metadata(1u64.into()).unwrap(); + + assert!(token.is_burned); +} diff --git a/scripts/deploy_functions.sh b/scripts/deploy_functions.sh index b7b9f3d..664f74d 100644 --- a/scripts/deploy_functions.sh +++ b/scripts/deploy_functions.sh @@ -2,124 +2,32 @@ set -e -deploy_deferred() { +deploy_dip721() { INSTALL_MODE="$1" NETWORK="$2" - DEFERRED_PRINCIPAL="$3" - EKOKE_REWARD_POOL_PRINCIPAL="$4" - MARKETPLACE_PRINCIPAL="$5" - ADMIN_PRINCIPAL="$6" + ADMIN_PRINCIPAL="$3" + SUPPORTED_INTERFACES="$4" + NAME="$5" + SYMBOL="$6" + LOGO="$7" - echo "deploying deferred canister $DEFERRED_PRINCIPAL" + echo "deploying dip721 canister" - deferred_init_args="(record { - ekoke_reward_pool_canister = principal \"$EKOKE_REWARD_POOL_PRINCIPAL\"; - marketplace_canister = principal \"$MARKETPLACE_PRINCIPAL\"; - custodians = vec { principal \"$ADMIN_PRINCIPAL\" }; - })" - - dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$deferred_init_args" deferred - -} - -deploy_ekoke_erc20_swap() { - INSTALL_MODE="$1" - NETWORK="$2" - EKOKE_ERC20_SWAP_PRINCIPAL="$3" - ADMINS="$4" - EKOKE_LEDGER_PRINCIPAL="$5" - ERC20_BRIDGE_ADDRESS="$6" - ERC20_SWAP_FEE="$7" - ERC20_NETWORK="$8" - - echo "deploying ekoke-erc20-swap canister $EKOKE_ERC20_SWAP_PRINCIPAL" - - ekoke_erc20_swap_init_args="(record { - admins = vec { $(for admin in $ADMINS; do echo "principal \"$admin\";"; done) }; - ledger_id = principal \"$EKOKE_LEDGER_PRINCIPAL\"; - cketh_minter_canister = principal \"sv3dd-oaaaa-aaaar-qacoa-cai\"; - cketh_ledger_canister = principal \"ss2fx-dyaaa-aaaar-qacoq-cai\"; - erc20_bridge_address = \"$ERC20_BRIDGE_ADDRESS\"; - erc20_gas_price = $ERC20_SWAP_FEE; - erc20_network = variant { $ERC20_NETWORK }; - })" - - dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$ekoke_erc20_swap_init_args" ekoke-erc20-swap -} - -deploy_ekoke_erc20_swap_frontend() { - INSTALL_MODE="$1" - NETWORK="$2" - - echo "deploying ekoke-erc20-swap-frontend canister" - - dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" ekoke-erc20-swap-frontend -} - -deploy_ekoke_reward_pool() { - INSTALL_MODE="$1" - NETWORK="$2" - EKOKE_REWARD_POOL_PRINCIPAL="$3" - ADMINS="$4" - EKOKE_LEDGER_PRINCIPAL="$5" - DEFERRED_PRINCIPAL="$6" - MARKETPLACE_PRINCIPAL="$7" - - echo "deploying ekoke-reward-pool canister $EKOKE_REWARD_POOL_PRINCIPAL" - - ekoke_init_args="(record { - deferred_canister = principal \"$DEFERRED_PRINCIPAL\"; - marketplace_canister = principal \"$MARKETPLACE_PRINCIPAL\"; - admins = vec { $(for admin in $ADMINS; do echo "principal \"$admin\";"; done) }; - ledger_canister = principal \"$EKOKE_LEDGER_PRINCIPAL\"; - })" - - dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$ekoke_init_args" ekoke-reward-pool - -} - -deploy_ekoke_liquidity_pool() { - INSTALL_MODE="$1" - NETWORK="$2" - EKOKE_LIQUIDITY_POOL_PRINCIPAL="$3" - ADMINS="$4" - SWAP_ACCOUNT="$5" - - echo "deploying ekoke-liquidity-pool canister $EKOKE_LIQUIDITY_POOL_PRINCIPAL" - - ekoke_liquidity_pool_init_args="(record { - swap_account = $SWAP_ACCOUNT; - admins = vec { $(for admin in $ADMINS; do echo "principal \"$admin\";"; done) }; - ckbtc_canister = principal \"mxzaz-hqaaa-aaaar-qaada-cai\"; - icp_ledger_canister = principal \"ryjl3-tyaaa-aaaaa-aaaba-cai\"; - xrc_canister = principal \"uf6dk-hyaaa-aaaaq-qaaaq-cai\"; - })" - - dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$ekoke_liquidity_pool_init_args" ekoke-liquidity-pool - -} - -deploy_marketplace() { - INSTALL_MODE="$1" - NETWORK="$2" - MARKETPLACE_PRINCIPAL="$3" - DEFERRED_PRINCIPAL="$4" - EKOKE_REWARD_POOL_PRINCIPAL="$5" - ADMINS="$6" - EKOKE_LIQUIDITY_POOL_PRINCIPAL="$7" - - echo "deploying marketplace canister $MARKETPLACE_PRINCIPAL" + if [ -z "$LOGO" ]; then + LOGO="null" + else + LOGO="\"$LOGO\"" + fi - marketplace_init_args="(record { - deferred_canister = principal \"$DEFERRED_PRINCIPAL\"; - ekoke_reward_pool_canister = principal \"$EKOKE_REWARD_POOL_PRINCIPAL\"; - ekoke_liquidity_pool_canister = principal \"$EKOKE_LIQUIDITY_POOL_PRINCIPAL\"; - xrc_canister = principal \"uf6dk-hyaaa-aaaaq-qaaaq-cai\"; - admins = vec { $(for admin in $ADMINS; do echo "principal \"$admin\";"; done) }; - icp_ledger_canister = principal \"ryjl3-tyaaa-aaaaa-aaaba-cai\"; + init_args="(record { + supported_interfaces = vec { $(for interface in $SUPPORTED_INTERFACES; do echo "variant { $interface }"; done) }; + custodians = vec { principal \"$ADMIN_PRINCIPAL\" }; + logo = $LOGO; + name = \"$NAME\"; + symbol = \"$SYMBOL\"; })" - dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$marketplace_init_args" marketplace + dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$init_args" dip721-canister } get_arg() { diff --git a/scripts/deploy_ic.sh b/scripts/deploy_ic.sh index 296c121..04aa60f 100755 --- a/scripts/deploy_ic.sh +++ b/scripts/deploy_ic.sh @@ -6,22 +6,14 @@ source ./deploy_functions.sh source ./did.sh ADMIN_PRINCIPAL="$(dfx identity get-principal)" -SWAP_ACCOUNT="$(account "$ADMIN_PRINCIPAL")" -ERC20_BRIDGE_ADDRESS="0xc08e14F47382BCc1dA6c3Ff366018cAb1c77091F" -ERC20_SWAP_FEE="231634000000000" -ERC20_NETWORK="Ethereum" -FALLBACK_CANISTER="$ADMIN_PRINCIPAL" +SUPPORTED_INTERFACES="Mint Burn Approval TransactionHistory" CANISTER="$1" if [ -z "$CANISTER" ]; then echo "Please provide the canister name as an argument" echo "Available canisters:" - echo "- deferred" - echo "- ekoke-erc20-swap" - echo "- ekoke-liquidity-pool" - echo "- ekoke-reward-pool" - echo "- marketplace" + echo "- dip721" exit 1 fi @@ -32,47 +24,17 @@ cd ../ case "$CANISTER" in - "deferred") - EKOKE_REWARD_POOL_PRINCIPAL=$(get_arg "ekoke-reward-pool" "$FALLBACK_CANISTER") - MARKETPLACE_PRINCIPAL=$(get_arg "marketplace" "$FALLBACK_CANISTER") - deploy_deferred "reinstall" "ic" "$DEFERRED_PRINCIPAL" "$EKOKE_REWARD_POOL_PRINCIPAL" "$MARKETPLACE_PRINCIPAL" "$ADMIN_PRINCIPAL" + "dip721") + NAME=$(get_arg "name" "DIP721") + SYMBOL=$(get_arg "symbol" "DIP") + LOGO=$(get_arg "logo") + deploy_deferred "reinstall" "ic" "$ADMIN_PRINCIPAL" "$SUPPORTED_INTERFACES" "$NAME" "$SYMBOL" "$LOGO" ;; - "ekoke-erc20-swap") - EKOKE_LEDGER_PRINCIPAL=$(get_arg "ekoke-ledger" "$FALLBACK_CANISTER") - deploy_ekoke_erc20_swap "reinstall" "ic" "$EKOKE_ERC20_SWAP_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LEDGER_PRINCIPAL" "$ERC20_BRIDGE_ADDRESS" "$ERC20_SWAP_FEE" "$ERC20_NETWORK" - ;; - - "ekoke-erc20-swap-frontend") - deploy_ekoke_erc20_swap_frontend "reinstall" "ic" - ;; - - "ekoke-liquidity-pool") - deploy_ekoke_liquidity_pool "reinstall" "ic" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$SWAP_ACCOUNT" - ;; - - "ekoke-reward-pool") - EKOKE_LEDGER_PRINCIPAL=$(get_arg "ekoke-ledger" "$FALLBACK_CANISTER") - DEFERRED_PRINCIPAL=$(get_arg "deferred" "$FALLBACK_CANISTER") - MARKETPLACE_PRINCIPAL=$(get_arg "marketplace" "$FALLBACK_CANISTER") - deploy_ekoke_reward_pool "reinstall" "ic" "$EKOKE_REWARD_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LEDGER_PRINCIPAL" "$DEFERRED_PRINCIPAL" "$MARKETPLACE_PRINCIPAL" - ;; - - "marketplace") - DEFERRED_PRINCIPAL=$(get_arg "deferred" "$FALLBACK_CANISTER") - EKOKE_REWARD_POOL_PRINCIPAL=$(get_arg "ekoke-reward-pool" "$FALLBACK_CANISTER") - EKOKE_LIQUIDITY_POOL_PRINCIPAL=$(get_arg "ekoke-liquidity-pool" "$FALLBACK_CANISTER") - deploy_marketplace "reinstall" "ic" "$MARKETPLACE_PRINCIPAL" "$DEFERRED_PRINCIPAL" "$EKOKE_REWARD_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" - ;; - *) echo "Invalid canister name" echo "Available canisters:" - echo "- deferred" - echo "- ekoke-erc20-swap" - echo "- ekoke-liquidity-pool" - echo "- ekoke-reward-pool" - echo "- marketplace" + echo "- dip721" exit 1 ;; diff --git a/scripts/deploy_local.sh b/scripts/deploy_local.sh index 778bad1..e474a56 100755 --- a/scripts/deploy_local.sh +++ b/scripts/deploy_local.sh @@ -3,21 +3,15 @@ cd "$(dirname "$0")" || exit 1 CANISTER_IDS="../.dfx/local/canister_ids.json" -DEFERRED_PRINCIPAL="$(cat "$CANISTER_IDS" | jq -r '.deferred.local')" -EKOKE_ERC20_SWAP_PRINCIPAL=$(cat "$CANISTER_IDS" | jq -r '."ekoke-erc20-swap".local') -EKOKE_LEDGER_PRINCIPAL=$(cat "$CANISTER_IDS" | jq -r '."sns_ledger".local') -EKOKE_LIQUIDITY_POOL_PRINCIPAL=$(cat "$CANISTER_IDS" | jq -r '."ekoke-liquidity-pool".local') -EKOKE_REWARD_POOL_PRINCIPAL=$(cat "$CANISTER_IDS" | jq -r '."ekoke-reward-pool".local') -MARKETPLACE_PRINCIPAL="$(cat "$CANISTER_IDS" | jq -r '.marketplace.local')" +DIP721_PRINCIPAL="$(cat "$CANISTER_IDS" | jq -r '.dip721-canister.local')" +SUPPORTED_INTERFACES="Mint Burn Approval TransactionHistory" +NAME="DIP721" +SYMBOL="DIP" source ./deploy_functions.sh source ./did.sh ADMIN_PRINCIPAL="$(dfx identity get-principal)" -SWAP_ACCOUNT="$(account "$ADMIN_PRINCIPAL")" -ERC20_BRIDGE_ADDRESS="0xc08e14F47382BCc1dA6c3Ff366018cAb1c77091F" -ERC20_SWAP_FEE="231634000000000" -ERC20_NETWORK="Sepolia" dfx stop dfx start --background @@ -26,11 +20,7 @@ cd ../ set -e -deploy_deferred "reinstall" "local" "$DEFERRED_PRINCIPAL" "$EKOKE_REWARD_POOL_PRINCIPAL" "$MARKETPLACE_PRINCIPAL" "$ADMIN_PRINCIPAL" -deploy_ekoke_erc20_swap "reinstall" "local" "$EKOKE_ERC20_SWAP_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LEDGER_PRINCIPAL" "$ERC20_BRIDGE_ADDRESS" "$ERC20_SWAP_FEE" "$ERC20_NETWORK" -deploy_ekoke_liquidity_pool "reinstall" "local" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$SWAP_ACCOUNT" -deploy_ekoke_reward_pool "reinstall" "local" "$EKOKE_REWARD_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LEDGER_PRINCIPAL" "$DEFERRED_PRINCIPAL" "$MARKETPLACE_PRINCIPAL" -deploy_marketplace "reinstall" "local" "$MARKETPLACE_PRINCIPAL" "$DEFERRED_PRINCIPAL" "$EKOKE_REWARD_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" +deploy_dip721 "reinstall" "local" "$DEFERRED_PRINCIPAL" "$SUPPORTED_INTERFACES" "$NAME" "$SYMBOL" set +e diff --git a/src/declarations/dip721-canister/dip721-canister.did b/src/declarations/dip721-canister/dip721-canister.did index 1e832d2..f01cad5 100644 --- a/src/declarations/dip721-canister/dip721-canister.did +++ b/src/declarations/dip721-canister/dip721-canister.did @@ -1,5 +1,5 @@ type CanisterInitData = record { - logo : text; + logo : opt text; name : text; custodians : vec principal; symbol : text; diff --git a/src/declarations/dip721-canister/dip721-canister.did.d.ts b/src/declarations/dip721-canister/dip721-canister.did.d.ts index ce3b610..a5c2098 100644 --- a/src/declarations/dip721-canister/dip721-canister.did.d.ts +++ b/src/declarations/dip721-canister/dip721-canister.did.d.ts @@ -3,7 +3,7 @@ import type { ActorMethod } from '@dfinity/agent'; import type { IDL } from '@dfinity/candid'; export interface CanisterInitData { - 'logo' : string, + 'logo' : [] | [string], 'name' : string, 'custodians' : Array, 'symbol' : string, diff --git a/src/declarations/dip721-canister/dip721-canister.did.js b/src/declarations/dip721-canister/dip721-canister.did.js index 3ce037c..0e000b3 100644 --- a/src/declarations/dip721-canister/dip721-canister.did.js +++ b/src/declarations/dip721-canister/dip721-canister.did.js @@ -7,7 +7,7 @@ export const idlFactory = ({ IDL }) => { 'TransactionHistory' : IDL.Null, }); const CanisterInitData = IDL.Record({ - 'logo' : IDL.Text, + 'logo' : IDL.Opt(IDL.Text), 'name' : IDL.Text, 'custodians' : IDL.Vec(IDL.Principal), 'symbol' : IDL.Text, @@ -169,7 +169,7 @@ export const init = ({ IDL }) => { 'TransactionHistory' : IDL.Null, }); const CanisterInitData = IDL.Record({ - 'logo' : IDL.Text, + 'logo' : IDL.Opt(IDL.Text), 'name' : IDL.Text, 'custodians' : IDL.Vec(IDL.Principal), 'symbol' : IDL.Text, diff --git a/src/dip721_canister/Cargo.toml b/src/dip721_canister/Cargo.toml new file mode 100644 index 0000000..4bfad45 --- /dev/null +++ b/src/dip721_canister/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "dip721_canister" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } + +[[bin]] +name = "dip721-canister-did" +path = "src/lib.rs" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +async-trait = { workspace = true } +candid = { workspace = true } +dip721-rs = { workspace = true } +getrandom = { workspace = true } +ic-cdk = { workspace = true } +ic-cdk-macros = { workspace = true } +ic-stable-structures = { workspace = true } +itertools = { workspace = true } +num-bigint = { workspace = true } +num-traits = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } + +[dev-dependencies] +pretty_assertions = "1" +tokio = { version = "1", features = ["full"] } + +[features] +default = [] +did = [] diff --git a/src/dip721-canister.did b/src/dip721_canister/declarations/dip721-canister/dip721-canister.did similarity index 100% rename from src/dip721-canister.did rename to src/dip721_canister/declarations/dip721-canister/dip721-canister.did diff --git a/src/dip721_canister/declarations/dip721-canister/dip721-canister.did.d.ts b/src/dip721_canister/declarations/dip721-canister/dip721-canister.did.d.ts new file mode 100644 index 0000000..ce3b610 --- /dev/null +++ b/src/dip721_canister/declarations/dip721-canister/dip721-canister.did.d.ts @@ -0,0 +1,131 @@ +import type { Principal } from '@dfinity/principal'; +import type { ActorMethod } from '@dfinity/agent'; +import type { IDL } from '@dfinity/candid'; + +export interface CanisterInitData { + 'logo' : string, + 'name' : string, + 'custodians' : Array, + 'symbol' : string, + 'supported_interfaces' : Array, +} +export type GenericValue = { 'Nat64Content' : bigint } | + { 'Nat32Content' : number } | + { 'BoolContent' : boolean } | + { 'Nat8Content' : number } | + { 'Int64Content' : bigint } | + { 'IntContent' : bigint } | + { 'NatContent' : bigint } | + { 'Nat16Content' : number } | + { 'Int32Content' : number } | + { 'Int8Content' : number } | + { 'FloatContent' : number } | + { 'Int16Content' : number } | + { 'BlobContent' : Uint8Array | number[] } | + { 'NestedContent' : Array<[string, GenericValue]> } | + { 'Principal' : Principal } | + { 'TextContent' : string }; +export interface Metadata { + 'logo' : [] | [string], + 'name' : [] | [string], + 'created_at' : bigint, + 'upgraded_at' : bigint, + 'custodians' : Array, + 'symbol' : [] | [string], +} +export type NftError = { 'UnauthorizedOperator' : null } | + { 'SelfTransfer' : null } | + { 'TokenNotFound' : null } | + { 'UnauthorizedOwner' : null } | + { 'TxNotFound' : null } | + { 'SelfApprove' : null } | + { 'OperatorNotFound' : null } | + { 'ExistedNFT' : null } | + { 'OwnerNotFound' : null } | + { 'Other' : string }; +export type Result = { 'Ok' : bigint } | + { 'Err' : NftError }; +export type Result_1 = { 'Ok' : boolean } | + { 'Err' : NftError }; +export type Result_2 = { 'Ok' : [] | [Principal] } | + { 'Err' : NftError }; +export type Result_3 = { 'Ok' : Array } | + { 'Err' : NftError }; +export type Result_4 = { 'Ok' : Array } | + { 'Err' : NftError }; +export type Result_5 = { 'Ok' : null } | + { 'Err' : NftError }; +export type Result_6 = { 'Ok' : TokenMetadata } | + { 'Err' : NftError }; +export type Result_7 = { 'Ok' : TxEvent } | + { 'Err' : NftError }; +export interface Stats { + 'cycles' : bigint, + 'total_transactions' : bigint, + 'total_unique_holders' : bigint, + 'total_supply' : bigint, +} +export type SupportedInterface = { 'Burn' : null } | + { 'Mint' : null } | + { 'Approval' : null } | + { 'TransactionHistory' : null }; +export interface TokenMetadata { + 'transferred_at' : [] | [bigint], + 'transferred_by' : [] | [Principal], + 'owner' : [] | [Principal], + 'operator' : [] | [Principal], + 'approved_at' : [] | [bigint], + 'approved_by' : [] | [Principal], + 'properties' : Array<[string, GenericValue]>, + 'is_burned' : boolean, + 'token_identifier' : bigint, + 'burned_at' : [] | [bigint], + 'burned_by' : [] | [Principal], + 'minted_at' : bigint, + 'minted_by' : Principal, +} +export interface TxEvent { + 'time' : bigint, + 'operation' : string, + 'details' : Array<[string, GenericValue]>, + 'caller' : Principal, +} +export interface _SERVICE { + 'approve' : ActorMethod<[Principal, bigint], Result>, + 'balance_of' : ActorMethod<[Principal], Result>, + 'burn' : ActorMethod<[bigint], Result>, + 'custodians' : ActorMethod<[], Array>, + 'cycles' : ActorMethod<[], bigint>, + 'is_approved_for_all' : ActorMethod<[Principal, Principal], Result_1>, + 'logo' : ActorMethod<[], [] | [string]>, + 'metadata' : ActorMethod<[], Metadata>, + 'mint' : ActorMethod< + [Principal, bigint, Array<[string, GenericValue]>], + Result + >, + 'name' : ActorMethod<[], [] | [string]>, + 'operator_of' : ActorMethod<[bigint], Result_2>, + 'operator_token_identifiers' : ActorMethod<[Principal], Result_3>, + 'operator_token_metadata' : ActorMethod<[Principal], Result_4>, + 'owner_of' : ActorMethod<[bigint], Result_2>, + 'owner_token_identifiers' : ActorMethod<[Principal], Result_3>, + 'owner_token_metadata' : ActorMethod<[Principal], Result_4>, + 'set_approval_for_all' : ActorMethod<[Principal, boolean], Result>, + 'set_custodians' : ActorMethod<[Array], undefined>, + 'set_logo' : ActorMethod<[string], undefined>, + 'set_name' : ActorMethod<[string], undefined>, + 'set_symbol' : ActorMethod<[string], undefined>, + 'set_token_property' : ActorMethod<[bigint, string, GenericValue], Result_5>, + 'stats' : ActorMethod<[], Stats>, + 'supported_interfaces' : ActorMethod<[], Array>, + 'symbol' : ActorMethod<[], [] | [string]>, + 'token_metadata' : ActorMethod<[bigint], Result_6>, + 'total_supply' : ActorMethod<[], bigint>, + 'total_transactions' : ActorMethod<[], bigint>, + 'total_unique_holders' : ActorMethod<[], bigint>, + 'transaction' : ActorMethod<[bigint], Result_7>, + 'transfer' : ActorMethod<[Principal, bigint], Result>, + 'transfer_from' : ActorMethod<[Principal, Principal, bigint], Result>, +} +export declare const idlFactory: IDL.InterfaceFactory; +export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[]; diff --git a/src/dip721_canister/declarations/dip721-canister/dip721-canister.did.js b/src/dip721_canister/declarations/dip721-canister/dip721-canister.did.js new file mode 100644 index 0000000..3ce037c --- /dev/null +++ b/src/dip721_canister/declarations/dip721-canister/dip721-canister.did.js @@ -0,0 +1,179 @@ +export const idlFactory = ({ IDL }) => { + const GenericValue = IDL.Rec(); + const SupportedInterface = IDL.Variant({ + 'Burn' : IDL.Null, + 'Mint' : IDL.Null, + 'Approval' : IDL.Null, + 'TransactionHistory' : IDL.Null, + }); + const CanisterInitData = IDL.Record({ + 'logo' : IDL.Text, + 'name' : IDL.Text, + 'custodians' : IDL.Vec(IDL.Principal), + 'symbol' : IDL.Text, + 'supported_interfaces' : IDL.Vec(SupportedInterface), + }); + const NftError = IDL.Variant({ + 'UnauthorizedOperator' : IDL.Null, + 'SelfTransfer' : IDL.Null, + 'TokenNotFound' : IDL.Null, + 'UnauthorizedOwner' : IDL.Null, + 'TxNotFound' : IDL.Null, + 'SelfApprove' : IDL.Null, + 'OperatorNotFound' : IDL.Null, + 'ExistedNFT' : IDL.Null, + 'OwnerNotFound' : IDL.Null, + 'Other' : IDL.Text, + }); + const Result = IDL.Variant({ 'Ok' : IDL.Nat, 'Err' : NftError }); + const Result_1 = IDL.Variant({ 'Ok' : IDL.Bool, 'Err' : NftError }); + const Metadata = IDL.Record({ + 'logo' : IDL.Opt(IDL.Text), + 'name' : IDL.Opt(IDL.Text), + 'created_at' : IDL.Nat64, + 'upgraded_at' : IDL.Nat64, + 'custodians' : IDL.Vec(IDL.Principal), + 'symbol' : IDL.Opt(IDL.Text), + }); + GenericValue.fill( + IDL.Variant({ + 'Nat64Content' : IDL.Nat64, + 'Nat32Content' : IDL.Nat32, + 'BoolContent' : IDL.Bool, + 'Nat8Content' : IDL.Nat8, + 'Int64Content' : IDL.Int64, + 'IntContent' : IDL.Int, + 'NatContent' : IDL.Nat, + 'Nat16Content' : IDL.Nat16, + 'Int32Content' : IDL.Int32, + 'Int8Content' : IDL.Int8, + 'FloatContent' : IDL.Float64, + 'Int16Content' : IDL.Int16, + 'BlobContent' : IDL.Vec(IDL.Nat8), + 'NestedContent' : IDL.Vec(IDL.Tuple(IDL.Text, GenericValue)), + 'Principal' : IDL.Principal, + 'TextContent' : IDL.Text, + }) + ); + const Result_2 = IDL.Variant({ + 'Ok' : IDL.Opt(IDL.Principal), + 'Err' : NftError, + }); + const Result_3 = IDL.Variant({ 'Ok' : IDL.Vec(IDL.Nat), 'Err' : NftError }); + const TokenMetadata = IDL.Record({ + 'transferred_at' : IDL.Opt(IDL.Nat64), + 'transferred_by' : IDL.Opt(IDL.Principal), + 'owner' : IDL.Opt(IDL.Principal), + 'operator' : IDL.Opt(IDL.Principal), + 'approved_at' : IDL.Opt(IDL.Nat64), + 'approved_by' : IDL.Opt(IDL.Principal), + 'properties' : IDL.Vec(IDL.Tuple(IDL.Text, GenericValue)), + 'is_burned' : IDL.Bool, + 'token_identifier' : IDL.Nat, + 'burned_at' : IDL.Opt(IDL.Nat64), + 'burned_by' : IDL.Opt(IDL.Principal), + 'minted_at' : IDL.Nat64, + 'minted_by' : IDL.Principal, + }); + const Result_4 = IDL.Variant({ + 'Ok' : IDL.Vec(TokenMetadata), + 'Err' : NftError, + }); + const Result_5 = IDL.Variant({ 'Ok' : IDL.Null, 'Err' : NftError }); + const Stats = IDL.Record({ + 'cycles' : IDL.Nat, + 'total_transactions' : IDL.Nat, + 'total_unique_holders' : IDL.Nat, + 'total_supply' : IDL.Nat, + }); + const Result_6 = IDL.Variant({ 'Ok' : TokenMetadata, 'Err' : NftError }); + const TxEvent = IDL.Record({ + 'time' : IDL.Nat64, + 'operation' : IDL.Text, + 'details' : IDL.Vec(IDL.Tuple(IDL.Text, GenericValue)), + 'caller' : IDL.Principal, + }); + const Result_7 = IDL.Variant({ 'Ok' : TxEvent, 'Err' : NftError }); + return IDL.Service({ + 'approve' : IDL.Func([IDL.Principal, IDL.Nat], [Result], []), + 'balance_of' : IDL.Func([IDL.Principal], [Result], ['query']), + 'burn' : IDL.Func([IDL.Nat], [Result], []), + 'custodians' : IDL.Func([], [IDL.Vec(IDL.Principal)], ['query']), + 'cycles' : IDL.Func([], [IDL.Nat], ['query']), + 'is_approved_for_all' : IDL.Func( + [IDL.Principal, IDL.Principal], + [Result_1], + [], + ), + 'logo' : IDL.Func([], [IDL.Opt(IDL.Text)], ['query']), + 'metadata' : IDL.Func([], [Metadata], ['query']), + 'mint' : IDL.Func( + [IDL.Principal, IDL.Nat, IDL.Vec(IDL.Tuple(IDL.Text, GenericValue))], + [Result], + [], + ), + 'name' : IDL.Func([], [IDL.Opt(IDL.Text)], ['query']), + 'operator_of' : IDL.Func([IDL.Nat], [Result_2], ['query']), + 'operator_token_identifiers' : IDL.Func( + [IDL.Principal], + [Result_3], + ['query'], + ), + 'operator_token_metadata' : IDL.Func( + [IDL.Principal], + [Result_4], + ['query'], + ), + 'owner_of' : IDL.Func([IDL.Nat], [Result_2], ['query']), + 'owner_token_identifiers' : IDL.Func( + [IDL.Principal], + [Result_3], + ['query'], + ), + 'owner_token_metadata' : IDL.Func([IDL.Principal], [Result_4], ['query']), + 'set_approval_for_all' : IDL.Func([IDL.Principal, IDL.Bool], [Result], []), + 'set_custodians' : IDL.Func([IDL.Vec(IDL.Principal)], [], []), + 'set_logo' : IDL.Func([IDL.Text], [], []), + 'set_name' : IDL.Func([IDL.Text], [], []), + 'set_symbol' : IDL.Func([IDL.Text], [], []), + 'set_token_property' : IDL.Func( + [IDL.Nat, IDL.Text, GenericValue], + [Result_5], + [], + ), + 'stats' : IDL.Func([], [Stats], ['query']), + 'supported_interfaces' : IDL.Func( + [], + [IDL.Vec(SupportedInterface)], + ['query'], + ), + 'symbol' : IDL.Func([], [IDL.Opt(IDL.Text)], ['query']), + 'token_metadata' : IDL.Func([IDL.Nat], [Result_6], ['query']), + 'total_supply' : IDL.Func([], [IDL.Nat], ['query']), + 'total_transactions' : IDL.Func([], [IDL.Nat], ['query']), + 'total_unique_holders' : IDL.Func([], [IDL.Nat], ['query']), + 'transaction' : IDL.Func([IDL.Nat], [Result_7], ['query']), + 'transfer' : IDL.Func([IDL.Principal, IDL.Nat], [Result], []), + 'transfer_from' : IDL.Func( + [IDL.Principal, IDL.Principal, IDL.Nat], + [Result], + [], + ), + }); +}; +export const init = ({ IDL }) => { + const SupportedInterface = IDL.Variant({ + 'Burn' : IDL.Null, + 'Mint' : IDL.Null, + 'Approval' : IDL.Null, + 'TransactionHistory' : IDL.Null, + }); + const CanisterInitData = IDL.Record({ + 'logo' : IDL.Text, + 'name' : IDL.Text, + 'custodians' : IDL.Vec(IDL.Principal), + 'symbol' : IDL.Text, + 'supported_interfaces' : IDL.Vec(SupportedInterface), + }); + return [CanisterInitData]; +}; diff --git a/src/dip721_canister/declarations/dip721-canister/index.d.ts b/src/dip721_canister/declarations/dip721-canister/index.d.ts new file mode 100644 index 0000000..294852e --- /dev/null +++ b/src/dip721_canister/declarations/dip721-canister/index.d.ts @@ -0,0 +1,50 @@ +import type { + ActorSubclass, + HttpAgentOptions, + ActorConfig, + Agent, +} from "@dfinity/agent"; +import type { Principal } from "@dfinity/principal"; +import type { IDL } from "@dfinity/candid"; + +import { _SERVICE } from './dip721-canister.did'; + +export declare const idlFactory: IDL.InterfaceFactory; +export declare const canisterId: string; + +export declare interface CreateActorOptions { + /** + * @see {@link Agent} + */ + agent?: Agent; + /** + * @see {@link HttpAgentOptions} + */ + agentOptions?: HttpAgentOptions; + /** + * @see {@link ActorConfig} + */ + actorOptions?: ActorConfig; +} + +/** + * Intializes an {@link ActorSubclass}, configured with the provided SERVICE interface of a canister. + * @constructs {@link ActorSubClass} + * @param {string | Principal} canisterId - ID of the canister the {@link Actor} will talk to + * @param {CreateActorOptions} options - see {@link CreateActorOptions} + * @param {CreateActorOptions["agent"]} options.agent - a pre-configured agent you'd like to use. Supercedes agentOptions + * @param {CreateActorOptions["agentOptions"]} options.agentOptions - options to set up a new agent + * @see {@link HttpAgentOptions} + * @param {CreateActorOptions["actorOptions"]} options.actorOptions - options for the Actor + * @see {@link ActorConfig} + */ +export declare const createActor: ( + canisterId: string | Principal, + options?: CreateActorOptions +) => ActorSubclass<_SERVICE>; + +/** + * Intialized Actor using default settings, ready to talk to a canister using its candid interface + * @constructs {@link ActorSubClass} + */ +export declare const dip721-canister: ActorSubclass<_SERVICE>; diff --git a/src/dip721_canister/declarations/dip721-canister/index.js b/src/dip721_canister/declarations/dip721-canister/index.js new file mode 100644 index 0000000..a6f010a --- /dev/null +++ b/src/dip721_canister/declarations/dip721-canister/index.js @@ -0,0 +1,42 @@ +import { Actor, HttpAgent } from "@dfinity/agent"; + +// Imports and re-exports candid interface +import { idlFactory } from "./dip721-canister.did.js"; +export { idlFactory } from "./dip721-canister.did.js"; + +/* CANISTER_ID is replaced by webpack based on node environment + * Note: canister environment variable will be standardized as + * process.env.CANISTER_ID_ + * beginning in dfx 0.15.0 + */ +export const canisterId = + process.env.CANISTER_ID_DIP721-CANISTER; + +export const createActor = (canisterId, options = {}) => { + const agent = options.agent || new HttpAgent({ ...options.agentOptions }); + + if (options.agent && options.agentOptions) { + console.warn( + "Detected both agent and agentOptions passed to createActor. Ignoring agentOptions and proceeding with the provided agent." + ); + } + + // Fetch root key for certificate validation during development + if (process.env.DFX_NETWORK !== "ic") { + agent.fetchRootKey().catch((err) => { + console.warn( + "Unable to fetch root key. Check to ensure that your local replica is running" + ); + console.error(err); + }); + } + + // Creates an actor with using the candid interface and the HttpAgent + return Actor.createActor(idlFactory, { + agent, + canisterId, + ...options.actorOptions, + }); +}; + +export const dip721-canister = canisterId ? createActor(canisterId) : undefined; diff --git a/src/dip721_canister/dip721-canister.did b/src/dip721_canister/dip721-canister.did new file mode 100644 index 0000000..f01cad5 --- /dev/null +++ b/src/dip721_canister/dip721-canister.did @@ -0,0 +1,115 @@ +type CanisterInitData = record { + logo : opt text; + name : text; + custodians : vec principal; + symbol : text; + supported_interfaces : vec SupportedInterface; +}; +type GenericValue = variant { + Nat64Content : nat64; + Nat32Content : nat32; + BoolContent : bool; + Nat8Content : nat8; + Int64Content : int64; + IntContent : int; + NatContent : nat; + Nat16Content : nat16; + Int32Content : int32; + Int8Content : int8; + FloatContent : float64; + Int16Content : int16; + BlobContent : blob; + NestedContent : vec record { text; GenericValue }; + Principal : principal; + TextContent : text; +}; +type Metadata = record { + logo : opt text; + name : opt text; + created_at : nat64; + upgraded_at : nat64; + custodians : vec principal; + symbol : opt text; +}; +type NftError = variant { + UnauthorizedOperator; + SelfTransfer; + TokenNotFound; + UnauthorizedOwner; + TxNotFound; + SelfApprove; + OperatorNotFound; + ExistedNFT; + OwnerNotFound; + Other : text; +}; +type Result = variant { Ok : nat; Err : NftError }; +type Result_1 = variant { Ok : bool; Err : NftError }; +type Result_2 = variant { Ok : opt principal; Err : NftError }; +type Result_3 = variant { Ok : vec nat; Err : NftError }; +type Result_4 = variant { Ok : vec TokenMetadata; Err : NftError }; +type Result_5 = variant { Ok; Err : NftError }; +type Result_6 = variant { Ok : TokenMetadata; Err : NftError }; +type Result_7 = variant { Ok : TxEvent; Err : NftError }; +type Stats = record { + cycles : nat; + total_transactions : nat; + total_unique_holders : nat; + total_supply : nat; +}; +type SupportedInterface = variant { Burn; Mint; Approval; TransactionHistory }; +type TokenMetadata = record { + transferred_at : opt nat64; + transferred_by : opt principal; + owner : opt principal; + operator : opt principal; + approved_at : opt nat64; + approved_by : opt principal; + properties : vec record { text; GenericValue }; + is_burned : bool; + token_identifier : nat; + burned_at : opt nat64; + burned_by : opt principal; + minted_at : nat64; + minted_by : principal; +}; +type TxEvent = record { + time : nat64; + operation : text; + details : vec record { text; GenericValue }; + caller : principal; +}; +service : (CanisterInitData) -> { + approve : (principal, nat) -> (Result); + balance_of : (principal) -> (Result) query; + burn : (nat) -> (Result); + custodians : () -> (vec principal) query; + cycles : () -> (nat) query; + is_approved_for_all : (principal, principal) -> (Result_1); + logo : () -> (opt text) query; + metadata : () -> (Metadata) query; + mint : (principal, nat, vec record { text; GenericValue }) -> (Result); + name : () -> (opt text) query; + operator_of : (nat) -> (Result_2) query; + operator_token_identifiers : (principal) -> (Result_3) query; + operator_token_metadata : (principal) -> (Result_4) query; + owner_of : (nat) -> (Result_2) query; + owner_token_identifiers : (principal) -> (Result_3) query; + owner_token_metadata : (principal) -> (Result_4) query; + set_approval_for_all : (principal, bool) -> (Result); + set_custodians : (vec principal) -> (); + set_logo : (text) -> (); + set_name : (text) -> (); + set_symbol : (text) -> (); + set_token_property : (nat, text, GenericValue) -> (Result_5); + stats : () -> (Stats) query; + supported_interfaces : () -> (vec SupportedInterface) query; + symbol : () -> (opt text) query; + token_metadata : (nat) -> (Result_6) query; + total_supply : () -> (nat) query; + total_transactions : () -> (nat) query; + total_unique_holders : () -> (nat) query; + transaction : (nat) -> (Result_7) query; + transfer : (principal, nat) -> (Result); + transfer_from : (principal, principal, nat) -> (Result); +} \ No newline at end of file diff --git a/src/app.rs b/src/dip721_canister/src/app.rs similarity index 99% rename from src/app.rs rename to src/dip721_canister/src/app.rs index a004e9a..e67dc18 100644 --- a/src/app.rs +++ b/src/dip721_canister/src/app.rs @@ -31,9 +31,11 @@ impl App { pub fn init(init_data: CanisterInitData) { Configuration::set_custodians(&init_data.custodians); Configuration::set_supported_interfaces(&init_data.supported_interfaces); - Configuration::set_logo(init_data.logo); Configuration::set_name(init_data.name); Configuration::set_symbol(init_data.symbol); + if let Some(logo) = init_data.logo { + Configuration::set_logo(logo); + } } /// Task to execute on post upgrade @@ -732,7 +734,7 @@ mod test { SupportedInterface::Mint, SupportedInterface::Approval, ], - logo: "logo".to_string(), + logo: Some("logo".to_string()), name: "nft".to_string(), symbol: "NFT".to_string(), }); diff --git a/src/app/configuration.rs b/src/dip721_canister/src/app/configuration.rs similarity index 100% rename from src/app/configuration.rs rename to src/dip721_canister/src/app/configuration.rs diff --git a/src/app/inspect.rs b/src/dip721_canister/src/app/inspect.rs similarity index 100% rename from src/app/inspect.rs rename to src/dip721_canister/src/app/inspect.rs diff --git a/src/app/memory.rs b/src/dip721_canister/src/app/memory.rs similarity index 100% rename from src/app/memory.rs rename to src/dip721_canister/src/app/memory.rs diff --git a/src/app/storage.rs b/src/dip721_canister/src/app/storage.rs similarity index 100% rename from src/app/storage.rs rename to src/dip721_canister/src/app/storage.rs diff --git a/src/app/storage/tokens.rs b/src/dip721_canister/src/app/storage/tokens.rs similarity index 100% rename from src/app/storage/tokens.rs rename to src/dip721_canister/src/app/storage/tokens.rs diff --git a/src/app/storage/tx_history.rs b/src/dip721_canister/src/app/storage/tx_history.rs similarity index 100% rename from src/app/storage/tx_history.rs rename to src/dip721_canister/src/app/storage/tx_history.rs diff --git a/src/app/test_utils.rs b/src/dip721_canister/src/app/test_utils.rs similarity index 100% rename from src/app/test_utils.rs rename to src/dip721_canister/src/app/test_utils.rs diff --git a/src/did.rs b/src/dip721_canister/src/did.rs similarity index 91% rename from src/did.rs rename to src/dip721_canister/src/did.rs index f187ff4..7d37ce3 100644 --- a/src/did.rs +++ b/src/dip721_canister/src/did.rs @@ -6,7 +6,7 @@ use serde::Deserialize; pub struct CanisterInitData { pub custodians: Vec, pub supported_interfaces: Vec, - pub logo: String, pub name: String, pub symbol: String, + pub logo: Option, } diff --git a/src/inspect.rs b/src/dip721_canister/src/inspect.rs similarity index 100% rename from src/inspect.rs rename to src/dip721_canister/src/inspect.rs diff --git a/src/lib.rs b/src/dip721_canister/src/lib.rs similarity index 100% rename from src/lib.rs rename to src/dip721_canister/src/lib.rs diff --git a/src/storable.rs b/src/dip721_canister/src/storable.rs similarity index 100% rename from src/storable.rs rename to src/dip721_canister/src/storable.rs diff --git a/src/utils.rs b/src/dip721_canister/src/utils.rs similarity index 100% rename from src/utils.rs rename to src/dip721_canister/src/utils.rs