diff --git a/Cargo.lock b/Cargo.lock index 49c4a4a6..2d1f648f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "base16ct" @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" [[package]] name = "byteorder" @@ -87,9 +87,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cosmwasm-crypto" @@ -231,18 +231,112 @@ dependencies = [ "cosmwasm-std", ] +[[package]] +name = "cw-ics721-incoming-proxy" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ics721-incoming-proxy-derive", + "cw-paginate-storage", + "cw-storage-plus 1.2.0", + "ics721-types 0.1.0 (git+https://github.com/arkprotocol/ark-cw-ics721?branch=incoming_proxy)", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-ics721-incoming-proxy-base" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ics721-incoming-proxy", + "cw-ics721-incoming-proxy-derive", + "cw-ics721-outgoing-proxy", + "cw-ics721-outgoing-proxy-derive", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ics721-types 0.1.0 (git+https://github.com/arkprotocol/ark-cw-ics721?branch=incoming_proxy)", + "serde", + "thiserror", +] + +[[package]] +name = "cw-ics721-incoming-proxy-derive" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "ics721-types 0.1.0 (git+https://github.com/arkprotocol/ark-cw-ics721?branch=incoming_proxy)", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-ics721-outgoing-proxy" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ics721-outgoing-proxy-derive", + "cw-storage-plus 1.2.0", + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw721-base 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ics721-types 0.1.0 (git+https://github.com/arkprotocol/ark-cw-ics721?branch=incoming_proxy)", + "thiserror", +] + +[[package]] +name = "cw-ics721-outgoing-proxy-derive" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" +dependencies = [ + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-ics721-outgoing-proxy-rate-limit" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-ics721-outgoing-proxy", + "cw-ics721-outgoing-proxy-derive", + "cw-rate-limiter", + "cw-storage-plus 1.2.0", + "cw2 1.1.2", + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw721-base 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ics721-types 0.1.0 (git+https://github.com/arkprotocol/ark-cw-ics721?branch=incoming_proxy)", + "serde", + "thiserror", +] + [[package]] name = "cw-multi-test" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e2c2f2c0877b839c5cad85e67811074e854a50c1ff3085eb8290b1c27809c" +checksum = "67fff029689ae89127cf6d7655809a68d712f3edbdb9686c70b018ba438b26ca" dependencies = [ "anyhow", + "bech32", "cosmwasm-std", "cw-storage-plus 1.2.0", - "cw-utils 1.0.2", + "cw-utils 1.0.3", "derivative", - "itertools", + "itertools 0.12.0", "prost", "schemars", "serde", @@ -261,7 +355,7 @@ dependencies = [ "cw-address-like", "cw-ownable-derive", "cw-storage-plus 1.2.0", - "cw-utils 1.0.2", + "cw-utils 1.0.3", "thiserror", ] @@ -278,8 +372,8 @@ dependencies = [ [[package]] name = "cw-paginate-storage" -version = "2.3.0" -source = "git+https://github.com/DA0-DA0/dao-contracts.git#1187dbac2729bc0504a3d39b7f617773a8a5b6ad" +version = "2.4.0" +source = "git+https://github.com/DA0-DA0/dao-contracts.git#3ead037e9366d922c862614974b16b4dc732b329" dependencies = [ "cosmwasm-std", "cosmwasm-storage", @@ -294,14 +388,14 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", - "cw-utils 1.0.2", + "cw-utils 1.0.3", "thiserror", ] [[package]] name = "cw-rate-limiter" -version = "0.0.1" -source = "git+https://github.com/arkprotocol/cw721-proxy.git?tag=v0.0.7#a433953f4d4f605a7b472f9cb31b5068dcad3e28" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/cw-ics721-proxy.git?tag=v0.1.0#cc1c156b1c0d2941c62b4291444674baf1ec855b" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -350,13 +444,13 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9f351a4e4d81ef7c890e44d903f8c0bdcdc00f094fd3a181eaf70c0eec7a3a" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.1", + "cw2 1.1.2", "schemars", "semver", "serde", @@ -378,14 +472,15 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9431d14f64f49e41c6ef5561ed11a5391c417d0cb16455dea8cdcb9037a8d197" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", "schemars", + "semver", "serde", "thiserror", ] @@ -411,7 +506,19 @@ checksum = "e3c4d286625ccadc957fe480dd3bdc54ada19e0e6b5b9325379db3130569e914" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-utils 1.0.2", + "cw-utils 1.0.3", + "schemars", + "serde", +] + +[[package]] +name = "cw721" +version = "0.18.0" +source = "git+https://github.com/CosmWasm/cw-nfts?branch=main#cc27e27d54e237709ebdcd478568126e109a8845" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils 1.0.3", "schemars", "serde", ] @@ -443,9 +550,9 @@ dependencies = [ "cosmwasm-std", "cw-ownable", "cw-storage-plus 1.2.0", - "cw-utils 1.0.2", - "cw2 1.1.1", - "cw721 0.18.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "cw721-base 0.16.0", "schemars", "serde", @@ -453,42 +560,19 @@ dependencies = [ ] [[package]] -name = "cw721-proxy" -version = "0.0.1" -source = "git+https://github.com/arkprotocol/cw721-proxy.git?tag=v0.0.7#a433953f4d4f605a7b472f9cb31b5068dcad3e28" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 1.2.0", - "cw721 0.18.0", - "cw721-proxy-derive", - "thiserror", -] - -[[package]] -name = "cw721-proxy-derive" -version = "0.0.1" -source = "git+https://github.com/arkprotocol/cw721-proxy.git?tag=v0.0.7#a433953f4d4f605a7b472f9cb31b5068dcad3e28" -dependencies = [ - "cw721 0.18.0", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "cw721-rate-limited-proxy" -version = "0.0.1" -source = "git+https://github.com/arkprotocol/cw721-proxy.git?tag=v0.0.7#a433953f4d4f605a7b472f9cb31b5068dcad3e28" +name = "cw721-base" +version = "0.18.0" +source = "git+https://github.com/CosmWasm/cw-nfts?branch=main#cc27e27d54e237709ebdcd478568126e109a8845" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-rate-limiter", + "cw-ownable", "cw-storage-plus 1.2.0", - "cw2 1.1.1", - "cw721 0.18.0", - "cw721-proxy", - "cw721-proxy-derive", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", + "cw721-base 0.16.0", + "schemars", "serde", "thiserror", ] @@ -500,8 +584,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus 1.2.0", - "cw2 1.1.1", - "cw721-base 0.18.0", + "cw2 1.1.2", + "cw721-base 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", "thiserror", ] @@ -590,9 +674,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.7" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9775b22bc152ad86a0cf23f0f348b884b26add12bf741e7ffc4d4ab2ab4d205" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -619,9 +703,9 @@ dependencies = [ [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -698,19 +782,20 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-cii", + "cw-ics721-incoming-proxy-base", + "cw-ics721-outgoing-proxy-rate-limit", "cw-multi-test", "cw-ownable", "cw-paginate-storage", "cw-pause-once", "cw-storage-plus 1.2.0", - "cw-utils 1.0.2", - "cw2 1.1.1", + "cw-utils 1.0.3", + "cw2 1.1.2", "cw721 0.16.0", - "cw721 0.18.0", + "cw721 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", "cw721-base 0.16.0", - "cw721-base 0.18.0", - "cw721-proxy-derive", - "cw721-rate-limited-proxy", + "cw721-base 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", + "ics721-types 0.1.0", "serde", "sha2 0.10.8", "thiserror", @@ -722,7 +807,7 @@ name = "ics721-base" version = "0.1.0" dependencies = [ "cosmwasm-std", - "cw2 1.1.1", + "cw2 1.1.2", "ics721", ] @@ -734,17 +819,43 @@ dependencies = [ "cosmwasm-std", "cosmwasm-storage", "cw-storage-plus 1.2.0", - "cw2 1.1.1", - "cw721 0.18.0", + "cw2 1.1.2", + "cw721 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", "ics721", + "ics721-types 0.1.0", + "thiserror", +] + +[[package]] +name = "ics721-types" +version = "0.1.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw721 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", + "serde", + "thiserror", +] + +[[package]] +name = "ics721-types" +version = "0.1.0" +source = "git+https://github.com/arkprotocol/ark-cw-ics721?branch=incoming_proxy#1fadd3b4869b7cdcbc54128d34ad86b2fdfed0b2" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw721 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", + "serde", "thiserror", ] [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -759,11 +870,20 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "k256" @@ -781,15 +901,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -799,9 +919,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pkcs8" @@ -815,18 +935,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] [[package]] name = "prost" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5a410fc7882af66deb8d01d01737353cf3ad6204c408177ba494291a626312" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", "prost-derive", @@ -834,22 +954,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065717a5dfaca4a83d2fe57db3487b311365200000551d7a364e715dbf4346bc" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.46", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -881,9 +1001,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "schemars" @@ -925,15 +1045,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] @@ -949,13 +1069,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.46", ] [[package]] @@ -971,9 +1091,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" dependencies = [ "itoa", "ryu", @@ -989,14 +1109,16 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-cii", + "cw-ics721-incoming-proxy-base", + "cw-ics721-outgoing-proxy-rate-limit", "cw-multi-test", "cw-pause-once", "cw-storage-plus 1.2.0", - "cw2 1.1.1", - "cw721 0.18.0", - "cw721-base 0.18.0", - "cw721-rate-limited-proxy", + "cw2 1.1.2", + "cw721 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", + "cw721-base 0.18.0 (git+https://github.com/CosmWasm/cw-nfts?branch=main)", "ics721", + "ics721-types 0.1.0", "sg-std", "sg721", "sg721-base", @@ -1011,8 +1133,8 @@ checksum = "4db53aebc2b4f981dc20a51213544adde8beaace6880345627f4babe2e1bc3ab" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-utils 1.0.2", - "cw721 0.18.0", + "cw-utils 1.0.3", + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "schemars", "serde", "thiserror", @@ -1027,8 +1149,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-ownable", - "cw-utils 1.0.2", - "cw721-base 0.18.0", + "cw-utils 1.0.3", + "cw721-base 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "thiserror", ] @@ -1043,10 +1165,10 @@ dependencies = [ "cosmwasm-std", "cw-ownable", "cw-storage-plus 1.2.0", - "cw-utils 1.0.2", - "cw2 1.1.1", - "cw721 0.18.0", - "cw721-base 0.18.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw721 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cw721-base 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "sg-std", "sg721", @@ -1090,9 +1212,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -1123,9 +1245,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" dependencies = [ "proc-macro2", "quote", @@ -1134,22 +1256,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.46", ] [[package]] @@ -1175,9 +1297,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -1196,9 +1318,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", diff --git a/Cargo.toml b/Cargo.toml index 2a8f4f1d..b4b09abd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,35 +7,37 @@ edition = "2021" [workspace.dependencies] # common libs -anyhow = "1.0" +anyhow = "^1.0" bech32 = "^0.9" -cosmwasm-std = "1.2" -cosmwasm-schema = "1.2" -cosmwasm-storage = "1.2" -cw-ownable = "0.5.0" -cw-paginate-storage = { version = "2.2.0", git = "https://github.com/DA0-DA0/dao-contracts.git" } +cosmwasm-std = "^1.5" +cosmwasm-schema = "^1.5" +cosmwasm-storage = "^1.5" +cw-ownable = "^0.5" +cw-paginate-storage = { version = "^2.4", git = "https://github.com/DA0-DA0/dao-contracts.git" } cw-storage-plus = "1.1" cw2 = "1.1" -cw721 = "0.18" +cw721 = { git = "https://github.com/CosmWasm/cw-nfts", branch = "main"} # TODO switch to version 0.18.1/0.19.0, once released cw721-016 = { version = "0.16.0", package = "cw721" } -cw721-base = "0.18" +cw721-base = { git = "https://github.com/CosmWasm/cw-nfts", branch = "main"} # TODO switch to version 0.18.1/0.19.0, once released cw721-base-016 = { version = "0.16.0", package = "cw721-base" } -cw721-proxy-derive = { git = "https://github.com/arkprotocol/cw721-proxy.git", tag = "v0.0.7" } -cw721-rate-limited-proxy = { git = "https://github.com/arkprotocol/cw721-proxy.git", tag = "v0.0.7" } -cw-multi-test = { version = "0.18", features = ["cosmwasm_1_2"] } -cw-utils = "1.0" +cw-ics721-incoming-proxy = { git = "https://github.com/arkprotocol/cw-ics721-proxy.git", tag = "v0.1.0" } +cw-ics721-incoming-proxy-base = { git = "https://github.com/arkprotocol/cw-ics721-proxy.git", tag = "v0.1.0" } +cw-ics721-outgoing-proxy-rate-limit = { git = "https://github.com/arkprotocol/cw-ics721-proxy.git", tag = "v0.1.0" } +cw-multi-test = { version = "^0.20", features = ["cosmwasm_1_2"] } +cw-utils = "^1.0" sha2 = "^0.10" -serde = "1.0" -thiserror = "1" +serde = "^1.0" +thiserror = "^1.0" # Stargaze libs sg-std = "^3.2" sg-multi-test = "^3.1" -sg721 = "^3.1" -sg721-base = "^3.1" +sg721 = "^3.3" +sg721-base = "^3.3" # packages and contracts cw-cii = { path = "./packages/cw-cii" } cw-pause-once = { path = "./packages/cw-pause-once" } ics721 = { path = "./packages/ics721" } +ics721-types = { path = "./packages/ics721-types" } zip-optional = { path = "./packages/zip-optional" } ics721-base = { path = "./contracts/ics721-base"} ics721-base-tester = { path = "./contracts/cw-ics721-base-tester"} diff --git a/README.md b/README.md index b51ce829..d4725043 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Pause functionality is designed to allow for quick pauses by a trusted group, wi After a pause, the ICS721 contract will remain paused until governance chooses to unpause it. During the unpause process governance may appoint a new subDAO or reappoint the existing one as pause manager. It is imagined that the admin of this contract will be a chain's community pool, and the pause manager will be a small, active subDAO. This process means that the subDAO may pause the contract in the event of a problem, but may not lock the contract, as in pausing the contract the subDAO burns its ability to do so again. -Filtering is enabled by an optional proxy that the ICS721 contract may be configured to use. If a proxy is configured, the ICS721 contract will only accept NFTs delivered by the proxy address. This proxy interface is very minimal and enables very flexible rate limiting and filtering. Currently, per-collection rate limiting is implemented. Users of this ICS721 contract are encouraged to implement their own filtering regimes and may add them to the [proxy repository](https://github.com/arkprotocol/cw721-proxy) so that others may use them. +Filtering is enabled by an optional proxy that the ICS721 contract may be configured to use. If a proxy is configured, the ICS721 contract will only accept NFTs delivered by the proxy address. This proxy interface is very minimal and enables very flexible rate limiting and filtering. Currently, per-collection rate limiting is implemented. Users of this ICS721 contract are encouraged to implement their own filtering regimes and may add them to the [proxy repository](https://github.com/arkprotocol/cw-ics721-proxy) so that others may use them. ## Failure handling errata diff --git a/contracts/cw721-tester/Cargo.lock b/contracts/cw721-tester/Cargo.lock deleted file mode 100644 index 91fb09ff..00000000 --- a/contracts/cw721-tester/Cargo.lock +++ /dev/null @@ -1,738 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[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 = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-multi-test" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbea57e5be4a682268a5eca1a57efece57a54ff216bfd87603d5e864aad40e12" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools", - "prost", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993df11574f29574dd443eb0c189484bb91bc0638b6de3e32ab7f9319c92122d" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21ecb263bf75fc69d5e74b0f2a60b6dd80cfd9fb0eba15c4b9d1104ceffc77" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219b924f5b39f25b7d7c9203873a2698fdac8db2b396aaea6fa099b699cc40e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "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", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "testgen-local" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[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.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/contracts/cw721-tester/src/lib.rs b/contracts/cw721-tester/src/lib.rs index e793ca10..ed686b1e 100644 --- a/contracts/cw721-tester/src/lib.rs +++ b/contracts/cw721-tester/src/lib.rs @@ -40,6 +40,7 @@ pub fn instantiate( name: msg.name, symbol: msg.symbol, minter: msg.minter, + withdraw_address: None, }, )?; TARGET.save(deps.storage, &deps.api.addr_validate(&msg.target)?)?; diff --git a/contracts/ics721-base-tester/Cargo.lock b/contracts/ics721-base-tester/Cargo.lock deleted file mode 100644 index 42783426..00000000 --- a/contracts/ics721-base-tester/Cargo.lock +++ /dev/null @@ -1,738 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[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 = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-ibc-example" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbea57e5be4a682268a5eca1a57efece57a54ff216bfd87603d5e864aad40e12" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools", - "prost", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993df11574f29574dd443eb0c189484bb91bc0638b6de3e32ab7f9319c92122d" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21ecb263bf75fc69d5e74b0f2a60b6dd80cfd9fb0eba15c4b9d1104ceffc77" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219b924f5b39f25b7d7c9203873a2698fdac8db2b396aaea6fa099b699cc40e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "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", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[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.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/contracts/ics721-base-tester/Cargo.toml b/contracts/ics721-base-tester/Cargo.toml index 1c266320..2d30479c 100644 --- a/contracts/ics721-base-tester/Cargo.toml +++ b/contracts/ics721-base-tester/Cargo.toml @@ -19,5 +19,6 @@ cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } ics721 = { workspace = true } +ics721-types = { workspace = true } thiserror = { workspace = true } cw721 = { workspace = true } diff --git a/contracts/ics721-base-tester/src/contract.rs b/contracts/ics721-base-tester/src/contract.rs index 94410133..15e3a988 100644 --- a/contracts/ics721-base-tester/src/contract.rs +++ b/contracts/ics721-base-tester/src/contract.rs @@ -5,7 +5,7 @@ use cosmwasm_std::{ StdResult, WasmMsg, }; use cw2::set_contract_version; -use ics721::ibc::NonFungibleTokenPacketData; +use ics721_types::ibc_types::{IbcOutgoingMsg, NonFungibleTokenPacketData}; use crate::{ error::ContractError, @@ -64,8 +64,8 @@ pub fn execute( mod receive_callbacks { use cosmwasm_std::{ensure_eq, from_json, DepsMut, MessageInfo, Response}; - use ics721::{ - ibc::NonFungibleTokenPacketData, + use ics721_types::{ + ibc_types::NonFungibleTokenPacketData, types::{Ics721AckCallbackMsg, Ics721ReceiveCallbackMsg, Ics721Status}, }; @@ -220,7 +220,7 @@ fn execute_send_nft( msg: to_json_binary(&cw721::Cw721ExecuteMsg::SendNft { contract: ics721, token_id, - msg: to_json_binary(&ics721::msg::IbcOutgoingMsg { + msg: to_json_binary(&IbcOutgoingMsg { receiver: recipient, channel_id, timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(1000)), diff --git a/contracts/ics721-base-tester/src/msg.rs b/contracts/ics721-base-tester/src/msg.rs index 3038279c..75a0bd3a 100644 --- a/contracts/ics721-base-tester/src/msg.rs +++ b/contracts/ics721-base-tester/src/msg.rs @@ -43,8 +43,8 @@ pub struct InstantiateMsg { // for clippy's taste. pub enum ExecuteMsg { ReceiveNft(cw721::Cw721ReceiveMsg), - Ics721ReceiveCallback(ics721::types::Ics721ReceiveCallbackMsg), - Ics721AckCallback(ics721::types::Ics721AckCallbackMsg), + Ics721ReceiveCallback(ics721_types::types::Ics721ReceiveCallbackMsg), + Ics721AckCallback(ics721_types::types::Ics721AckCallbackMsg), SendNft { cw721: String, ics721: String, @@ -60,7 +60,7 @@ pub enum ExecuteMsg { channel_id: String, timeout: IbcTimeout, - data: ics721::ibc::NonFungibleTokenPacketData, + data: ics721_types::ibc_types::NonFungibleTokenPacketData, }, SetAckMode { ack_mode: AckMode, diff --git a/contracts/ics721-base/Cargo.lock b/contracts/ics721-base/Cargo.lock deleted file mode 100644 index f3f526cb..00000000 --- a/contracts/ics721-base/Cargo.lock +++ /dev/null @@ -1,738 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[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 = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-ics721" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbea57e5be4a682268a5eca1a57efece57a54ff216bfd87603d5e864aad40e12" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools", - "prost", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993df11574f29574dd443eb0c189484bb91bc0638b6de3e32ab7f9319c92122d" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21ecb263bf75fc69d5e74b0f2a60b6dd80cfd9fb0eba15c4b9d1104ceffc77" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219b924f5b39f25b7d7c9203873a2698fdac8db2b396aaea6fa099b699cc40e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "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", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[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.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/contracts/sg-ics721/Cargo.lock b/contracts/sg-ics721/Cargo.lock deleted file mode 100644 index f3f526cb..00000000 --- a/contracts/sg-ics721/Cargo.lock +++ /dev/null @@ -1,738 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anyhow" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "base64ct" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" - -[[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 = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - -[[package]] -name = "cosmwasm-crypto" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eb0afef2325df81aadbf9be1233f522ed8f6e91df870c764bc44cca2b1415bd" -dependencies = [ - "digest", - "ed25519-zebra", - "k256", - "rand_core 0.6.3", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" -dependencies = [ - "syn", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772e80bbad231a47a2068812b723a1ff81dd4a0d56c9391ac748177bea3a61da" -dependencies = [ - "schemars", - "serde_json", -] - -[[package]] -name = "cosmwasm-std" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" -dependencies = [ - "base64", - "cosmwasm-crypto", - "cosmwasm-derive", - "forward_ref", - "schemars", - "serde", - "serde-json-wasm", - "thiserror", - "uint", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18403b07304d15d304dad11040d45bbcaf78d603b4be3fb5e2685c16f9229b5" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" -dependencies = [ - "generic-array", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "cw-ics721" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-multi-test", - "cw-storage-plus", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-multi-test" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbea57e5be4a682268a5eca1a57efece57a54ff216bfd87603d5e864aad40e12" -dependencies = [ - "anyhow", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus", - "cw-utils", - "derivative", - "itertools", - "prost", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw-storage-plus" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9336ecef1e19d56cf6e3e932475fc6a3dee35eec5a386e07917a1d1ba6bb0e35" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-utils" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babd2c090f39d07ce5bf2556962305e795daa048ce20a93709eb591476e4a29e" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993df11574f29574dd443eb0c189484bb91bc0638b6de3e32ab7f9319c92122d" -dependencies = [ - "cosmwasm-std", - "cw-storage-plus", - "schemars", - "serde", -] - -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "dyn-clone" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" - -[[package]] -name = "ecdsa" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-zebra" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" -dependencies = [ - "curve25519-dalek", - "hex", - "rand_core 0.6.3", - "serde", - "sha2", - "thiserror", - "zeroize", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "ff", - "generic-array", - "group", - "rand_core 0.6.3", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "generic-array" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" -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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", -] - -[[package]] -name = "group" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" - -[[package]] -name = "k256" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sec1", - "sha2", -] - -[[package]] -name = "libc" -version = "0.2.126" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - -[[package]] -name = "proc-macro2" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" -dependencies = [ - "proc-macro2", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.6", -] - -[[package]] -name = "rfc6979" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] -name = "ryu" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" - -[[package]] -name = "schemars" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d21ecb263bf75fc69d5e74b0f2a60b6dd80cfd9fb0eba15c4b9d1104ceffc77" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219b924f5b39f25b7d7c9203873a2698fdac8db2b396aaea6fa099b699cc40e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn", -] - -[[package]] -name = "sec1" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" -dependencies = [ - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.137" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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", -] - -[[package]] -name = "serde_json" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" -dependencies = [ - "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", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "signature" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" -dependencies = [ - "digest", - "rand_core 0.6.3", -] - -[[package]] -name = "spki" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "typenum" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" - -[[package]] -name = "uint" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f03af7ccf01dd611cc450a0d10dbc9b745770d096473e2faf0ca6e2d66d1e0" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[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.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "zeroize" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" diff --git a/contracts/sg-ics721/Cargo.toml b/contracts/sg-ics721/Cargo.toml index 3bf2602e..63ac889c 100644 --- a/contracts/sg-ics721/Cargo.toml +++ b/contracts/sg-ics721/Cargo.toml @@ -17,6 +17,7 @@ cosmwasm-std = { workspace = true, features = ["ibc3"] } cosmwasm-schema = { workspace = true } cw2 = { workspace = true } ics721 = { workspace = true } +ics721-types = { workspace = true } sg-std = { workspace = true} sg721 = { workspace = true } sg721-base = { workspace = true, features = ["library"] } @@ -30,6 +31,7 @@ cw-multi-test = { workspace = true } cw-pause-once = { workspace = true } cw-storage-plus = { workspace = true } cw721 = { workspace = true} -cw721-rate-limited-proxy = { workspace = true } +cw-ics721-incoming-proxy-base = { workspace = true } +cw-ics721-outgoing-proxy-rate-limit = { workspace = true } cw721-base = { workspace = true} sha2 = { workspace = true } diff --git a/contracts/sg-ics721/src/execute.rs b/contracts/sg-ics721/src/execute.rs index 2605a99a..a937700d 100644 --- a/contracts/sg-ics721/src/execute.rs +++ b/contracts/sg-ics721/src/execute.rs @@ -1,7 +1,7 @@ use cosmwasm_std::{from_json, to_json_binary, Addr, Binary, Deps, DepsMut, Env, StdResult}; -use ics721::{ - execute::Ics721Execute, state::CollectionData, token_types::Class, utils::get_collection_data, -}; +use ics721::{execute::Ics721Execute, state::CollectionData, utils::get_collection_data}; +use ics721_types::token_types::Class; + use sg721_base::msg::{CollectionInfoResponse, QueryMsg}; use crate::state::{SgCollectionData, SgIcs721Contract}; diff --git a/contracts/sg-ics721/src/testing/integration_tests.rs b/contracts/sg-ics721/src/testing/integration_tests.rs index f77f1094..90cb9fa8 100644 --- a/contracts/sg-ics721/src/testing/integration_tests.rs +++ b/contracts/sg-ics721/src/testing/integration_tests.rs @@ -11,16 +11,20 @@ use cw721_base::msg::QueryMsg as Cw721QueryMsg; use cw_cii::{Admin, ContractInstantiateInfo}; use cw_multi_test::{ AddressGenerator, App, AppBuilder, BankKeeper, Contract, ContractWrapper, DistributionKeeper, - Executor, FailingModule, IbcAcceptingModule, Router, StakeKeeper, WasmKeeper, + Executor, FailingModule, IbcAcceptingModule, Router, StakeKeeper, StargateFailing, WasmKeeper, }; use cw_pause_once::PauseError; use ics721::{ execute::Ics721Execute, ibc::Ics721Ibc, - msg::{CallbackMsg, ExecuteMsg, IbcOutgoingMsg, InstantiateMsg, MigrateMsg, QueryMsg}, + msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, query::Ics721Query, state::CollectionData, - token_types::{Class, ClassId, Token, TokenId, VoucherCreation}, + token_types::VoucherCreation, +}; +use ics721_types::{ + ibc_types::{IbcOutgoingMsg, IbcOutgoingProxyMsg}, + token_types::{Class, ClassId, Token, TokenId}, }; use sg721::InstantiateMsg as Sg721InstantiateMsg; use sg721_base::msg::{CollectionInfoResponse, QueryMsg as Sg721QueryMsg}; @@ -49,6 +53,7 @@ type MockRouter = Router< DistributionKeeper, IbcAcceptingModule, FailingModule, + StargateFailing, >; type MockApp = App< @@ -281,7 +286,9 @@ struct Test { impl Test { fn new( - proxy: bool, + outgoing_proxy: bool, + incoming_proxy: bool, + channels: Option>, admin_and_pauser: Option, cw721_code: Box>, ) -> Self { @@ -295,19 +302,37 @@ impl Test { let source_cw721_id = app.store_code(cw721_code); let ics721_id = app.store_code(ics721_contract()); - use cw721_rate_limited_proxy as rlp; - let proxy = match proxy { + let outgoing_proxy = match outgoing_proxy { + true => { + let proxy_id = app.store_code(outgoing_proxy_contract()); + Some(ContractInstantiateInfo { + code_id: proxy_id, + msg: to_json_binary( + &cw_ics721_outgoing_proxy_rate_limit::msg::InstantiateMsg { + rate_limit: cw_ics721_outgoing_proxy_rate_limit::Rate::PerBlock(10), + origin: None, + }, + ) + .unwrap(), + admin: Some(Admin::Instantiator {}), + label: "outgoing proxy rate limit".to_string(), + }) + } + false => None, + }; + + let incoming_proxy = match incoming_proxy { true => { - let proxy_id = app.store_code(proxy_contract()); + let proxy_id = app.store_code(incoming_proxy_contract()); Some(ContractInstantiateInfo { code_id: proxy_id, - msg: to_json_binary(&rlp::msg::InstantiateMsg { - rate_limit: rlp::Rate::PerBlock(10), + msg: to_json_binary(&cw_ics721_incoming_proxy_base::msg::InstantiateMsg { origin: None, + channels, }) .unwrap(), admin: Some(Admin::Instantiator {}), - label: "rate limited proxy".to_string(), + label: "incoming proxy".to_string(), }) } false => None, @@ -319,7 +344,8 @@ impl Test { app.api().addr_make(ICS721_CREATOR), &InstantiateMsg { cw721_base_code_id: source_cw721_id, - proxy, + incoming_proxy, + outgoing_proxy, pauser: admin_and_pauser .clone() .map(|p| app.api().addr_make(&p).to_string()), @@ -405,10 +431,17 @@ impl Test { (paused, pauser) } - fn query_proxy(&mut self) -> Option { + fn query_outgoing_proxy(&mut self) -> Option { self.app .wrap() - .query_wasm_smart(self.ics721.clone(), &QueryMsg::Proxy {}) + .query_wasm_smart(self.ics721.clone(), &QueryMsg::OutgoingProxy {}) + .unwrap() + } + + fn query_incoming_proxy(&mut self) -> Option { + self.app + .wrap() + .query_wasm_smart(self.ics721.clone(), &QueryMsg::IncomingProxy {}) .unwrap() } @@ -513,20 +546,27 @@ fn ics721_contract() -> Box> { Box::new(contract) } -fn proxy_contract() -> Box> { - let execute_fn = cw721_rate_limited_proxy::contract::execute::; - let instatiate_fn = cw721_rate_limited_proxy::contract::instantiate::; +fn incoming_proxy_contract() -> Box> { let contract = ContractWrapper::new( - execute_fn, - instatiate_fn, - cw721_rate_limited_proxy::contract::query, + cw_ics721_incoming_proxy_base::contract::execute, + cw_ics721_incoming_proxy_base::contract::instantiate, + cw_ics721_incoming_proxy_base::contract::query, + ); + Box::new(contract) +} + +fn outgoing_proxy_contract() -> Box> { + let contract = ContractWrapper::new( + cw_ics721_outgoing_proxy_rate_limit::contract::execute, + cw_ics721_outgoing_proxy_rate_limit::contract::instantiate, + cw_ics721_outgoing_proxy_rate_limit::contract::query, ); Box::new(contract) } #[test] fn test_instantiate() { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(true, true, None, None, sg721_base_contract()); // check stores are properly initialized let cw721_id = test.query_cw721_id(); @@ -537,11 +577,15 @@ fn test_instantiate() { assert_eq!(outgoing_channels, []); let incoming_channels = test.query_incoming_channels(); assert_eq!(incoming_channels, []); + let outgoing_proxy = test.query_outgoing_proxy(); + assert!(outgoing_proxy.is_some()); + let incoming_proxy = test.query_incoming_proxy(); + assert!(incoming_proxy.is_some()); } #[test] fn test_do_instantiate_and_mint_weird_data() { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -593,7 +637,7 @@ fn test_do_instantiate_and_mint_weird_data() { fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with no ClassData (without owner, name, and symbol) { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -753,7 +797,7 @@ fn test_do_instantiate_and_mint() { } // test case: instantiate cw721 with ClassData containing owner, name, and symbol { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -930,7 +974,7 @@ fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with CustomClassData (includes name, but without owner and symbol) // results in nft contract using class id for name and symbol { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1105,7 +1149,7 @@ fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with PartialCustomCollectionData (includes name and symbol) // results in nft contract using name and symbol { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1283,7 +1327,7 @@ fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with PartialCustomCollectionData (includes name and symbol) // results in nft contract using name and symbol { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1464,7 +1508,7 @@ fn test_do_instantiate_and_mint() { fn test_do_instantiate_and_mint_2_different_collections() { // test case: instantiate two cw721 contracts with different class id and make sure instantiate2 creates 2 different, predictable contracts { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain_1 = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id_1 = format!( @@ -1769,7 +1813,7 @@ fn test_do_instantiate_and_mint_2_different_collections() { #[test] fn test_do_instantiate_and_mint_no_instantiate() { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1898,7 +1942,7 @@ fn test_do_instantiate_and_mint_no_instantiate() { #[test] fn test_do_instantiate_and_mint_permissions() { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1949,23 +1993,71 @@ fn test_do_instantiate_and_mint_permissions() { assert_eq!(err, ContractError::Unauthorized {}); } -/// Tests that we can not proxy NFTs if no proxy is configured. +/// Tests that we can not send IbcOutgoingProxyMsg if no proxy is configured. #[test] -fn test_no_proxy_unauthorized() { - let mut test = Test::new(false, None, sg721_base_contract()); +fn test_no_proxy_unknown_msg() { + let mut test = Test::new(false, false, None, None, sg721_base_contract()); + let msg = IbcOutgoingProxyMsg { + collection: "foo".to_string(), + msg: to_json_binary(&IbcOutgoingMsg { + receiver: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + channel_id: "channel-0".to_string(), + timeout: IbcTimeout::with_block(IbcTimeoutBlock { + revision: 0, + height: 10, + }), + memo: None, + }) + .unwrap(), + }; let err: ContractError = test .app .execute_contract( test.app.api().addr_make("proxy"), test.ics721, - &ExecuteMsg::ReceiveProxyNft { - eyeball: "nft".to_string(), - msg: cw721::Cw721ReceiveMsg { - sender: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), - token_id: "1".to_string(), - msg: to_json_binary("").unwrap(), - }, - }, + &ExecuteMsg::ReceiveNft(cw721::Cw721ReceiveMsg { + sender: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + token_id: "1".to_string(), + msg: to_json_binary(&msg).unwrap(), + }), + &[], + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!( + err, + ContractError::UnknownMsg(to_json_binary(&msg).unwrap()) + ); +} + +/// Tests that we can non-proxy addresses can send if proxy is configured. +#[test] +fn test_no_proxy_unauthorized() { + let mut test = Test::new(true, false, None, None, sg721_base_contract()); + let msg = IbcOutgoingProxyMsg { + collection: "foo".to_string(), + msg: to_json_binary(&IbcOutgoingMsg { + receiver: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + channel_id: "channel-0".to_string(), + timeout: IbcTimeout::with_block(IbcTimeoutBlock { + revision: 0, + height: 10, + }), + memo: None, + }) + .unwrap(), + }; + let err: ContractError = test + .app + .execute_contract( + test.app.api().addr_make("foo"), + test.ics721, + &ExecuteMsg::ReceiveNft(cw721::Cw721ReceiveMsg { + sender: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + token_id: "1".to_string(), + msg: to_json_binary(&msg).unwrap(), + }), &[], ) .unwrap_err() @@ -1976,11 +2068,11 @@ fn test_no_proxy_unauthorized() { #[test] fn test_proxy_authorized() { - let mut test = Test::new(true, None, sg721_base_contract()); + let mut test = Test::new(true, false, None, None, sg721_base_contract()); let proxy_address: Option = test .app .wrap() - .query_wasm_smart(&test.ics721, &QueryMsg::Proxy {}) + .query_wasm_smart(&test.ics721, &QueryMsg::OutgoingProxy {}) .unwrap(); // check proxy is set let proxy_address = proxy_address.expect("expected a proxy"); @@ -2042,15 +2134,15 @@ fn test_proxy_authorized() { .execute_contract( proxy_address, test.ics721, - &ExecuteMsg::ReceiveProxyNft { - eyeball: source_cw721.into_string(), - msg: cw721::Cw721ReceiveMsg { - sender: test - .app - .api() - .addr_make(COLLECTION_OWNER_SOURCE_CHAIN) - .to_string(), - token_id: "1".to_string(), + &ExecuteMsg::ReceiveNft(cw721::Cw721ReceiveMsg { + sender: test + .app + .api() + .addr_make(COLLECTION_OWNER_SOURCE_CHAIN) + .to_string(), + token_id: "1".to_string(), + msg: to_json_binary(&IbcOutgoingProxyMsg { + collection: source_cw721.into_string(), msg: to_json_binary(&IbcOutgoingMsg { receiver: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), channel_id: "channel-0".to_string(), @@ -2061,8 +2153,9 @@ fn test_proxy_authorized() { memo: None, }) .unwrap(), - }, - }, + }) + .unwrap(), + }), &[], ) .unwrap(); @@ -2070,7 +2163,7 @@ fn test_proxy_authorized() { #[test] fn test_receive_nft() { - let mut test = Test::new(false, None, sg721_base_contract()); + let mut test = Test::new(false, false, None, None, sg721_base_contract()); // simplify: mint and escrowed/owned by ics721, as a precondition for receive nft let token_id = test.execute_cw721_mint(test.ics721.clone()).unwrap(); // ics721 receives NFT from sender/collection contract, @@ -2149,7 +2242,7 @@ fn test_receive_nft() { /// In case proxy for ICS721 is defined, ICS721 only accepts receival from proxy - not from nft contract! #[test] fn test_no_receive_with_proxy() { - let mut test = Test::new(true, None, sg721_base_contract()); + let mut test = Test::new(true, false, None, None, sg721_base_contract()); // unauthorized to receive nft from nft contract let err: ContractError = test .app @@ -2183,6 +2276,8 @@ fn test_no_receive_with_proxy() { fn test_pause() { let mut test = Test::new( true, + false, + None, Some(ICS721_ADMIN_AND_PAUSER.to_string()), sg721_base_contract(), ); @@ -2239,7 +2334,8 @@ fn test_pause() { new_code_id: ics721_id, msg: to_json_binary(&MigrateMsg::WithUpdate { pauser: Some(test.app.api().addr_make("new_pauser").to_string()), - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, cw721_base_code_id: None, }) .unwrap(), @@ -2265,6 +2361,8 @@ fn test_pause() { fn test_migration() { let mut test = Test::new( true, + false, + None, Some(ICS721_ADMIN_AND_PAUSER.to_string()), sg721_base_contract(), ); @@ -2274,7 +2372,7 @@ fn test_migration() { pauser, Some(test.app.api().addr_make(ICS721_ADMIN_AND_PAUSER)) ); - let proxy = test.query_proxy(); + let proxy = test.query_outgoing_proxy(); assert!(proxy.is_some()); let cw721_code_id = test.query_cw721_id(); assert_eq!(cw721_code_id, test.source_cw721_id); @@ -2288,7 +2386,8 @@ fn test_migration() { new_code_id: test.ics721_id, msg: to_json_binary(&MigrateMsg::WithUpdate { pauser: None, - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, cw721_base_code_id: Some(12345678), }) .unwrap(), @@ -2299,7 +2398,7 @@ fn test_migration() { // assert migration worked let (_, pauser) = test.query_pause_info(); assert_eq!(pauser, None); - let proxy = test.query_proxy(); + let proxy = test.query_outgoing_proxy(); assert!(proxy.is_none()); let cw721_code_id = test.query_cw721_id(); assert_eq!(cw721_code_id, 12345678); @@ -2313,7 +2412,8 @@ fn test_migration() { new_code_id: test.ics721_id, msg: to_json_binary(&MigrateMsg::WithUpdate { pauser: None, - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, cw721_base_code_id: None, }) .unwrap(), @@ -2324,7 +2424,7 @@ fn test_migration() { // assert migration worked let (_, pauser) = test.query_pause_info(); assert_eq!(pauser, None); - let proxy = test.query_proxy(); + let proxy = test.query_outgoing_proxy(); assert!(proxy.is_none()); let cw721_code_id = test.query_cw721_id(); assert_eq!(cw721_code_id, 12345678); diff --git a/e2e/adversarial_test.go b/e2e/adversarial_test.go index c4ce761a..139a0b16 100644 --- a/e2e/adversarial_test.go +++ b/e2e/adversarial_test.go @@ -77,6 +77,7 @@ func (suite *AdversarialTestSuite) SetupTest() { 2, nil, nil, + nil, } instantiateBridgeRaw, err := json.Marshal(instantiateBridge) require.NoError(suite.T(), err) @@ -244,7 +245,7 @@ func (suite *AdversarialTestSuite) TestInvalidOnMineValidOnTheirs() { ics721Nft(suite.T(), suite.chainA, suite.pathAC, suite.coordinator, chainACw721, "bad kid 1", suite.bridgeA, suite.chainA.SenderAccount.GetAddress(), suite.chainC.SenderAccount.GetAddress(), "") err = suite.chainA.SmartQuery(chainACw721, OwnerOfQuery{OwnerOf: OwnerOfQueryData{TokenID: suite.tokenIdA}}, &OwnerOfResponse{}) - require.ErrorContains(suite.T(), err, "cw721_base::state::TokenInfo> not found") + require.ErrorContains(suite.T(), err, "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found") // Send the NFT back, this time setting new metadata for the // class ID. @@ -477,7 +478,7 @@ func (suite *AdversarialTestSuite) TestMetadataForwarding() { require.ErrorContains( suite.T(), err, - "cw721_base::state::TokenInfo> not found", + "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found", ) // Check that token metadata was cleared. diff --git a/e2e/callback_test.go b/e2e/callback_test.go index d0520b55..8ecf69c1 100644 --- a/e2e/callback_test.go +++ b/e2e/callback_test.go @@ -70,6 +70,7 @@ func (suite *CbTestSuite) SetupTest() { "bad/kids", "bad/kids", suite.chainA.SenderAccount.GetAddress().String(), + nil, } instantiateRaw, err := json.Marshal(cw721Instantiate) require.NoError(suite.T(), err) @@ -82,6 +83,7 @@ func (suite *CbTestSuite) SetupTest() { 2, nil, nil, + nil, } instantiateBridgeRaw, err := json.Marshal(instantiateBridge) require.NoError(suite.T(), err) @@ -133,6 +135,7 @@ func (suite *CbTestSuite) SetupTest() { "bad/kids", "bad/kids", suite.chainA.SenderAccount.GetAddress().String(), + nil, } instantiateRaw, err := json.Marshal(cw721Instantiate) require.NoError(suite.T(), err) diff --git a/e2e/suite_test.go b/e2e/suite_test.go index 32140034..3524ad8d 100644 --- a/e2e/suite_test.go +++ b/e2e/suite_test.go @@ -53,6 +53,7 @@ func (suite *TransferTestSuite) SetupTest() { // no pauser nor proxy by default. nil, nil, + nil, } instantiateICS721Raw, err := json.Marshal(instantiateICS721) require.NoError(suite.T(), err) @@ -114,6 +115,7 @@ func (suite *TransferTestSuite) TestIBCSendNFT() { "bad/kids", "bad/kids", suite.chainA.SenderAccount.GetAddress().String(), + nil, } instantiateRaw, err := json.Marshal(cw721Instantiate) require.NoError(suite.T(), err) @@ -268,6 +270,7 @@ func instantiateBridge(t *testing.T, chain *wasmibctesting.TestChain) sdk.AccAdd cw721resp.CodeID, nil, nil, + nil, } instantiateICS721Raw, err := json.Marshal(instantiateICS721) require.NoError(t, err) @@ -280,6 +283,7 @@ func instantiateCw721(t *testing.T, chain *wasmibctesting.TestChain) sdk.AccAddr "bad/kids", "bad/kids", chain.SenderAccount.GetAddress().String(), + nil, } instantiateRaw, err := json.Marshal(cw721Instantiate) require.NoError(t, err) @@ -485,7 +489,7 @@ func TestSendBetweenThreeIdenticalChains(t *testing.T) { // contract "is this burned" so we just query and make sure it // now errors with a storage load failure. err := chainA.SmartQuery(chainANftDerivative, OwnerOfQuery{OwnerOf: OwnerOfQueryData{TokenID: "bad kid 1"}}, &OwnerOfResponse{}) - require.ErrorContains(t, err, "cw721_base::state::TokenInfo> not found") + require.ErrorContains(t, err, "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found") // NFT should belong to chainC sender on chain C. ownerC = queryGetOwnerOf(t, chainC, chainCNft, "bad kid 1") @@ -501,7 +505,7 @@ func TestSendBetweenThreeIdenticalChains(t *testing.T) { // Burned on C. err = chainC.SmartQuery(chainCNft, OwnerOfQuery{OwnerOf: OwnerOfQueryData{TokenID: "bad kid 1"}}, &OwnerOfResponse{}) - require.ErrorContains(t, err, "cw721_base::state::TokenInfo> not found") + require.ErrorContains(t, err, "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found") // B -> A path = getPath(1, 0) @@ -513,7 +517,7 @@ func TestSendBetweenThreeIdenticalChains(t *testing.T) { // Burned on chain B. err = chainB.SmartQuery(chainBNft, OwnerOfQuery{OwnerOf: OwnerOfQueryData{TokenID: "bad kid 1"}}, &OwnerOfResponse{}) - require.ErrorContains(t, err, "cw721_base::state::TokenInfo> not found") + require.ErrorContains(t, err, "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found") // Hooray! We have completed the journey between three // identical blockchains using our ICS721 contract. @@ -569,7 +573,7 @@ func (suite *TransferTestSuite) TestMultipleAddressesInvolved() { // Make sure the NFT was burned on chain B err = suite.chainB.SmartQuery(chainBNft, OwnerOfQuery{OwnerOf: OwnerOfQueryData{TokenID: "bad kid 1"}}, &OwnerOfResponse{}) - require.ErrorContains(suite.T(), err, "cw721_base::state::TokenInfo> not found") + require.ErrorContains(suite.T(), err, "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found") // Make another account on chain B and transfer to the new account. anotherAcount := CreateAndFundAccount(suite.T(), suite.chainB, 19) @@ -587,7 +591,7 @@ func (suite *TransferTestSuite) TestMultipleAddressesInvolved() { // Make sure it was burned on B. err = suite.chainB.SmartQuery(chainBNft, OwnerOfQuery{OwnerOf: OwnerOfQueryData{TokenID: "bad kid 1"}}, &OwnerOfResponse{}) - require.ErrorContains(suite.T(), err, "cw721_base::state::TokenInfo> not found") + require.ErrorContains(suite.T(), err, "cw721_base::state::TokenInfo>; key: [00, 06, 74, 6F, 6B, 65, 6E, 73, 62, 61, 64, 20, 6B, 69, 64, 20, 31] not found") // Make sure it is owned by the correct address on A. resp := OwnerOfResponse{} @@ -618,6 +622,7 @@ func TestCloseRejected(t *testing.T) { 2, nil, nil, + nil, } instantiateICS721Raw, err := json.Marshal(instantiateICS721) require.NoError(t, err) diff --git a/e2e/test.sh b/e2e/test.sh index c5f5b7fb..a50d6df6 100755 --- a/e2e/test.sh +++ b/e2e/test.sh @@ -1,7 +1,8 @@ #!/bin/bash SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) # source: https://stackoverflow.com/a/246128/3437868 WORKSPACE_DIR=$(cd $SCRIPT_DIR/.. && pwd) -echo "!!! NOTE: for a clean test it is recommended to delete wasm files: sudo rm -rf $WORKSPACE_DIR/artifacts) !!!" +echo "sudo rm -rf $WORKSPACE_DIR/artifacts" +sudo rm -rf $WORKSPACE_DIR/artifacts $WORKSPACE_DIR/ts-relayer-tests/build.sh echo "running tests..." go test $SCRIPT_DIR \ No newline at end of file diff --git a/e2e/types.go b/e2e/types.go index c69776c6..42baaa35 100644 --- a/e2e/types.go +++ b/e2e/types.go @@ -25,7 +25,8 @@ type ModuleInstantiateInfo struct { type InstantiateICS721Bridge struct { CW721CodeID uint64 `json:"cw721_base_code_id"` - Proxy *ModuleInstantiateInfo `json:"proxy"` + OutgoingProxy *ModuleInstantiateInfo `json:"outgoing_proxy"` + IncomingProxy *ModuleInstantiateInfo `json:"incoming_proxy"` Pauser *string `json:"pauser"` } @@ -33,6 +34,7 @@ type InstantiateCw721 struct { Name string `json:"name"` Symbol string `json:"symbol"` Minter string `json:"minter"` + WithdrawAddress *string `json:"withdraw_address"` } type InstantiateBridgeTester struct { diff --git a/external-wasms/cw721_base_v0.18.0.wasm b/external-wasms/cw721_base_v0.18.0.wasm index 74fba98c..86f06696 100644 Binary files a/external-wasms/cw721_base_v0.18.0.wasm and b/external-wasms/cw721_base_v0.18.0.wasm differ diff --git a/external-wasms/cw721_incoming_proxy.wasm b/external-wasms/cw721_incoming_proxy.wasm new file mode 100644 index 00000000..96a03f96 Binary files /dev/null and b/external-wasms/cw721_incoming_proxy.wasm differ diff --git a/external-wasms/cw721_outgoing_proxy_rate_limit.wasm b/external-wasms/cw721_outgoing_proxy_rate_limit.wasm new file mode 100644 index 00000000..803f471f Binary files /dev/null and b/external-wasms/cw721_outgoing_proxy_rate_limit.wasm differ diff --git a/packages/cw-pause-once/src/lib.rs b/packages/cw-pause-once/src/lib.rs index df1d7d97..0fb16ed6 100644 --- a/packages/cw-pause-once/src/lib.rs +++ b/packages/cw-pause-once/src/lib.rs @@ -21,8 +21,8 @@ pub enum PauseError { } pub struct PauseOrchestrator<'a> { - pauser: Item<'a, Option>, - paused: Item<'a, bool>, + pub pauser: Item<'a, Option>, + pub paused: Item<'a, bool>, } impl<'a> PauseOrchestrator<'a> { diff --git a/packages/ics721-types/Cargo.toml b/packages/ics721-types/Cargo.toml new file mode 100644 index 00000000..1756369e --- /dev/null +++ b/packages/ics721-types/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "ics721-types" +version = "0.1.0" +edition = "2021" +authors = ["ekez ", "mr-t ", "Art3mix "] +description = "an implementation of the ICS721 specification for transfering NFTs between blockchains" + +[dependencies] +cosmwasm-std = { workspace = true, features = ["cosmwasm_1_2"] } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw721 = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } diff --git a/packages/ics721-types/README b/packages/ics721-types/README new file mode 100644 index 00000000..ed516796 --- /dev/null +++ b/packages/ics721-types/README @@ -0,0 +1,3 @@ +# ICS721 Types Package + +Contains all types being used by ICS721, Incoming Proxy, and Outgoing Proxy. \ No newline at end of file diff --git a/packages/ics721-types/src/error.rs b/packages/ics721-types/src/error.rs new file mode 100644 index 00000000..73b2ebcb --- /dev/null +++ b/packages/ics721-types/src/error.rs @@ -0,0 +1,16 @@ +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum Ics721Error { + #[error("empty class ID")] + EmptyClassId {}, + + #[error("must transfer at least one token")] + NoTokens {}, + + #[error("optional fields may not be empty if provided")] + EmptyOptional {}, + + #[error("tokenIds, tokenUris, and tokenData must have the same length")] + TokenInfoLenMissmatch {}, +} diff --git a/packages/ics721-types/src/ibc_types.rs b/packages/ics721-types/src/ibc_types.rs new file mode 100644 index 00000000..ed43aa0c --- /dev/null +++ b/packages/ics721-types/src/ibc_types.rs @@ -0,0 +1,183 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Binary, IbcTimeout}; + +use crate::{ + error::Ics721Error, + token_types::{ClassId, TokenId}, +}; + +#[cw_serde] +#[serde(rename_all = "camelCase")] +pub struct NonFungibleTokenPacketData { + /// Uniquely identifies the collection which the tokens being + /// transfered belong to on the sending chain. Must be non-empty. + pub class_id: ClassId, + /// Optional URL that points to metadata about the + /// collection. Must be non-empty if provided. + pub class_uri: Option, + /// Optional base64 encoded field which contains on-chain metadata + /// about the NFT class. Must be non-empty if provided. + pub class_data: Option, + /// Uniquely identifies the tokens in the NFT collection being + /// transfered. This MUST be non-empty. + pub token_ids: Vec, + /// Optional URL that points to metadata for each token being + /// transfered. `tokenUris[N]` should hold the metadata for + /// `tokenIds[N]` and both lists should have the same if + /// provided. Must be non-empty if provided. + pub token_uris: Option>, + /// Optional base64 encoded metadata for the tokens being + /// transfered. `tokenData[N]` should hold metadata for + /// `tokenIds[N]` and both lists should have the same length if + /// provided. Must be non-empty if provided. + pub token_data: Option>, + + /// The address sending the tokens on the sending chain. + pub sender: String, + /// The address that should receive the tokens on the receiving + /// chain. + pub receiver: String, + /// Memo to add custom string to the msg + pub memo: Option, +} + +macro_rules! non_empty_optional { + ($e:expr) => { + if $e.map_or(false, |data| data.is_empty()) { + return Err(Ics721Error::EmptyOptional {}); + } + }; +} + +impl NonFungibleTokenPacketData { + pub fn validate(&self) -> Result<(), Ics721Error> { + if self.class_id.is_empty() { + return Err(Ics721Error::EmptyClassId {}); + } + + non_empty_optional!(self.class_uri.as_ref()); + non_empty_optional!(self.class_data.as_ref()); + + let token_count = self.token_ids.len(); + if token_count == 0 { + return Err(Ics721Error::NoTokens {}); + } + + // Non-empty optionality of tokenData an tokenUris implicitly + // checked here. + if self + .token_data + .as_ref() + .map_or(false, |data| data.len() != token_count) + || self + .token_uris + .as_ref() + .map_or(false, |data| data.len() != token_count) + { + return Err(Ics721Error::TokenInfoLenMissmatch {}); + } + + // This contract assumes that the backing cw721 is functional, + // so no need to check tokenIds for duplicates as the cw721 + // will prevent minting of duplicates. + + Ok(()) + } +} + +#[cw_serde] +pub struct IbcOutgoingMsg { + /// The address that should receive the NFT being sent on the + /// *receiving chain*. + pub receiver: String, + /// The *local* channel ID this ought to be sent away on. This + /// contract must have a connection on this channel. + pub channel_id: String, + /// Timeout for the IBC message. + pub timeout: IbcTimeout, + /// Memo to add custom string to the msg + pub memo: Option, +} + +#[cw_serde] +pub struct IbcOutgoingProxyMsg { + pub collection: String, + pub msg: Binary, +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::token_types::{ClassId, TokenId}; + + #[test] + fn test_packet_validation() { + let default_token = NonFungibleTokenPacketData { + class_id: ClassId::new("id"), + class_uri: None, + class_data: None, + token_ids: vec![TokenId::new("1")], + token_uris: None, + token_data: None, + sender: "violet".to_string(), + receiver: "blue".to_string(), + memo: None, + }; + + let empty_class_id = NonFungibleTokenPacketData { + class_id: ClassId::new(""), + ..default_token.clone() + }; + let err = empty_class_id.validate().unwrap_err(); + assert_eq!(err, Ics721Error::EmptyClassId {}); + + let empty_class_uri = NonFungibleTokenPacketData { + class_uri: Some("".to_string()), + ..default_token.clone() + }; + let err = empty_class_uri.validate().unwrap_err(); + assert_eq!(err, Ics721Error::EmptyOptional {}); + + let empty_class_data = NonFungibleTokenPacketData { + class_data: Some(Binary::default()), + ..default_token.clone() + }; + let err = empty_class_data.validate().unwrap_err(); + assert_eq!(err, Ics721Error::EmptyOptional {}); + + let no_tokens = NonFungibleTokenPacketData { + token_ids: vec![], + ..default_token.clone() + }; + let err = no_tokens.validate().unwrap_err(); + assert_eq!(err, Ics721Error::NoTokens {}); + + let uri_imbalance_empty = NonFungibleTokenPacketData { + token_uris: Some(vec![]), + ..default_token.clone() + }; + let err = uri_imbalance_empty.validate().unwrap_err(); + assert_eq!(err, Ics721Error::TokenInfoLenMissmatch {}); + + let uri_imbalance = NonFungibleTokenPacketData { + token_uris: Some(vec!["a".to_string(), "b".to_string()]), + ..default_token.clone() + }; + let err = uri_imbalance.validate().unwrap_err(); + assert_eq!(err, Ics721Error::TokenInfoLenMissmatch {}); + + let data_imbalance_empty = NonFungibleTokenPacketData { + token_data: Some(vec![]), + ..default_token.clone() + }; + let err = data_imbalance_empty.validate().unwrap_err(); + assert_eq!(err, Ics721Error::TokenInfoLenMissmatch {}); + + let data_imbalance = NonFungibleTokenPacketData { + token_data: Some(vec![Binary::default(), Binary::default()]), + ..default_token + }; + let err = data_imbalance.validate().unwrap_err(); + assert_eq!(err, Ics721Error::TokenInfoLenMissmatch {}); + } +} diff --git a/packages/ics721-types/src/lib.rs b/packages/ics721-types/src/lib.rs new file mode 100644 index 00000000..d811044e --- /dev/null +++ b/packages/ics721-types/src/lib.rs @@ -0,0 +1,4 @@ +pub mod error; +pub mod ibc_types; +pub mod token_types; +pub mod types; diff --git a/packages/ics721-types/src/token_types.rs b/packages/ics721-types/src/token_types.rs new file mode 100644 index 00000000..78a9590d --- /dev/null +++ b/packages/ics721-types/src/token_types.rs @@ -0,0 +1,149 @@ +use std::ops::Deref; + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Binary, StdResult}; +use cw_storage_plus::{Bound, Bounder, Key, KeyDeserialize, Prefixer, PrimaryKey}; + +/// A token ID according to the ICS-721 spec. The newtype pattern is +/// used here to provide some distinction between token and class IDs +/// in the type system. +#[cw_serde] +pub struct TokenId(String); + +/// A token according to the ICS-721 spec. +#[cw_serde] +pub struct Token { + /// A unique identifier for the token. + pub id: TokenId, + /// Optional URI pointing to off-chain metadata about the token. + pub uri: Option, + /// Optional base64 encoded metadata about the token. + pub data: Option, +} + +/// A class ID according to the ICS-721 spec. The newtype pattern is +/// used here to provide some distinction between token and class IDs +/// in the type system. +#[cw_serde] +pub struct ClassId(String); + +#[cw_serde] +pub struct Class { + /// A unique (from the source chain's perspective) identifier for + /// the class. + pub id: ClassId, + /// Optional URI pointing to off-chain metadata about the class. + pub uri: Option, + /// Optional base64 encoded metadata about the class. + pub data: Option, +} + +impl TokenId { + pub fn new(token_id: T) -> Self + where + T: Into, + { + Self(token_id.into()) + } +} + +impl ClassId { + pub fn new(class_id: T) -> Self + where + T: Into, + { + Self(class_id.into()) + } +} + +#[cw_serde] +pub struct ClassToken { + pub class_id: ClassId, + pub token_id: TokenId, +} + +impl<'a> Bounder<'a> for ClassId { + fn inclusive_bound(self) -> Option> { + Some(Bound::inclusive(self)) + } + + fn exclusive_bound(self) -> Option> { + Some(Bound::exclusive(self)) + } +} + +// Allow ClassId to be inferred into String +impl From for String { + fn from(c: ClassId) -> Self { + c.0 + } +} + +impl From for String { + fn from(t: TokenId) -> Self { + t.0 + } +} + +impl Deref for ClassId { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::fmt::Display for ClassId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +// Allow ClassId to be inferred into Key - using String.key() +impl<'a> PrimaryKey<'a> for ClassId { + type Prefix = >::Prefix; + type SubPrefix = >::SubPrefix; + type Suffix = >::Suffix; + type SuperSuffix = >::SuperSuffix; + + fn key(&self) -> Vec { + self.0.key() + } +} + +impl<'a> PrimaryKey<'a> for TokenId { + type Prefix = >::Prefix; + type SubPrefix = >::SubPrefix; + type Suffix = >::Suffix; + type SuperSuffix = >::SuperSuffix; + + fn key(&self) -> Vec { + self.0.key() + } +} + +impl<'a> Prefixer<'a> for ClassId { + fn prefix(&self) -> Vec { + self.0.prefix() + } +} + +impl<'a> Prefixer<'a> for TokenId { + fn prefix(&self) -> Vec { + self.0.prefix() + } +} + +impl KeyDeserialize for ClassId { + type Output = ::Output; + fn from_vec(value: Vec) -> StdResult { + String::from_vec(value) + } +} + +impl KeyDeserialize for TokenId { + type Output = ::Output; + fn from_vec(value: Vec) -> StdResult { + String::from_vec(value) + } +} diff --git a/packages/ics721/src/types.rs b/packages/ics721-types/src/types.rs similarity index 87% rename from packages/ics721/src/types.rs rename to packages/ics721-types/src/types.rs index e181e04f..69160e94 100644 --- a/packages/ics721/src/types.rs +++ b/packages/ics721-types/src/types.rs @@ -1,8 +1,8 @@ use cosmwasm_schema::{cw_serde, schemars::JsonSchema}; -use cosmwasm_std::Binary; +use cosmwasm_std::{Binary, IbcPacket}; use serde::{Deserialize, Serialize}; -use crate::ibc::NonFungibleTokenPacketData; +use crate::ibc_types::NonFungibleTokenPacketData; #[derive(Serialize, Deserialize, JsonSchema, Clone, Debug, PartialEq)] #[allow(clippy::derive_partial_eq_without_eq)] @@ -68,4 +68,12 @@ pub enum ReceiverExecuteMsg { /// Being called as a status update of the transfer. (source side) /// Note - Failing this message will NOT fail the transfer, its just a status update. Ics721AckCallback(Ics721AckCallbackMsg), + + /// Being called on receiving the NFT before transfer is completed. (destination side) + /// `on_recieve` hook + /// Note - Failing this message will fail the transfer. + Ics721ReceivePacketMsg { + packet: IbcPacket, + data: NonFungibleTokenPacketData, + }, } diff --git a/packages/ics721/Cargo.toml b/packages/ics721/Cargo.toml index 3f9d7519..e850a9fb 100644 --- a/packages/ics721/Cargo.toml +++ b/packages/ics721/Cargo.toml @@ -15,10 +15,10 @@ cw-utils = { workspace = true } cw721 = { workspace = true } cw721-base = { workspace = true, features = ["library"] } cw721-base-016 = { workspace = true, features = ["library"] } +ics721-types = { workspace = true } thiserror = { workspace = true } serde = { workspace = true } cw-paginate-storage = { workspace = true } -cw721-proxy-derive = { workspace = true } cw-pause-once = { workspace = true } cw-cii = { workspace = true } sha2 = { workspace = true } @@ -26,7 +26,8 @@ zip-optional = { workspace = true } [dev-dependencies] anyhow = { workspace = true } +cw-ics721-incoming-proxy-base = { workspace = true } +cw-ics721-outgoing-proxy-rate-limit = { workspace = true } cw-multi-test = { workspace = true } cw2 = { workspace = true } cw721-016 = { workspace = true } -cw721-rate-limited-proxy = { workspace = true } diff --git a/packages/ics721/schema/ics721.json b/packages/ics721/schema/ics721.json index 2efdfd0c..863f9db2 100644 --- a/packages/ics721/schema/ics721.json +++ b/packages/ics721/schema/ics721.json @@ -1,6 +1,6 @@ { "contract_name": "ics721", - "contract_version": "0.0.1", + "contract_version": "0.1.0", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", @@ -16,15 +16,19 @@ "format": "uint64", "minimum": 0.0 }, - "pauser": { - "description": "Address that may pause the contract. PAUSER may pause the contract a single time; in pausing the contract they burn the right to do so again. A new pauser may be later nominated by the CosmWasm level admin via a migration.", - "type": [ - "string", - "null" + "incoming_proxy": { + "description": "An optional proxy contract. If an incoming proxy is set, the contract will call it and pass IbcPacket. The proxy is expected to implement the Ics721ReceiveIbcPacketMsg for message execution.", + "anyOf": [ + { + "$ref": "#/definitions/ContractInstantiateInfo" + }, + { + "type": "null" + } ] }, - "proxy": { - "description": "An optional proxy contract. If a proxy is set the contract will only accept NFTs from that proxy. The proxy is expected to implement the cw721 proxy interface defined in the cw721-proxy crate.", + "outgoing_proxy": { + "description": "An optional proxy contract. If an outging proxy is set, the contract will only accept NFTs from that proxy. The proxy is expected to implement the cw721 proxy interface defined in the cw721-outgoing-proxy crate.", "anyOf": [ { "$ref": "#/definitions/ContractInstantiateInfo" @@ -33,6 +37,13 @@ "type": "null" } ] + }, + "pauser": { + "description": "Address that may pause the contract. PAUSER may pause the contract a single time; in pausing the contract they burn the right to do so again. A new pauser may be later nominated by the CosmWasm level admin via a migration.", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false, @@ -562,7 +573,58 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code using a predictable address derivation algorithm implemented in [`cosmwasm_std::instantiate2_address`].\n\nThis is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). `sender` is automatically filled with the current contract's address. `fix_msg` is automatically set to false.", + "type": "object", + "required": [ + "instantiate2" + ], + "properties": { + "instantiate2": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg", + "salt" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { @@ -572,6 +634,9 @@ "$ref": "#/definitions/Binary" } ] + }, + "salt": { + "$ref": "#/definitions/Binary" } } } @@ -815,13 +880,27 @@ "additionalProperties": false }, { - "description": "Gets this contract's cw721-proxy if one is set.", + "description": "Gets this contract's outgoing cw721-outgoing-proxy if one is set.", + "type": "object", + "required": [ + "outgoing_proxy" + ], + "properties": { + "outgoing_proxy": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets this contract's incoming cw721-outgoing-proxy if one is set.", "type": "object", "required": [ - "proxy" + "incoming_proxy" ], "properties": { - "proxy": { + "incoming_proxy": { "type": "object", "additionalProperties": false } @@ -1095,6 +1174,24 @@ } } }, + "incoming_proxy": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "nft_contract": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Nullable_Addr", @@ -1179,6 +1276,24 @@ } } }, + "outgoing_proxy": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "owner": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "OwnerOfResponse", @@ -1308,24 +1423,6 @@ } } }, - "proxy": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_Addr", - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, "token_metadata": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Nullable_Token", diff --git a/packages/ics721/schema/raw/execute.json b/packages/ics721/schema/raw/execute.json index 87023eee..6e99d45c 100644 --- a/packages/ics721/schema/raw/execute.json +++ b/packages/ics721/schema/raw/execute.json @@ -447,7 +447,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { @@ -463,6 +463,60 @@ }, "additionalProperties": false }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code using a predictable address derivation algorithm implemented in [`cosmwasm_std::instantiate2_address`].\n\nThis is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). `sender` is automatically filled with the current contract's address. `fix_msg` is automatically set to false.", + "type": "object", + "required": [ + "instantiate2" + ], + "properties": { + "instantiate2": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg", + "salt" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "salt": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, { "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", "type": "object", diff --git a/packages/ics721/schema/raw/instantiate.json b/packages/ics721/schema/raw/instantiate.json index cbc071c4..f431f451 100644 --- a/packages/ics721/schema/raw/instantiate.json +++ b/packages/ics721/schema/raw/instantiate.json @@ -12,15 +12,19 @@ "format": "uint64", "minimum": 0.0 }, - "pauser": { - "description": "Address that may pause the contract. PAUSER may pause the contract a single time; in pausing the contract they burn the right to do so again. A new pauser may be later nominated by the CosmWasm level admin via a migration.", - "type": [ - "string", - "null" + "incoming_proxy": { + "description": "An optional proxy contract. If an incoming proxy is set, the contract will call it and pass IbcPacket. The proxy is expected to implement the Ics721ReceiveIbcPacketMsg for message execution.", + "anyOf": [ + { + "$ref": "#/definitions/ContractInstantiateInfo" + }, + { + "type": "null" + } ] }, - "proxy": { - "description": "An optional proxy contract. If a proxy is set the contract will only accept NFTs from that proxy. The proxy is expected to implement the cw721 proxy interface defined in the cw721-proxy crate.", + "outgoing_proxy": { + "description": "An optional proxy contract. If an outging proxy is set, the contract will only accept NFTs from that proxy. The proxy is expected to implement the cw721 proxy interface defined in the cw721-outgoing-proxy crate.", "anyOf": [ { "$ref": "#/definitions/ContractInstantiateInfo" @@ -29,6 +33,13 @@ "type": "null" } ] + }, + "pauser": { + "description": "Address that may pause the contract. PAUSER may pause the contract a single time; in pausing the contract they burn the right to do so again. A new pauser may be later nominated by the CosmWasm level admin via a migration.", + "type": [ + "string", + "null" + ] } }, "additionalProperties": false, diff --git a/packages/ics721/schema/raw/query.json b/packages/ics721/schema/raw/query.json index 0af38314..9a6d14f2 100644 --- a/packages/ics721/schema/raw/query.json +++ b/packages/ics721/schema/raw/query.json @@ -148,13 +148,27 @@ "additionalProperties": false }, { - "description": "Gets this contract's cw721-proxy if one is set.", + "description": "Gets this contract's outgoing cw721-outgoing-proxy if one is set.", "type": "object", "required": [ - "proxy" + "outgoing_proxy" ], "properties": { - "proxy": { + "outgoing_proxy": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Gets this contract's incoming cw721-outgoing-proxy if one is set.", + "type": "object", + "required": [ + "incoming_proxy" + ], + "properties": { + "incoming_proxy": { "type": "object", "additionalProperties": false } diff --git a/packages/ics721/schema/raw/response_to_incoming_proxy.json b/packages/ics721/schema/raw/response_to_incoming_proxy.json new file mode 100644 index 00000000..970164b3 --- /dev/null +++ b/packages/ics721/schema/raw/response_to_incoming_proxy.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} diff --git a/packages/ics721/schema/raw/response_to_outgoing_proxy.json b/packages/ics721/schema/raw/response_to_outgoing_proxy.json new file mode 100644 index 00000000..970164b3 --- /dev/null +++ b/packages/ics721/schema/raw/response_to_outgoing_proxy.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Nullable_Addr", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ], + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} diff --git a/packages/ics721/src/error.rs b/packages/ics721/src/error.rs index 876eda4d..5f7d04e0 100644 --- a/packages/ics721/src/error.rs +++ b/packages/ics721/src/error.rs @@ -1,10 +1,14 @@ -use cosmwasm_std::{Instantiate2AddressError, StdError}; +use cosmwasm_std::{Binary, Instantiate2AddressError, StdError}; use cw_pause_once::PauseError; use cw_utils::ParseReplyError; +use ics721_types::error::Ics721Error; use thiserror::Error; #[derive(Error, Debug, PartialEq)] pub enum ContractError { + #[error(transparent)] + Ics721Error(#[from] Ics721Error), + #[error(transparent)] Std(#[from] StdError), @@ -17,6 +21,12 @@ pub enum ContractError { #[error("unauthorized")] Unauthorized {}, + #[error("unauthorized")] + UnknownMsg(Binary), + + #[error("NFT not escrowed by ICS721! Owner: {0}")] + NotEscrowedByIcs721(String), + #[error("only unordered channels are supported")] OrderedChannel {}, @@ -26,40 +36,12 @@ pub enum ContractError { #[error("ICS 721 channels may not be closed")] CantCloseChannel {}, - #[error("unrecognised class ID")] - UnrecognisedClassId {}, - - #[error("class ID already exists")] - ClassIdAlreadyExists {}, - - #[error("empty class ID")] - EmptyClassId {}, - - #[error("must transfer at least one token")] - NoTokens {}, - - #[error("optional fields may not be empty if provided")] - EmptyOptional {}, - #[error("unrecognised reply ID")] UnrecognisedReplyId {}, #[error(transparent)] ParseReplyError(#[from] ParseReplyError), - #[error("must provide same number of token IDs and URIs")] - ImbalancedTokenInfo {}, - - #[error("unexpected uri for classID {class_id} - got ({actual:?}), expected ({expected:?})")] - ClassUriClash { - class_id: String, - expected: Option, - actual: Option, - }, - - #[error("tokenIds, tokenUris, and tokenData must have the same length")] - TokenInfoLenMissmatch {}, - #[error("Transfer contains both redemption and a creation action")] InvalidTransferBothActions, diff --git a/packages/ics721/src/execute.rs b/packages/ics721/src/execute.rs index 990ae8ec..9eb345ac 100644 --- a/packages/ics721/src/execute.rs +++ b/packages/ics721/src/execute.rs @@ -1,22 +1,29 @@ use std::fmt::Debug; use cosmwasm_std::{ - from_json, to_json_binary, Addr, Binary, Deps, DepsMut, Empty, Env, IbcMsg, MessageInfo, - Response, StdResult, SubMsg, WasmMsg, + from_json, to_json_binary, Addr, Binary, ContractInfoResponse, Deps, DepsMut, Empty, Env, + IbcMsg, MessageInfo, Response, StdResult, SubMsg, WasmMsg, +}; +use ics721_types::{ + ibc_types::{IbcOutgoingMsg, IbcOutgoingProxyMsg, NonFungibleTokenPacketData}, + token_types::{Class, ClassId, Token, TokenId}, }; use serde::{de::DeserializeOwned, Serialize}; use sha2::{Digest, Sha256}; use crate::{ helpers::get_instantiate2_address, - ibc::{NonFungibleTokenPacketData, INSTANTIATE_CW721_REPLY_ID, INSTANTIATE_PROXY_REPLY_ID}, - msg::{CallbackMsg, ExecuteMsg, IbcOutgoingMsg, InstantiateMsg, MigrateMsg}, + ibc::{ + INSTANTIATE_CW721_REPLY_ID, INSTANTIATE_INCOMING_PROXY_REPLY_ID, + INSTANTIATE_OUTGOING_PROXY_REPLY_ID, + }, + msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg}, state::{ CollectionData, UniversalAllNftInfoResponse, CLASS_ID_TO_CLASS, CLASS_ID_TO_NFT_CONTRACT, - CW721_CODE_ID, NFT_CONTRACT_TO_CLASS_ID, OUTGOING_CLASS_TOKEN_TO_CHANNEL, PO, PROXY, - TOKEN_METADATA, + CW721_CODE_ID, INCOMING_PROXY, NFT_CONTRACT_TO_CLASS_ID, OUTGOING_CLASS_TOKEN_TO_CHANNEL, + OUTGOING_PROXY, PO, TOKEN_METADATA, }, - token_types::{Class, ClassId, Token, TokenId, VoucherCreation, VoucherRedemption}, + token_types::{VoucherCreation, VoucherRedemption}, ContractError, }; @@ -34,17 +41,29 @@ where msg: InstantiateMsg, ) -> StdResult> { CW721_CODE_ID.save(deps.storage, &msg.cw721_base_code_id)?; - PROXY.save(deps.storage, &None)?; + // proxy contracts are optional + INCOMING_PROXY.save(deps.storage, &None)?; + OUTGOING_PROXY.save(deps.storage, &None)?; PO.set_pauser(deps.storage, deps.api, msg.pauser.as_deref())?; - let proxy_instantiate = msg - .proxy - .map(|m| m.into_wasm_msg(env.contract.address)) - .map(|wasm| SubMsg::reply_on_success(wasm, INSTANTIATE_PROXY_REPLY_ID)) - .map_or(vec![], |s| vec![s]); + let mut proxies_instantiate: Vec> = Vec::new(); + if let Some(cii) = msg.incoming_proxy { + proxies_instantiate.push(SubMsg::reply_on_success( + cii.into_wasm_msg(env.clone().contract.address), + // on reply proxy contract is set in INCOMING_PROXY + INSTANTIATE_INCOMING_PROXY_REPLY_ID, + )); + } + if let Some(cii) = msg.outgoing_proxy { + proxies_instantiate.push(SubMsg::reply_on_success( + cii.into_wasm_msg(env.contract.address), + // on reply proxy contract is set in OUTGOING_PROXY + INSTANTIATE_OUTGOING_PROXY_REPLY_ID, + )); + } Ok(Response::default() - .add_submessages(proxy_instantiate) + .add_submessages(proxies_instantiate) .add_attribute("method", "instantiate") .add_attribute("cw721_code_id", msg.cw721_base_code_id.to_string())) } @@ -63,54 +82,74 @@ where token_id, msg, }) => self.execute_receive_nft(deps, env, info, token_id, sender, msg), - ExecuteMsg::ReceiveProxyNft { eyeball, msg } => { - self.execute_receive_proxy_nft(deps, env, info, eyeball, msg) - } ExecuteMsg::Pause {} => self.execute_pause(deps, info), ExecuteMsg::Callback(msg) => self.execute_callback(deps, env, info, msg), } } + /// ICS721 may receive an NFT from 2 sources: + /// 1. From a local cw721 contract (e.g. cw721-base) + /// 2. From a(n outgoing) proxy contract. + /// + /// In case of 2. outgoing proxy calls 2 messages: + /// a) tranfer NFT to ICS721 + /// b) call/forwards "ReceiveNFt" message to ICS721. + /// + /// Unlike 1) proxy passes in b) an IbcOutgoingProxyMsg (and not an IbcOutgoingMsg) + /// which also holds the collection address, since info.sender + /// is the proxy contract - and not the collection. + /// + /// NB: outgoing proxy can use `SendNft` on collectio and pass it directly to ICS721, + /// since one `OUTGOING_PROXY` is defined in ICS721, it accepts only NFT receives from this proxy. fn execute_receive_nft( &self, deps: DepsMut, env: Env, info: MessageInfo, token_id: String, - sender: String, + nft_owner: String, msg: Binary, ) -> Result, ContractError> { - if PROXY.load(deps.storage)?.is_some() { - Err(ContractError::Unauthorized {}) - } else { - self.receive_nft(deps, env, info, TokenId::new(token_id), sender, msg) - } - } - - fn execute_receive_proxy_nft( - &self, - deps: DepsMut, - env: Env, - info: MessageInfo, - eyeball: String, - msg: cw721::Cw721ReceiveMsg, - ) -> Result, ContractError> { - if PROXY - .load(deps.storage)? - .map_or(true, |proxy| info.sender != proxy) - { - return Err(ContractError::Unauthorized {}); - } - let mut info = info; - info.sender = deps.api.addr_validate(&eyeball)?; - let cw721::Cw721ReceiveMsg { - token_id, - sender, - msg, - } = msg; - let res = self.receive_nft(deps, env, info, TokenId::new(token_id), sender, msg)?; - // override method key - Ok(res.add_attribute("method", "execute_receive_proxy_nft")) + // if there is an outgoing proxy, we need to check if the msg is IbcOutgoingProxyMsg + let result = match OUTGOING_PROXY.load(deps.storage)? { + Some(proxy) => { + // accept only messages from the proxy + if proxy != info.sender { + return Err(ContractError::Unauthorized {}); + } + from_json::(msg.clone()) + .ok() + .map(|msg| { + let mut info = info; + match deps.api.addr_validate(&msg.collection) { + Ok(collection_addr) => { + // set collection address as (initial) sender + info.sender = collection_addr; + self.receive_nft( + deps, + env, + info, + TokenId::new(token_id), + nft_owner, + msg.msg, + ) + } + Err(err) => Err(ContractError::Std(err)), + } + }) + } + None => from_json::(msg.clone()).ok().map(|_| { + self.receive_nft( + deps, + env, + info, + TokenId::new(token_id), + nft_owner, + msg.clone(), + ) + }), + }; + result.ok_or(ContractError::UnknownMsg(msg))? } fn get_class_data(&self, deps: &DepsMut, sender: &Addr) -> StdResult>; @@ -121,10 +160,10 @@ where env: Env, info: MessageInfo, token_id: TokenId, - sender: String, + nft_owner: String, msg: Binary, ) -> Result, ContractError> { - let sender = deps.api.addr_validate(&sender)?; + let nft_owner = deps.api.addr_validate(&nft_owner)?; let msg: IbcOutgoingMsg = from_json(msg)?; let class = match NFT_CONTRACT_TO_CLASS_ID.may_load(deps.storage, info.sender.clone())? { @@ -162,7 +201,7 @@ where }, )?; if access.owner != env.contract.address { - return Err(ContractError::Unauthorized {}); + return Err(ContractError::NotEscrowedByIcs721(access.owner)); } // cw721 doesn't support on-chain metadata yet @@ -181,7 +220,7 @@ where token_uris: info.token_uri.map(|uri| vec![uri]), token_data: token_metadata.map(|metadata| vec![metadata]), - sender: sender.into_string(), + sender: nft_owner.into_string(), receiver: msg.receiver, memo: msg.memo, }; @@ -325,12 +364,18 @@ where } /// Default implementation using `cw721_base::msg::InstantiateMsg` - fn init_msg(&self, _deps: Deps, env: &Env, class: &Class) -> StdResult { + fn init_msg(&self, deps: Deps, env: &Env, class: &Class) -> StdResult { + // use ics721 creator for withdraw address + let ContractInfoResponse { creator, .. } = deps + .querier + .query_wasm_contract_info(env.contract.address.to_string())?; + // use by default ClassId, in case there's no class data with name and symbol let mut instantiate_msg = cw721_base::msg::InstantiateMsg { name: class.id.clone().into(), symbol: class.id.clone().into(), minter: env.contract.address.to_string(), + withdraw_address: Some(creator), }; // use collection data for setting name and symbol @@ -423,12 +468,22 @@ where match msg { MigrateMsg::WithUpdate { pauser, - proxy, + incoming_proxy, + outgoing_proxy, cw721_base_code_id, } => { - PROXY.save( + // disables incoming proxy if none is provided! + INCOMING_PROXY.save( deps.storage, - &proxy + &incoming_proxy + .as_ref() + .map(|h| deps.api.addr_validate(h)) + .transpose()?, + )?; + // disables outgoing proxy if none is provided! + OUTGOING_PROXY.save( + deps.storage, + &outgoing_proxy .as_ref() .map(|h| deps.api.addr_validate(h)) .transpose()?, @@ -440,7 +495,14 @@ where Ok(Response::default() .add_attribute("method", "migrate") .add_attribute("pauser", pauser.map_or_else(|| "none".to_string(), |or| or)) - .add_attribute("proxy", proxy.map_or_else(|| "none".to_string(), |or| or)) + .add_attribute( + "outgoing_proxy", + outgoing_proxy.map_or_else(|| "none".to_string(), |or| or), + ) + .add_attribute( + "incoming_proxy", + incoming_proxy.map_or_else(|| "none".to_string(), |or| or), + ) .add_attribute( "cw721_base_code_id", cw721_base_code_id.map_or_else(|| "none".to_string(), |or| or.to_string()), diff --git a/packages/ics721/src/helpers.rs b/packages/ics721/src/helpers.rs index 4b912472..f2d83586 100644 --- a/packages/ics721/src/helpers.rs +++ b/packages/ics721/src/helpers.rs @@ -1,16 +1,16 @@ use cosmwasm_std::{ - from_json, instantiate2_address, to_json_binary, Addr, Binary, CodeInfoResponse, Deps, SubMsg, - WasmMsg, + from_json, instantiate2_address, to_json_binary, Addr, Binary, CodeInfoResponse, Deps, + IbcPacket, StdResult, Storage, SubMsg, WasmMsg, }; use serde::Deserialize; -use crate::{ - ibc::{NonFungibleTokenPacketData, ACK_CALLBACK_REPLY_ID}, +use crate::{ibc::ACK_CALLBACK_REPLY_ID, state::INCOMING_PROXY, ContractError}; +use ics721_types::{ + ibc_types::NonFungibleTokenPacketData, types::{ Ics721AckCallbackMsg, Ics721Callbacks, Ics721Memo, Ics721ReceiveCallbackMsg, Ics721Status, ReceiverExecuteMsg, }, - ContractError, }; /// Parse the memo field into the type we want @@ -67,6 +67,27 @@ pub(crate) fn ack_callback_msg( )) } +/// If there is an incoming proxy, let proxy validate the packet, in case it fails, we fail the transfer +/// This proxy for example whitelist channels that can send to this contract: +/// https://github.com/arkprotocol/cw-ics721-proxy/tree/main/contracts/cw-ics721-incoming-proxy-base +pub(crate) fn get_incoming_proxy_msg( + storage: &dyn Storage, + packet: IbcPacket, + data: NonFungibleTokenPacketData, +) -> StdResult> { + match INCOMING_PROXY.load(storage).ok().flatten() { + Some(incoming_proxy) => { + let msg = to_json_binary(&ReceiverExecuteMsg::Ics721ReceivePacketMsg { packet, data })?; + Ok(Some(WasmMsg::Execute { + contract_addr: incoming_proxy.to_string(), + msg, + funds: vec![], + })) + } + None => Ok(None), + } +} + /// Get the msg and address from the memo field /// if there is no receive callback returns None pub(crate) fn get_receive_callback( diff --git a/packages/ics721/src/ibc.rs b/packages/ics721/src/ibc.rs index 4365bea5..0b6b6b8b 100644 --- a/packages/ics721/src/ibc.rs +++ b/packages/ics721/src/ibc.rs @@ -1,11 +1,11 @@ -use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - from_json, to_json_binary, Binary, DepsMut, Empty, Env, IbcBasicResponse, IbcChannelCloseMsg, + from_json, to_json_binary, DepsMut, Empty, Env, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, Never, Reply, Response, StdResult, SubMsgResult, WasmMsg, }; use cw_utils::parse_reply_instantiate_data; +use ics721_types::{ibc_types::NonFungibleTokenPacketData, types::Ics721Status}; use serde::{de::DeserializeOwned, Serialize}; use crate::{ @@ -13,62 +13,27 @@ use crate::{ ibc_helpers::{ack_fail, ack_success, try_get_ack_error, validate_order_and_version}, ibc_packet_receive::receive_ibc_packet, state::{ - CLASS_ID_TO_NFT_CONTRACT, INCOMING_CLASS_TOKEN_TO_CHANNEL, NFT_CONTRACT_TO_CLASS_ID, - OUTGOING_CLASS_TOKEN_TO_CHANNEL, PROXY, TOKEN_METADATA, + CLASS_ID_TO_NFT_CONTRACT, INCOMING_CLASS_TOKEN_TO_CHANNEL, INCOMING_PROXY, + NFT_CONTRACT_TO_CLASS_ID, OUTGOING_CLASS_TOKEN_TO_CHANNEL, OUTGOING_PROXY, TOKEN_METADATA, }, - token_types::{ClassId, TokenId}, - types::Ics721Status, ContractError, }; /// Submessage reply ID used for instantiating cw721 contracts. pub(crate) const INSTANTIATE_CW721_REPLY_ID: u64 = 0; /// Submessage reply ID used for instantiating the proxy contract. -pub(crate) const INSTANTIATE_PROXY_REPLY_ID: u64 = 1; +pub(crate) const INSTANTIATE_INCOMING_PROXY_REPLY_ID: u64 = 1; +/// Submessage reply ID used for instantiating the proxy contract. +pub(crate) const INSTANTIATE_OUTGOING_PROXY_REPLY_ID: u64 = 2; /// Submessages dispatched with this reply ID will set the ack on the /// response depending on if the submessage execution succeded or /// failed. -pub(crate) const ACK_AND_DO_NOTHING: u64 = 2; +pub(crate) const ACK_AND_DO_NOTHING_REPLY_ID: u64 = 3; /// Reply on callback -pub(crate) const ACK_CALLBACK_REPLY_ID: u64 = 3; +pub(crate) const ACK_CALLBACK_REPLY_ID: u64 = 4; /// The IBC version this contract expects to communicate with. pub const IBC_VERSION: &str = "ics721-1"; -#[cw_serde] -#[serde(rename_all = "camelCase")] -pub struct NonFungibleTokenPacketData { - /// Uniquely identifies the collection which the tokens being - /// transfered belong to on the sending chain. Must be non-empty. - pub class_id: ClassId, - /// Optional URL that points to metadata about the - /// collection. Must be non-empty if provided. - pub class_uri: Option, - /// Optional base64 encoded field which contains on-chain metadata - /// about the NFT class. Must be non-empty if provided. - pub class_data: Option, - /// Uniquely identifies the tokens in the NFT collection being - /// transfered. This MUST be non-empty. - pub token_ids: Vec, - /// Optional URL that points to metadata for each token being - /// transfered. `tokenUris[N]` should hold the metadata for - /// `tokenIds[N]` and both lists should have the same if - /// provided. Must be non-empty if provided. - pub token_uris: Option>, - /// Optional base64 encoded metadata for the tokens being - /// transfered. `tokenData[N]` should hold metadata for - /// `tokenIds[N]` and both lists should have the same length if - /// provided. Must be non-empty if provided. - pub token_data: Option>, - - /// The address sending the tokens on the sending chain. - pub sender: String, - /// The address that should receive the tokens on the receiving - /// chain. - pub receiver: String, - /// Memo to add custom string to the msg - pub memo: Option, -} - pub trait Ics721Ibc where T: Serialize + DeserializeOwned + Clone, @@ -286,18 +251,27 @@ where .add_attribute("class_id", class_id) .add_attribute("cw721_addr", cw721_addr)) } - INSTANTIATE_PROXY_REPLY_ID => { + INSTANTIATE_OUTGOING_PROXY_REPLY_ID => { + let res = parse_reply_instantiate_data(reply)?; + let proxy_addr = deps.api.addr_validate(&res.contract_address)?; + OUTGOING_PROXY.save(deps.storage, &Some(proxy_addr))?; + + Ok(Response::default() + .add_attribute("method", "instantiate_outgoing_proxy_reply_id") + .add_attribute("outgoing_proxy", res.contract_address)) + } + INSTANTIATE_INCOMING_PROXY_REPLY_ID => { let res = parse_reply_instantiate_data(reply)?; let proxy_addr = deps.api.addr_validate(&res.contract_address)?; - PROXY.save(deps.storage, &Some(proxy_addr))?; + INCOMING_PROXY.save(deps.storage, &Some(proxy_addr))?; Ok(Response::default() - .add_attribute("method", "instantiate_proxy_reply_id") - .add_attribute("proxy", res.contract_address)) + .add_attribute("method", "instantiate_incoming_proxy_reply_id") + .add_attribute("incoming_proxy", res.contract_address)) } // These messages don't need to do any state changes in the // reply - just need to commit an ack. - ACK_AND_DO_NOTHING => { + ACK_AND_DO_NOTHING_REPLY_ID => { match reply.result { // On success, set a successful ack. Nothing else to do. SubMsgResult::Ok(_) => Ok(Response::new().set_data(ack_success())), diff --git a/packages/ics721/src/ibc_helpers.rs b/packages/ics721/src/ibc_helpers.rs index 98f8e9d2..625adecc 100644 --- a/packages/ics721/src/ibc_helpers.rs +++ b/packages/ics721/src/ibc_helpers.rs @@ -3,10 +3,7 @@ use cosmwasm_std::{ }; use serde::{Deserialize, Serialize}; -use crate::{ - ibc::{NonFungibleTokenPacketData, IBC_VERSION}, - ContractError, -}; +use crate::{ibc::IBC_VERSION, ContractError}; /// Tries to remove the source prefix from a given class_id. If the /// class_id does not begin with the given prefix, returns @@ -120,54 +117,9 @@ pub(crate) fn validate_order_and_version( Ok(()) } -macro_rules! non_empty_optional { - ($e:expr) => { - if $e.map_or(false, |data| data.is_empty()) { - return Err(ContractError::EmptyOptional {}); - } - }; -} - -impl NonFungibleTokenPacketData { - pub fn validate(&self) -> Result<(), ContractError> { - if self.class_id.is_empty() { - return Err(ContractError::EmptyClassId {}); - } - - non_empty_optional!(self.class_uri.as_ref()); - non_empty_optional!(self.class_data.as_ref()); - - let token_count = self.token_ids.len(); - if token_count == 0 { - return Err(ContractError::NoTokens {}); - } - - // Non-empty optionality of tokenData an tokenUris implicitly - // checked here. - if self - .token_data - .as_ref() - .map_or(false, |data| data.len() != token_count) - || self - .token_uris - .as_ref() - .map_or(false, |data| data.len() != token_count) - { - return Err(ContractError::TokenInfoLenMissmatch {}); - } - - // This contract assumes that the backing cw721 is functional, - // so no need to check tokenIds for duplicates as the cw721 - // will prevent minting of duplicates. - - Ok(()) - } -} - #[cfg(test)] mod tests { use super::*; - use crate::token_types::{ClassId, TokenId}; #[test] fn test_pop_source_simple() { @@ -221,75 +173,4 @@ mod tests { None ); } - - #[test] - fn test_packet_validation() { - let default_token = NonFungibleTokenPacketData { - class_id: ClassId::new("id"), - class_uri: None, - class_data: None, - token_ids: vec![TokenId::new("1")], - token_uris: None, - token_data: None, - sender: "violet".to_string(), - receiver: "blue".to_string(), - memo: None, - }; - - let empty_class_id = NonFungibleTokenPacketData { - class_id: ClassId::new(""), - ..default_token.clone() - }; - let err = empty_class_id.validate().unwrap_err(); - assert_eq!(err, ContractError::EmptyClassId {}); - - let empty_class_uri = NonFungibleTokenPacketData { - class_uri: Some("".to_string()), - ..default_token.clone() - }; - let err = empty_class_uri.validate().unwrap_err(); - assert_eq!(err, ContractError::EmptyOptional {}); - - let empty_class_data = NonFungibleTokenPacketData { - class_data: Some(Binary::default()), - ..default_token.clone() - }; - let err = empty_class_data.validate().unwrap_err(); - assert_eq!(err, ContractError::EmptyOptional {}); - - let no_tokens = NonFungibleTokenPacketData { - token_ids: vec![], - ..default_token.clone() - }; - let err = no_tokens.validate().unwrap_err(); - assert_eq!(err, ContractError::NoTokens {}); - - let uri_imbalance_empty = NonFungibleTokenPacketData { - token_uris: Some(vec![]), - ..default_token.clone() - }; - let err = uri_imbalance_empty.validate().unwrap_err(); - assert_eq!(err, ContractError::TokenInfoLenMissmatch {}); - - let uri_imbalance = NonFungibleTokenPacketData { - token_uris: Some(vec!["a".to_string(), "b".to_string()]), - ..default_token.clone() - }; - let err = uri_imbalance.validate().unwrap_err(); - assert_eq!(err, ContractError::TokenInfoLenMissmatch {}); - - let data_imbalance_empty = NonFungibleTokenPacketData { - token_data: Some(vec![]), - ..default_token.clone() - }; - let err = data_imbalance_empty.validate().unwrap_err(); - assert_eq!(err, ContractError::TokenInfoLenMissmatch {}); - - let data_imbalance = NonFungibleTokenPacketData { - token_data: Some(vec![Binary::default(), Binary::default()]), - ..default_token - }; - let err = data_imbalance.validate().unwrap_err(); - assert_eq!(err, ContractError::TokenInfoLenMissmatch {}); - } } diff --git a/packages/ics721/src/ibc_packet_receive.rs b/packages/ics721/src/ibc_packet_receive.rs index bdc84f0c..02951694 100644 --- a/packages/ics721/src/ibc_packet_receive.rs +++ b/packages/ics721/src/ibc_packet_receive.rs @@ -6,17 +6,24 @@ use sha2::{Digest, Sha256}; use zip_optional::Zippable; use crate::{ - helpers::{generate_receive_callback_msg, get_instantiate2_address, get_receive_callback}, - ibc::{NonFungibleTokenPacketData, ACK_AND_DO_NOTHING}, + helpers::{ + generate_receive_callback_msg, get_incoming_proxy_msg, get_instantiate2_address, + get_receive_callback, + }, + ibc::ACK_AND_DO_NOTHING_REPLY_ID, ibc_helpers::{get_endpoint_prefix, try_pop_source_prefix}, msg::{CallbackMsg, ExecuteMsg}, state::{ CLASS_ID_TO_NFT_CONTRACT, CW721_CODE_ID, INCOMING_CLASS_TOKEN_TO_CHANNEL, OUTGOING_CLASS_TOKEN_TO_CHANNEL, PO, }, - token_types::{Class, ClassId, Token, TokenId, VoucherCreation, VoucherRedemption}, + token_types::{VoucherCreation, VoucherRedemption}, ContractError, }; +use ics721_types::{ + ibc_types::NonFungibleTokenPacketData, + token_types::{Class, ClassId, Token, TokenId}, +}; /// Every incoming token has some associated action. enum Action { @@ -52,7 +59,6 @@ pub(crate) fn receive_ibc_packet( packet: IbcPacket, ) -> Result { PO.error_if_paused(deps.storage)?; - let data: NonFungibleTokenPacketData = from_json(&packet.data)?; data.validate()?; @@ -173,8 +179,14 @@ pub(crate) fn receive_ibc_packet( None }; - let submessage = - action_aggregator.into_submessage(env.contract.address, receiver, callback_msg)?; + let incoming_proxy_msg = + get_incoming_proxy_msg(deps.storage, packet.clone(), cloned_data.clone())?; + let submessage = action_aggregator.into_submessage( + env.contract.address, + receiver, + callback_msg, + incoming_proxy_msg, + )?; let response = if let Some(memo) = data.memo { IbcReceiveResponse::default().add_attribute("ics721_memo", memo) @@ -297,14 +309,21 @@ impl ActionAggregator { contract: Addr, receiver: Addr, callback_msg: Option, + incoming_proxy_msg: Option, ) -> StdResult> { - let mut m = Vec::with_capacity(2); + let mut m = Vec::with_capacity(3); // 3 is the max number of submessages we can have + if let Some(incoming_proxy_msg) = incoming_proxy_msg { + m.push(incoming_proxy_msg) + } + + // we can only have redeem or create, not both if let Some(redeem) = self.redemption { m.push(redeem.into_wasm_msg(contract.clone(), receiver.to_string())?) } if let Some(create) = self.creation { m.push(create.into_wasm_msg(contract.clone(), receiver.into_string())?) } + if let Some(callback_msg) = callback_msg { m.push(callback_msg) } @@ -319,6 +338,6 @@ impl ActionAggregator { funds: vec![], } }; - Ok(SubMsg::reply_always(message, ACK_AND_DO_NOTHING)) + Ok(SubMsg::reply_always(message, ACK_AND_DO_NOTHING_REPLY_ID)) } } diff --git a/packages/ics721/src/lib.rs b/packages/ics721/src/lib.rs index 5502942e..75734a0f 100644 --- a/packages/ics721/src/lib.rs +++ b/packages/ics721/src/lib.rs @@ -8,10 +8,12 @@ pub mod msg; pub mod query; pub mod state; pub mod token_types; -pub mod types; pub mod utils; - pub use crate::error::ContractError; +pub use ics721_types::{ + ibc_types::NonFungibleTokenPacketData, + token_types::{Class, ClassId, Token, TokenId}, +}; #[cfg(test)] pub mod testing; diff --git a/packages/ics721/src/msg.rs b/packages/ics721/src/msg.rs index 4f84ba69..f5a9401f 100644 --- a/packages/ics721/src/msg.rs +++ b/packages/ics721/src/msg.rs @@ -1,9 +1,9 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, IbcTimeout, WasmMsg}; -use cw721_proxy_derive::cw721_proxy; +use cosmwasm_std::{Addr, WasmMsg}; use cw_cii::ContractInstantiateInfo; -use crate::token_types::{ClassId, Token, TokenId, VoucherCreation, VoucherRedemption}; +use crate::token_types::{VoucherCreation, VoucherRedemption}; +use ics721_types::token_types::{Class, ClassId, ClassToken, Token, TokenId}; #[cw_serde] pub struct InstantiateMsg { @@ -15,11 +15,15 @@ pub struct InstantiateMsg { /// this contract to stop working, and IBCd away NFTs to be /// unreturnable as cw721 does not have a mint method in the spec. pub cw721_base_code_id: u64, - /// An optional proxy contract. If a proxy is set the contract + /// An optional proxy contract. If an incoming proxy is set, the contract + /// will call it and pass IbcPacket. The proxy is expected + /// to implement the Ics721ReceiveIbcPacketMsg for message execution. + pub incoming_proxy: Option, + /// An optional proxy contract. If an outging proxy is set, the contract /// will only accept NFTs from that proxy. The proxy is expected /// to implement the cw721 proxy interface defined in the - /// cw721-proxy crate. - pub proxy: Option, + /// cw721-outgoing-proxy crate. + pub outgoing_proxy: Option, /// Address that may pause the contract. PAUSER may pause the /// contract a single time; in pausing the contract they burn the /// right to do so again. A new pauser may be later nominated by @@ -27,7 +31,6 @@ pub struct InstantiateMsg { pub pauser: Option, } -#[cw721_proxy] #[cw_serde] pub enum ExecuteMsg { /// Receives a NFT to be IBC transfered away. The `msg` field must @@ -80,27 +83,13 @@ pub enum CallbackMsg { Conjunction { operands: Vec }, } -#[cw_serde] -pub struct IbcOutgoingMsg { - /// The address that should receive the NFT being sent on the - /// *receiving chain*. - pub receiver: String, - /// The *local* channel ID this ought to be sent away on. This - /// contract must have a connection on this channel. - pub channel_id: String, - /// Timeout for the IBC message. - pub timeout: IbcTimeout, - /// Memo to add custom string to the msg - pub memo: Option, -} - #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { /// Gets the classID this contract has stored for a given NFT /// contract. If there is no class ID for the provided contract, /// returns None. - #[returns(Option)] + #[returns(Option)] ClassId { contract: String }, /// Gets the NFT contract associated wtih the provided class @@ -112,10 +101,10 @@ pub enum QueryMsg { /// Gets the class level metadata URI for the provided /// class_id. If there is no metadata, returns None. Returns /// `Option`. - #[returns(Option)] + #[returns(Option)] ClassMetadata { class_id: String }, - #[returns(Option)] + #[returns(Option)] TokenMetadata { class_id: String, token_id: String }, /// Gets the owner of the NFT identified by CLASS_ID and @@ -132,9 +121,13 @@ pub enum QueryMsg { #[returns(bool)] Paused {}, - /// Gets this contract's cw721-proxy if one is set. + /// Gets this contract's outgoing cw721-outgoing-proxy if one is set. + #[returns(Option<::cosmwasm_std::Addr>)] + OutgoingProxy {}, + + /// Gets this contract's incoming cw721-outgoing-proxy if one is set. #[returns(Option<::cosmwasm_std::Addr>)] - Proxy {}, + IncomingProxy {}, /// Gets the code used for instantiating new cw721s. #[returns(u64)] @@ -168,21 +161,18 @@ pub enum QueryMsg { }, } -#[cw_serde] -pub struct ClassToken { - pub class_id: ClassId, - pub token_id: TokenId, -} - #[cw_serde] pub enum MigrateMsg { WithUpdate { /// The address that may pause the contract. If `None` is /// provided the current pauser will be removed. pauser: Option, - /// The cw721-proxy for this contract. If `None` is provided + /// The cw721-outgoing-proxy for this contract. If `None` is provided + /// the current proxy will be removed. + outgoing_proxy: Option, + /// The cw721-outgoing-proxy for this contract. If `None` is provided /// the current proxy will be removed. - proxy: Option, + incoming_proxy: Option, /// Code ID of cw721-ics contract. A new cw721-ics will be /// instantiated for each new IBCd NFT classID. /// diff --git a/packages/ics721/src/query.rs b/packages/ics721/src/query.rs index 408220c9..37c43e16 100644 --- a/packages/ics721/src/query.rs +++ b/packages/ics721/src/query.rs @@ -2,14 +2,14 @@ use cosmwasm_std::{to_json_binary, Addr, Binary, Deps, Env, Order, StdResult}; use cw_storage_plus::Map; use crate::{ - msg::{ClassToken, QueryMsg}, + msg::QueryMsg, state::{ UniversalAllNftInfoResponse, CLASS_ID_TO_CLASS, CLASS_ID_TO_NFT_CONTRACT, CW721_CODE_ID, - INCOMING_CLASS_TOKEN_TO_CHANNEL, NFT_CONTRACT_TO_CLASS_ID, OUTGOING_CLASS_TOKEN_TO_CHANNEL, - PO, PROXY, TOKEN_METADATA, + INCOMING_CLASS_TOKEN_TO_CHANNEL, INCOMING_PROXY, NFT_CONTRACT_TO_CLASS_ID, + OUTGOING_CLASS_TOKEN_TO_CHANNEL, OUTGOING_PROXY, PO, TOKEN_METADATA, }, - token_types::{Class, ClassId, Token, TokenId}, }; +use ics721_types::token_types::{Class, ClassId, ClassToken, Token, TokenId}; pub trait Ics721Query { fn query(&self, deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { @@ -31,7 +31,8 @@ pub trait Ics721Query { } QueryMsg::Pauser {} => to_json_binary(&PO.query_pauser(deps.storage)?), QueryMsg::Paused {} => to_json_binary(&PO.query_paused(deps.storage)?), - QueryMsg::Proxy {} => to_json_binary(&PROXY.load(deps.storage)?), + QueryMsg::OutgoingProxy {} => to_json_binary(&OUTGOING_PROXY.load(deps.storage)?), + QueryMsg::IncomingProxy {} => to_json_binary(&INCOMING_PROXY.load(deps.storage)?), QueryMsg::Cw721CodeId {} => to_json_binary(&self.query_cw721_code_id(deps)?), QueryMsg::NftContracts { start_after, limit } => { to_json_binary(&self.query_nft_contracts(deps, start_after, limit)?) diff --git a/packages/ics721/src/state.rs b/packages/ics721/src/state.rs index 8a17b4a1..bc75a832 100644 --- a/packages/ics721/src/state.rs +++ b/packages/ics721/src/state.rs @@ -4,12 +4,16 @@ use cw_pause_once::PauseOrchestrator; use cw_storage_plus::{Item, Map}; use serde::{Deserialize, Serialize}; -use crate::token_types::{Class, ClassId, TokenId}; +use ics721_types::token_types::{Class, ClassId, TokenId}; /// The code ID we will use for instantiating new cw721s. pub const CW721_CODE_ID: Item = Item::new("a"); -/// The proxy that this contract is receiving NFTs from, if any. -pub const PROXY: Item> = Item::new("b"); + +/// The incoming proxy that this contract is handling incoming IbcPackets from, if any. +pub const INCOMING_PROXY: Item> = Item::new("k"); +/// The outgoing proxy that this contract is receiving NFTs from, if any. +pub const OUTGOING_PROXY: Item> = Item::new("b"); + /// Manages contract pauses. pub const PO: PauseOrchestrator = PauseOrchestrator::new("c", "d"); diff --git a/packages/ics721/src/testing/contract.rs b/packages/ics721/src/testing/contract.rs index 0d271810..7d5acb48 100644 --- a/packages/ics721/src/testing/contract.rs +++ b/packages/ics721/src/testing/contract.rs @@ -3,24 +3,33 @@ use cosmwasm_std::{ from_json, testing::{mock_dependencies, mock_env, mock_info, MockQuerier, MOCK_CONTRACT_ADDR}, to_json_binary, Addr, ContractResult, CosmosMsg, DepsMut, Empty, IbcMsg, IbcTimeout, Order, - QuerierResult, StdResult, SubMsg, Timestamp, WasmQuery, + QuerierResult, Response, StdResult, SubMsg, Timestamp, WasmQuery, }; use cw721::{AllNftInfoResponse, NftInfoResponse, NumTokensResponse}; use cw721_base::QueryMsg; +use cw_cii::ContractInstantiateInfo; use cw_ownable::Ownership; use crate::{ execute::Ics721Execute, - ibc::{Ics721Ibc, NonFungibleTokenPacketData}, - msg::IbcOutgoingMsg, + ibc::{Ics721Ibc, INSTANTIATE_INCOMING_PROXY_REPLY_ID, INSTANTIATE_OUTGOING_PROXY_REPLY_ID}, + msg::InstantiateMsg, query::Ics721Query, - state::{CollectionData, CLASS_ID_TO_CLASS, OUTGOING_CLASS_TOKEN_TO_CHANNEL}, - token_types::{ClassId, TokenId}, + state::{ + CollectionData, CLASS_ID_TO_CLASS, CW721_CODE_ID, INCOMING_PROXY, + OUTGOING_CLASS_TOKEN_TO_CHANNEL, OUTGOING_PROXY, PO, + }, utils::get_collection_data, }; +use ics721_types::{ + ibc_types::{IbcOutgoingMsg, NonFungibleTokenPacketData}, + token_types::{ClassId, TokenId}, +}; const NFT_ADDR: &str = "nft"; -const OWNER: &str = "owner"; +const OWNER_ADDR: &str = "owner"; +const ADMIN_ADDR: &str = "admin"; +const PAUSER_ADDR: &str = "pauser"; #[derive(Default)] pub struct Ics721Contract {} @@ -72,7 +81,7 @@ fn mock_querier(query: &WasmQuery) -> QuerierResult { } => match from_json::>(&msg).unwrap() { QueryMsg::Ownership {} => QuerierResult::Ok(ContractResult::Ok( to_json_binary(&Ownership:: { - owner: Some(Addr::unchecked(OWNER)), + owner: Some(Addr::unchecked(OWNER_ADDR)), pending_owner: None, pending_expiry: None, }) @@ -128,7 +137,7 @@ fn mock_querier_v016(query: &WasmQuery) -> QuerierResult { to_json_binary( // return v016 response &cw721_base_016::msg::MinterResponse { - minter: OWNER.to_string(), + minter: OWNER_ADDR.to_string(), }, ) .unwrap(), @@ -231,7 +240,7 @@ fn test_receive_nft() { class_uri: None, class_data: Some( to_json_binary(&CollectionData { - owner: Some(OWNER.to_string()), + owner: Some(OWNER_ADDR.to_string()), contract_info: Some(expected_contract_info.clone()), name: "name".to_string(), symbol: "symbol".to_string(), @@ -312,7 +321,7 @@ fn test_receive_nft() { class_uri: None, class_data: Some( to_json_binary(&CollectionData { - owner: Some(OWNER.to_string()), + owner: Some(OWNER_ADDR.to_string()), contract_info: Some(expected_contract_info), name: "name".to_string(), symbol: "symbol".to_string(), @@ -467,7 +476,7 @@ fn test_receive_sets_uri() { class.data, Some( to_json_binary(&CollectionData { - owner: Some(OWNER.to_string()), + owner: Some(OWNER_ADDR.to_string()), contract_info: Some(expected_contract_info), name: "name".to_string(), symbol: "symbol".to_string(), @@ -477,3 +486,60 @@ fn test_receive_sets_uri() { ), ); } + +#[test] +fn test_instantiate() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let info = mock_info(OWNER_ADDR, &[]); + let incoming_proxy_init_msg = ContractInstantiateInfo { + code_id: 0, + msg: to_json_binary("incoming").unwrap(), + admin: Some(cw_cii::Admin::Address { + addr: ADMIN_ADDR.to_string(), + }), + label: "incoming".to_string(), + }; + let outgoing_proxy_init_msg = ContractInstantiateInfo { + code_id: 0, + msg: to_json_binary("outgoing").unwrap(), + admin: Some(cw_cii::Admin::Address { + addr: ADMIN_ADDR.to_string(), + }), + label: "outgoing".to_string(), + }; + let msg = InstantiateMsg { + cw721_base_code_id: 0, + incoming_proxy: Some(incoming_proxy_init_msg.clone()), + outgoing_proxy: Some(outgoing_proxy_init_msg.clone()), + pauser: Some(PAUSER_ADDR.to_string()), + }; + let response = Ics721Contract {} + .instantiate(deps.as_mut(), env.clone(), info, msg.clone()) + .unwrap(); + + let expected_incoming_proxy_msg = + incoming_proxy_init_msg.into_wasm_msg(env.clone().contract.address); + let expected_outgoing_proxy_msg = outgoing_proxy_init_msg.into_wasm_msg(env.contract.address); + let expected_response = Response::::default() + .add_submessage(SubMsg::reply_on_success( + expected_incoming_proxy_msg, + INSTANTIATE_INCOMING_PROXY_REPLY_ID, + )) + .add_submessage(SubMsg::reply_on_success( + expected_outgoing_proxy_msg, + INSTANTIATE_OUTGOING_PROXY_REPLY_ID, + )) + .add_attribute("method", "instantiate") + .add_attribute("cw721_code_id", msg.cw721_base_code_id.to_string()); + assert_eq!(response, expected_response); + assert_eq!(CW721_CODE_ID.load(&deps.storage).unwrap(), 0); + // incoming and outgoing proxy initially set to None and set later in sub msg + assert_eq!(OUTGOING_PROXY.load(&deps.storage).unwrap(), None); + assert_eq!(INCOMING_PROXY.load(&deps.storage).unwrap(), None); + assert_eq!( + PO.pauser.load(&deps.storage).unwrap(), + Some(Addr::unchecked(PAUSER_ADDR)) + ); + assert!(!PO.paused.load(&deps.storage).unwrap()); +} diff --git a/packages/ics721/src/testing/ibc_tests.rs b/packages/ics721/src/testing/ibc_tests.rs index b8092f48..39ced734 100644 --- a/packages/ics721/src/testing/ibc_tests.rs +++ b/packages/ics721/src/testing/ibc_tests.rs @@ -10,19 +10,19 @@ use cosmwasm_std::{ use crate::{ execute::Ics721Execute, - ibc::{ - Ics721Ibc, NonFungibleTokenPacketData, ACK_AND_DO_NOTHING, IBC_VERSION, - INSTANTIATE_CW721_REPLY_ID, - }, + ibc::{Ics721Ibc, ACK_AND_DO_NOTHING_REPLY_ID, IBC_VERSION, INSTANTIATE_CW721_REPLY_ID}, ibc_helpers::{ack_fail, ack_success, try_get_ack_error}, msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, QueryMsg}, query::Ics721Query, state::{CollectionData, INCOMING_CLASS_TOKEN_TO_CHANNEL, NFT_CONTRACT_TO_CLASS_ID, PO}, - token_types::{ClassId, TokenId}, - types::Ics721Callbacks, utils::get_collection_data, ContractError, }; +use ics721_types::{ + ibc_types::NonFungibleTokenPacketData, + token_types::{ClassId, TokenId}, + types::Ics721Callbacks, +}; const CONTRACT_PORT: &str = "wasm.address1"; const REMOTE_PORT: &str = "stars.address1"; @@ -105,7 +105,8 @@ fn add_channel(mut deps: DepsMut, env: Env, channel_id: &str) { fn do_instantiate(deps: DepsMut, env: Env, sender: &str) -> StdResult { let msg = InstantiateMsg { cw721_base_code_id: CW721_CODE_ID, - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, pauser: None, }; Ics721Contract::default().instantiate(deps, env, mock_info(sender, &[]), msg) @@ -179,7 +180,7 @@ fn test_stateless_reply() { let mut deps = mock_dependencies(); let rep = Reply { - id: ACK_AND_DO_NOTHING, + id: ACK_AND_DO_NOTHING_REPLY_ID, result: SubMsgResult::Ok(SubMsgResponse { events: vec![], data: None, @@ -191,7 +192,7 @@ fn test_stateless_reply() { assert_eq!(res.data, Some(ack_success())); let rep = Reply { - id: ACK_AND_DO_NOTHING, + id: ACK_AND_DO_NOTHING_REPLY_ID, result: SubMsgResult::Err("some failure".to_string()), }; let res = Ics721Contract::default() @@ -476,7 +477,7 @@ fn test_ibc_packet_receive() { #[test] fn test_ibc_packet_receive_invalid_packet_data() { // the actual message used here is unimportant. this just - // constructs a valud JSON blob that is not a valid ICS-721 + // constructs a valid JSON blob that is not a valid ICS-721 // packet. let data = to_json_binary(&QueryMsg::ClassMetadata { class_id: "foobar".to_string(), @@ -496,7 +497,7 @@ fn test_ibc_packet_receive_invalid_packet_data() { assert!(error .unwrap() - .starts_with("Error parsing into type ics721::ibc::NonFungibleTokenPacketData")) + .starts_with("Error parsing into type ics721_types::ibc_types::NonFungibleTokenPacketData")) } #[test] @@ -557,7 +558,10 @@ fn test_ibc_packet_receive_missmatched_lengths() { assert_eq!( error, - Some(ContractError::TokenInfoLenMissmatch {}.to_string()) + Some( + ContractError::Ics721Error(ics721_types::error::Ics721Error::TokenInfoLenMissmatch {}) + .to_string() + ) ); // More token data are provided than tokens. @@ -589,7 +593,10 @@ fn test_ibc_packet_receive_missmatched_lengths() { assert_eq!( error, - Some(ContractError::TokenInfoLenMissmatch {}.to_string()) + Some( + ContractError::Ics721Error(ics721_types::error::Ics721Error::TokenInfoLenMissmatch {}) + .to_string() + ) ) } diff --git a/packages/ics721/src/testing/integration_tests.rs b/packages/ics721/src/testing/integration_tests.rs index c5dcd607..f6814f2c 100644 --- a/packages/ics721/src/testing/integration_tests.rs +++ b/packages/ics721/src/testing/integration_tests.rs @@ -11,7 +11,7 @@ use cw721_base::msg::{InstantiateMsg as Cw721InstantiateMsg, QueryMsg as Cw721Qu use cw_cii::{Admin, ContractInstantiateInfo}; use cw_multi_test::{ AddressGenerator, App, AppBuilder, BankKeeper, Contract, ContractWrapper, DistributionKeeper, - Executor, FailingModule, IbcAcceptingModule, Router, StakeKeeper, WasmKeeper, + Executor, FailingModule, IbcAcceptingModule, Router, StakeKeeper, StargateFailing, WasmKeeper, }; use cw_pause_once::PauseError; use sha2::{digest::Update, Digest, Sha256}; @@ -19,12 +19,16 @@ use sha2::{digest::Update, Digest, Sha256}; use crate::{ execute::Ics721Execute, ibc::Ics721Ibc, - msg::{CallbackMsg, ExecuteMsg, IbcOutgoingMsg, InstantiateMsg, MigrateMsg, QueryMsg}, + msg::{CallbackMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, query::Ics721Query, state::CollectionData, - token_types::{Class, ClassId, Token, TokenId, VoucherCreation}, + token_types::VoucherCreation, ContractError, }; +use ics721_types::{ + ibc_types::{IbcOutgoingMsg, IbcOutgoingProxyMsg}, + token_types::{Class, ClassId, Token, TokenId}, +}; use super::contract::Ics721Contract; @@ -49,6 +53,7 @@ type MockRouter = Router< DistributionKeeper, IbcAcceptingModule, FailingModule, + StargateFailing, >; type MockApp = App< @@ -280,10 +285,14 @@ struct Test { } impl Test { + /// Test setup with optional pauser and proxy contracts. fn new( - proxy: bool, + outgoing_proxy: bool, + incoming_proxy: bool, + channels: Option>, admin_and_pauser: Option, cw721_code: Box>, + is_cw721_018: bool, ) -> Self { let mut app = AppBuilder::new() .with_wasm::>( @@ -295,19 +304,37 @@ impl Test { let source_cw721_id = app.store_code(cw721_code); let ics721_id = app.store_code(ics721_contract()); - use cw721_rate_limited_proxy as rlp; - let proxy = match proxy { + let outgoing_proxy = match outgoing_proxy { + true => { + let proxy_id = app.store_code(outgoing_proxy_contract()); + Some(ContractInstantiateInfo { + code_id: proxy_id, + msg: to_json_binary( + &cw_ics721_outgoing_proxy_rate_limit::msg::InstantiateMsg { + rate_limit: cw_ics721_outgoing_proxy_rate_limit::Rate::PerBlock(10), + origin: None, + }, + ) + .unwrap(), + admin: Some(Admin::Instantiator {}), + label: "outgoing proxy rate limit".to_string(), + }) + } + false => None, + }; + + let incoming_proxy = match incoming_proxy { true => { - let proxy_id = app.store_code(proxy_contract()); + let proxy_id = app.store_code(incoming_proxy_contract()); Some(ContractInstantiateInfo { code_id: proxy_id, - msg: to_json_binary(&rlp::msg::InstantiateMsg { - rate_limit: rlp::Rate::PerBlock(10), + msg: to_json_binary(&cw_ics721_incoming_proxy_base::msg::InstantiateMsg { origin: None, + channels, }) .unwrap(), admin: Some(Admin::Instantiator {}), - label: "rate limited proxy".to_string(), + label: "incoming proxy".to_string(), }) } false => None, @@ -319,7 +346,8 @@ impl Test { app.api().addr_make(ICS721_CREATOR), &InstantiateMsg { cw721_base_code_id: source_cw721_id, - proxy, + incoming_proxy, + outgoing_proxy, pauser: admin_and_pauser .clone() .map(|p| app.api().addr_make(&p).to_string()), @@ -331,20 +359,37 @@ impl Test { .unwrap(); let source_cw721_owner = app.api().addr_make(COLLECTION_OWNER_SOURCE_CHAIN); - let source_cw721 = app - .instantiate_contract( - source_cw721_id, - source_cw721_owner.clone(), - &Cw721InstantiateMsg { - name: "name".to_string(), - symbol: "symbol".to_string(), - minter: source_cw721_owner.to_string(), - }, - &[], - "cw721-base", - None, - ) - .unwrap(); + let source_cw721 = match is_cw721_018 { + true => app + .instantiate_contract( + source_cw721_id, + source_cw721_owner.clone(), + &Cw721InstantiateMsg { + name: "name".to_string(), + symbol: "symbol".to_string(), + minter: source_cw721_owner.to_string(), + withdraw_address: None, + }, + &[], + "cw721-base", + None, + ) + .unwrap(), + false => app + .instantiate_contract( + source_cw721_id, + source_cw721_owner.clone(), + &cw721_base_016::msg::InstantiateMsg { + name: "name".to_string(), + symbol: "symbol".to_string(), + minter: source_cw721_owner.to_string(), + }, + &[], + "cw721-base", + None, + ) + .unwrap(), + }; Self { app, @@ -395,10 +440,17 @@ impl Test { (paused, pauser) } - fn query_proxy(&mut self) -> Option { + fn query_outgoing_proxy(&mut self) -> Option { + self.app + .wrap() + .query_wasm_smart(self.ics721.clone(), &QueryMsg::OutgoingProxy {}) + .unwrap() + } + + fn query_incoming_proxy(&mut self) -> Option { self.app .wrap() - .query_wasm_smart(self.ics721.clone(), &QueryMsg::Proxy {}) + .query_wasm_smart(self.ics721.clone(), &QueryMsg::IncomingProxy {}) .unwrap() } @@ -498,18 +550,27 @@ fn ics721_contract() -> Box> { Box::new(contract) } -fn proxy_contract() -> Box> { +fn incoming_proxy_contract() -> Box> { let contract = ContractWrapper::new( - cw721_rate_limited_proxy::contract::execute::, - cw721_rate_limited_proxy::contract::instantiate, - cw721_rate_limited_proxy::contract::query, + cw_ics721_incoming_proxy_base::contract::execute, + cw_ics721_incoming_proxy_base::contract::instantiate, + cw_ics721_incoming_proxy_base::contract::query, + ); + Box::new(contract) +} + +fn outgoing_proxy_contract() -> Box> { + let contract = ContractWrapper::new( + cw_ics721_outgoing_proxy_rate_limit::contract::execute, + cw_ics721_outgoing_proxy_rate_limit::contract::instantiate, + cw_ics721_outgoing_proxy_rate_limit::contract::query, ); Box::new(contract) } #[test] fn test_instantiate() { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(true, true, None, None, cw721_base_contract(), true); // check stores are properly initialized let cw721_id = test.query_cw721_id(); @@ -520,11 +581,15 @@ fn test_instantiate() { assert_eq!(outgoing_channels, []); let incoming_channels = test.query_incoming_channels(); assert_eq!(incoming_channels, []); + let outgoing_proxy = test.query_outgoing_proxy(); + assert!(outgoing_proxy.is_some()); + let incoming_proxy = test.query_incoming_proxy(); + assert!(incoming_proxy.is_some()); } #[test] fn test_do_instantiate_and_mint_weird_data() { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -575,7 +640,7 @@ fn test_do_instantiate_and_mint_weird_data() { fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with no ClassData (without owner, name, and symbol) { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -714,7 +779,7 @@ fn test_do_instantiate_and_mint() { } // test case: instantiate cw721 with ClassData containing owner, name, and symbol { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -869,7 +934,7 @@ fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with CustomClassData (includes name, but without owner and symbol) // results in nft contract using class id for name and symbol { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1023,7 +1088,7 @@ fn test_do_instantiate_and_mint() { // test case: instantiate cw721 with PartialCustomCollectionData (includes name and symbol) // results in nft contract using name and symbol { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1183,7 +1248,7 @@ fn test_do_instantiate_and_mint() { fn test_do_instantiate_and_mint_2_different_collections() { // test case: instantiate two cw721 contracts with different class id and make sure instantiate2 creates 2 different, predictable contracts { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain_1 = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id_1 = format!( @@ -1450,7 +1515,7 @@ fn test_do_instantiate_and_mint_2_different_collections() { #[test] fn test_do_instantiate_and_mint_no_instantiate() { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1558,7 +1623,7 @@ fn test_do_instantiate_and_mint_no_instantiate() { #[test] fn test_do_instantiate_and_mint_permissions() { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); let collection_contract_source_chain = ClassId::new(test.app.api().addr_make(COLLECTION_CONTRACT_SOURCE_CHAIN)); let class_id = format!( @@ -1609,23 +1674,71 @@ fn test_do_instantiate_and_mint_permissions() { assert_eq!(err, ContractError::Unauthorized {}); } -/// Tests that we can not proxy NFTs if no proxy is configured. +/// Tests that we can not send IbcOutgoingProxyMsg if no proxy is configured. #[test] -fn test_no_proxy_unauthorized() { - let mut test = Test::new(false, None, cw721_base_contract()); +fn test_no_proxy_unknown_msg() { + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); + let msg = IbcOutgoingProxyMsg { + collection: "foo".to_string(), + msg: to_json_binary(&IbcOutgoingMsg { + receiver: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + channel_id: "channel-0".to_string(), + timeout: IbcTimeout::with_block(IbcTimeoutBlock { + revision: 0, + height: 10, + }), + memo: None, + }) + .unwrap(), + }; let err: ContractError = test .app .execute_contract( test.app.api().addr_make("proxy"), test.ics721, - &ExecuteMsg::ReceiveProxyNft { - eyeball: "nft".to_string(), - msg: cw721::Cw721ReceiveMsg { - sender: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), - token_id: "1".to_string(), - msg: to_json_binary("").unwrap(), - }, - }, + &ExecuteMsg::ReceiveNft(cw721::Cw721ReceiveMsg { + sender: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + token_id: "1".to_string(), + msg: to_json_binary(&msg).unwrap(), + }), + &[], + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!( + err, + ContractError::UnknownMsg(to_json_binary(&msg).unwrap()) + ); +} + +/// Tests that we can non-proxy addresses can send if proxy is configured. +#[test] +fn test_no_proxy_unauthorized() { + let mut test = Test::new(true, false, None, None, cw721_base_contract(), true); + let msg = IbcOutgoingProxyMsg { + collection: "foo".to_string(), + msg: to_json_binary(&IbcOutgoingMsg { + receiver: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + channel_id: "channel-0".to_string(), + timeout: IbcTimeout::with_block(IbcTimeoutBlock { + revision: 0, + height: 10, + }), + memo: None, + }) + .unwrap(), + }; + let err: ContractError = test + .app + .execute_contract( + test.app.api().addr_make("foo"), + test.ics721, + &ExecuteMsg::ReceiveNft(cw721::Cw721ReceiveMsg { + sender: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), + token_id: "1".to_string(), + msg: to_json_binary(&msg).unwrap(), + }), &[], ) .unwrap_err() @@ -1636,11 +1749,11 @@ fn test_no_proxy_unauthorized() { #[test] fn test_proxy_authorized() { - let mut test = Test::new(true, None, cw721_base_contract()); + let mut test = Test::new(true, false, None, None, cw721_base_contract(), true); let proxy_address: Option = test .app .wrap() - .query_wasm_smart(&test.ics721, &QueryMsg::Proxy {}) + .query_wasm_smart(&test.ics721, &QueryMsg::OutgoingProxy {}) .unwrap(); // check proxy is set let proxy_address = proxy_address.expect("expected a proxy"); @@ -1660,14 +1773,15 @@ fn test_proxy_authorized() { .api() .addr_make(COLLECTION_OWNER_SOURCE_CHAIN) .to_string(), + withdraw_address: None, }, &[], "label cw721", None, ) .unwrap(); - // simplify: instead of `send_nft` to proxy, and proxy transfer NFT to ics721 and call receiveproy, - // here it is directly transfer to ics721 and then call receiveproxy + // simplify: instead of `send_nft` to proxy, and proxy transfer NFT to ics721 and call receive proxy, + // here it is directly transferred to ics721 and then call receive proxy test.app .execute_contract( test.app.api().addr_make(COLLECTION_OWNER_SOURCE_CHAIN), @@ -1689,15 +1803,15 @@ fn test_proxy_authorized() { .execute_contract( proxy_address, test.ics721, - &ExecuteMsg::ReceiveProxyNft { - eyeball: source_cw721.into_string(), - msg: cw721::Cw721ReceiveMsg { - sender: test - .app - .api() - .addr_make(COLLECTION_OWNER_SOURCE_CHAIN) - .to_string(), - token_id: "1".to_string(), + &ExecuteMsg::ReceiveNft(cw721::Cw721ReceiveMsg { + sender: test + .app + .api() + .addr_make(COLLECTION_OWNER_SOURCE_CHAIN) + .to_string(), + token_id: "1".to_string(), + msg: to_json_binary(&IbcOutgoingProxyMsg { + collection: source_cw721.into_string(), msg: to_json_binary(&IbcOutgoingMsg { receiver: test.app.api().addr_make(NFT_OWNER_TARGET_CHAIN).to_string(), channel_id: "channel-0".to_string(), @@ -1708,8 +1822,9 @@ fn test_proxy_authorized() { memo: None, }) .unwrap(), - }, - }, + }) + .unwrap(), + }), &[], ) .unwrap(); @@ -1719,7 +1834,7 @@ fn test_proxy_authorized() { fn test_receive_nft() { // test case: receive nft from cw721-base { - let mut test = Test::new(false, None, cw721_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_base_contract(), true); // simplify: mint and escrowed/owned by ics721, as a precondition for receive nft let token_id = test.execute_cw721_mint(test.ics721.clone()).unwrap(); // ics721 receives NFT from sender/collection contract, @@ -1787,7 +1902,7 @@ fn test_receive_nft() { } // test case: backward compatibility - receive nft also works for old/v016 cw721-base { - let mut test = Test::new(false, None, cw721_v016_base_contract()); + let mut test = Test::new(false, false, None, None, cw721_v016_base_contract(), false); // simplify: mint and escrowed/owned by ics721, as a precondition for receive nft let token_id = test.execute_cw721_mint(test.ics721.clone()).unwrap(); // ics721 receives NFT from sender/collection contract, @@ -1861,7 +1976,7 @@ fn test_receive_nft() { /// In case proxy for ICS721 is defined, ICS721 only accepts receival from proxy - not from nft contract! #[test] fn test_no_receive_with_proxy() { - let mut test = Test::new(true, None, cw721_base_contract()); + let mut test = Test::new(true, false, None, None, cw721_base_contract(), true); // unauthorized to receive nft from nft contract let err: ContractError = test .app @@ -1895,8 +2010,11 @@ fn test_no_receive_with_proxy() { fn test_pause() { let mut test = Test::new( true, + false, + None, Some(ICS721_ADMIN_AND_PAUSER.to_string()), cw721_base_contract(), + true, ); // Should start unpaused. let (paused, pauser) = test.query_pause_info(); @@ -1951,7 +2069,8 @@ fn test_pause() { new_code_id: ics721_id, msg: to_json_binary(&MigrateMsg::WithUpdate { pauser: Some(test.app.api().addr_make("new_pauser").to_string()), - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, cw721_base_code_id: None, }) .unwrap(), @@ -1977,8 +2096,11 @@ fn test_pause() { fn test_migration() { let mut test = Test::new( true, + false, + None, Some(ICS721_ADMIN_AND_PAUSER.to_string()), cw721_base_contract(), + true, ); // assert instantiation worked let (_, pauser) = test.query_pause_info(); @@ -1986,8 +2108,8 @@ fn test_migration() { pauser, Some(test.app.api().addr_make(ICS721_ADMIN_AND_PAUSER)) ); - let proxy = test.query_proxy(); - assert!(proxy.is_some()); + let outgoing_proxy = test.query_outgoing_proxy(); + assert!(outgoing_proxy.is_some()); let cw721_code_id = test.query_cw721_id(); assert_eq!(cw721_code_id, test.source_cw721_id); @@ -2000,7 +2122,8 @@ fn test_migration() { new_code_id: test.ics721_id, msg: to_json_binary(&MigrateMsg::WithUpdate { pauser: None, - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, cw721_base_code_id: Some(12345678), }) .unwrap(), @@ -2011,7 +2134,7 @@ fn test_migration() { // assert migration worked let (_, pauser) = test.query_pause_info(); assert_eq!(pauser, None); - let proxy = test.query_proxy(); + let proxy = test.query_outgoing_proxy(); assert!(proxy.is_none()); let cw721_code_id = test.query_cw721_id(); assert_eq!(cw721_code_id, 12345678); @@ -2025,7 +2148,8 @@ fn test_migration() { new_code_id: test.ics721_id, msg: to_json_binary(&MigrateMsg::WithUpdate { pauser: None, - proxy: None, + incoming_proxy: None, + outgoing_proxy: None, cw721_base_code_id: None, }) .unwrap(), @@ -2036,7 +2160,7 @@ fn test_migration() { // assert migration worked let (_, pauser) = test.query_pause_info(); assert_eq!(pauser, None); - let proxy = test.query_proxy(); + let proxy = test.query_outgoing_proxy(); assert!(proxy.is_none()); let cw721_code_id = test.query_cw721_id(); assert_eq!(cw721_code_id, 12345678); diff --git a/packages/ics721/src/token_types.rs b/packages/ics721/src/token_types.rs index 8ddc16a5..9e955d9b 100644 --- a/packages/ics721/src/token_types.rs +++ b/packages/ics721/src/token_types.rs @@ -1,45 +1,9 @@ -use std::ops::Deref; - use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_json_binary, Addr, Binary, StdResult, WasmMsg}; -use cw_storage_plus::{Bound, Bounder, Key, KeyDeserialize, Prefixer, PrimaryKey}; +use cosmwasm_std::{to_json_binary, Addr, StdResult, WasmMsg}; +use ics721_types::token_types::{Class, Token, TokenId}; use crate::msg::{CallbackMsg, ExecuteMsg}; -/// A token ID according to the ICS-721 spec. The newtype pattern is -/// used here to provide some distinction between token and class IDs -/// in the type system. -#[cw_serde] -pub struct TokenId(String); - -/// A token according to the ICS-721 spec. -#[cw_serde] -pub struct Token { - /// A unique identifier for the token. - pub id: TokenId, - /// Optional URI pointing to off-chain metadata about the token. - pub uri: Option, - /// Optional base64 encoded metadata about the token. - pub data: Option, -} - -/// A class ID according to the ICS-721 spec. The newtype pattern is -/// used here to provide some distinction between token and class IDs -/// in the type system. -#[cw_serde] -pub struct ClassId(String); - -#[cw_serde] -pub struct Class { - /// A unique (from the source chain's perspective) identifier for - /// the class. - pub id: ClassId, - /// Optional URI pointing to off-chain metadata about the class. - pub uri: Option, - /// Optional base64 encoded metadata about the class. - pub data: Option, -} - #[cw_serde] pub struct VoucherRedemption { /// The class that these vouchers are being redeemed from. @@ -56,34 +20,6 @@ pub struct VoucherCreation { pub tokens: Vec, } -impl TokenId { - pub fn new(token_id: T) -> Self - where - T: Into, - { - Self(token_id.into()) - } -} - -impl ClassId { - pub fn new(class_id: T) -> Self - where - T: Into, - { - Self(class_id.into()) - } -} - -impl<'a> Bounder<'a> for ClassId { - fn inclusive_bound(self) -> Option> { - Some(Bound::inclusive(self)) - } - - fn exclusive_bound(self) -> Option> { - Some(Bound::exclusive(self)) - } -} - impl VoucherRedemption { /// Transforms information about a redemption of vouchers into a /// message that may be executed to redeem said vouchers. @@ -127,81 +63,3 @@ impl VoucherCreation { }) } } - -// boilerplate for conversion between wrappers and the wrapped. - -impl From for String { - fn from(c: ClassId) -> Self { - c.0 - } -} - -impl From for String { - fn from(t: TokenId) -> Self { - t.0 - } -} - -impl Deref for ClassId { - type Target = str; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::fmt::Display for ClassId { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } -} - -// boilerplate for storing these wrapper types in CosmWasm maps. - -impl<'a> PrimaryKey<'a> for ClassId { - type Prefix = >::Prefix; - type SubPrefix = >::SubPrefix; - type Suffix = >::Suffix; - type SuperSuffix = >::SuperSuffix; - - fn key(&self) -> Vec { - self.0.key() - } -} - -impl<'a> PrimaryKey<'a> for TokenId { - type Prefix = >::Prefix; - type SubPrefix = >::SubPrefix; - type Suffix = >::Suffix; - type SuperSuffix = >::SuperSuffix; - - fn key(&self) -> Vec { - self.0.key() - } -} - -impl<'a> Prefixer<'a> for ClassId { - fn prefix(&self) -> Vec { - self.0.prefix() - } -} - -impl<'a> Prefixer<'a> for TokenId { - fn prefix(&self) -> Vec { - self.0.prefix() - } -} - -impl KeyDeserialize for ClassId { - type Output = ::Output; - fn from_vec(value: Vec) -> StdResult { - String::from_vec(value) - } -} - -impl KeyDeserialize for TokenId { - type Output = ::Output; - fn from_vec(value: Vec) -> StdResult { - String::from_vec(value) - } -} diff --git a/ts-relayer-tests/build.sh b/ts-relayer-tests/build.sh index e58de99d..bcef98c7 100755 --- a/ts-relayer-tests/build.sh +++ b/ts-relayer-tests/build.sh @@ -11,7 +11,7 @@ cd "$(git rev-parse --show-toplevel)" docker run --rm -v "$(pwd)":/code --platform linux/amd64 \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.14.0 + cosmwasm/workspace-optimizer:0.15.0 mkdir -p ./ts-relayer-tests/internal cp ./artifacts/*.wasm ./ts-relayer-tests/internal diff --git a/ts-relayer-tests/package-lock.json b/ts-relayer-tests/package-lock.json index 50588877..986325cc 100644 --- a/ts-relayer-tests/package-lock.json +++ b/ts-relayer-tests/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "license": "Apache-2.0", "dependencies": { - "@confio/relayer": "^0.10" + "@confio/relayer": "^0.11" }, "devDependencies": { "@ava/typescript": "^3.0.1", @@ -449,24 +449,24 @@ } }, "node_modules/@confio/relayer": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.10.0.tgz", - "integrity": "sha512-/WW5Eyfgylby9u0wz6XakA7yo5hamdWh6pxkOYHPz0ls7ikd7Ld+c2fpRbL0Qg5wZn9+9P+Uhfj4l0pVl3WPgw==", - "dependencies": { - "@cosmjs/cosmwasm-stargate": "^0.31.0", - "@cosmjs/crypto": "^0.31.0", - "@cosmjs/encoding": "^0.31.0", - "@cosmjs/faucet-client": "^0.31.0", - "@cosmjs/math": "^0.31.0", - "@cosmjs/proto-signing": "^0.31.0", - "@cosmjs/stargate": "^0.31.0", - "@cosmjs/stream": "^0.31.0", - "@cosmjs/tendermint-rpc": "^0.31.0", - "@cosmjs/utils": "^0.31.0", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.11.2.tgz", + "integrity": "sha512-xzTtY1HaV7qX5lsrWBAzaktzEc43Q2Q/bq7rard79JSyGKDfkR2GlFXZoSxYZ4j4L4ZXO50wf9gz5WcUbBl2kA==", + "dependencies": { + "@cosmjs/cosmwasm-stargate": "^0.32.1", + "@cosmjs/crypto": "^0.32.1", + "@cosmjs/encoding": "^0.32.1", + "@cosmjs/faucet-client": "^0.32.1", + "@cosmjs/math": "^0.32.1", + "@cosmjs/proto-signing": "^0.32.1", + "@cosmjs/stargate": "^0.32.1", + "@cosmjs/stream": "^0.32.1", + "@cosmjs/tendermint-rpc": "^0.32.1", + "@cosmjs/utils": "^0.32.1", "ajv": "7.1.1", "axios": "0.21.4", "commander": "7.1.0", - "cosmjs-types": "^0.8.0", + "cosmjs-types": "^0.9.0", "fast-safe-stringify": "2.0.4", "js-yaml": "4.0.0", "lodash": "4.17.21", @@ -485,42 +485,41 @@ } }, "node_modules/@cosmjs/amino": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.31.3.tgz", - "integrity": "sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.32.2.tgz", + "integrity": "sha512-lcK5RCVm4OfdAooxKcF2+NwaDVVpghOq6o/A40c2mHXDUzUoRZ33VAHjVJ9Me6vOFxshrw/XEFn1f4KObntjYA==", "dependencies": { - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/utils": "^0.31.3" + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/utils": "^0.32.2" } }, "node_modules/@cosmjs/cosmwasm-stargate": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.31.3.tgz", - "integrity": "sha512-Uv9TmCn3650gdFeZm7SEfUZF3uX3lfJfFhXOk6I2ZLr/FrKximnlb+vwAfZaZnWYvlA7qrKtHIjeRNHvT23zcw==", - "dependencies": { - "@cosmjs/amino": "^0.31.3", - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/proto-signing": "^0.31.3", - "@cosmjs/stargate": "^0.31.3", - "@cosmjs/tendermint-rpc": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.2.tgz", + "integrity": "sha512-OwJHzIx2CoJS6AULxOpNR6m+CI0GXxy8z9svHA1ZawzNM3ZGlL0GvHdhmF0WkpX4E7UdrYlJSLpKcgg5Fo6i7Q==", + "dependencies": { + "@cosmjs/amino": "^0.32.2", + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/proto-signing": "^0.32.2", + "@cosmjs/stargate": "^0.32.2", + "@cosmjs/tendermint-rpc": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "cosmjs-types": "^0.9.0", "pako": "^2.0.2" } }, "node_modules/@cosmjs/crypto": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.31.3.tgz", - "integrity": "sha512-vRbvM9ZKR2017TO73dtJ50KxoGcFzKtKI7C8iO302BQ5p+DuB+AirUg1952UpSoLfv5ki9O416MFANNg8UN/EQ==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.32.2.tgz", + "integrity": "sha512-RuxrYKzhrPF9g6NmU7VEq++Hn1vZJjqqJpZ9Tmw9lOYOV8BUsv+j/0BE86kmWi7xVJ7EwxiuxYsKuM8IR18CIA==", "dependencies": { - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/utils": "^0.31.3", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/utils": "^0.32.2", "@noble/hashes": "^1", "bn.js": "^5.2.0", "elliptic": "^6.5.4", @@ -528,9 +527,9 @@ } }, "node_modules/@cosmjs/encoding": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.3.tgz", - "integrity": "sha512-6IRtG0fiVYwyP7n+8e54uTx2pLYijO48V3t9TLiROERm5aUAIzIlz6Wp0NYaI5he9nh1lcEGJ1lkquVKFw3sUg==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.32.2.tgz", + "integrity": "sha512-WX7m1wLpA9V/zH0zRcz4EmgZdAv1F44g4dbXOgNj1eXZw1PIGR12p58OEkLN51Ha3S4DKRtCv5CkhK1KHEvQtg==", "dependencies": { "base64-js": "^1.3.0", "bech32": "^1.1.4", @@ -538,103 +537,120 @@ } }, "node_modules/@cosmjs/faucet-client": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.31.3.tgz", - "integrity": "sha512-gsVD/UD1R2k00iRVcBwXRgTkwzsnapfw8n1eWfc7o44xg0aVG8YL84ntj2YmjC9+NHCp2rmK9xndQeUOFIszOA==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.32.2.tgz", + "integrity": "sha512-tRumHGAURhCV7xvxPltwqiMX2bwJYR6M8Im586hnwVC+Ww2+TwH9c0QjZiUmWzZgCDUPkaSwVswUgucB7H59xA==", "dependencies": { - "axios": "^0.21.2" + "axios": "^1.6.0" + } + }, + "node_modules/@cosmjs/faucet-client/node_modules/axios": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", + "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/@cosmjs/json-rpc": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.31.3.tgz", - "integrity": "sha512-7LVYerXjnm69qqYR3uA6LGCrBW2EO5/F7lfJxAmY+iII2C7xO3a0vAjMSt5zBBh29PXrJVS6c2qRP22W1Le2Wg==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.32.2.tgz", + "integrity": "sha512-lan2lOgmz4yVE/HR8eCOSiII/1OudIulk8836koyIDCsPEpt6eKBuctnAD168vABGArKccLAo7Mr2gy9nrKrOQ==", "dependencies": { - "@cosmjs/stream": "^0.31.3", + "@cosmjs/stream": "^0.32.2", "xstream": "^11.14.0" } }, "node_modules/@cosmjs/math": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.31.3.tgz", - "integrity": "sha512-kZ2C6glA5HDb9hLz1WrftAjqdTBb3fWQsRR+Us2HsjAYdeE6M3VdXMsYCP5M3yiihal1WDwAY2U7HmfJw7Uh4A==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.32.2.tgz", + "integrity": "sha512-b8+ruAAY8aKtVKWSft2IvtCVCUH1LigIlf9ALIiY8n9jtM4kMASiaRbQ/27etnSAInV88IaezKK9rQZrtxTjcw==", "dependencies": { "bn.js": "^5.2.0" } }, "node_modules/@cosmjs/proto-signing": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.3.tgz", - "integrity": "sha512-24+10/cGl6lLS4VCrGTCJeDRPQTn1K5JfknzXzDIHOx8THR31JxA7/HV5eWGHqWgAbudA7ccdSvEK08lEHHtLA==", - "dependencies": { - "@cosmjs/amino": "^0.31.3", - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.32.2.tgz", + "integrity": "sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw==", + "dependencies": { + "@cosmjs/amino": "^0.32.2", + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "cosmjs-types": "^0.9.0" } }, "node_modules/@cosmjs/socket": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.31.3.tgz", - "integrity": "sha512-aqrDGGi7os/hsz5p++avI4L0ZushJ+ItnzbqA7C6hamFSCJwgOkXaOUs+K9hXZdX4rhY7rXO4PH9IH8q09JkTw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.32.2.tgz", + "integrity": "sha512-Qc8jaw4uSBJm09UwPgkqe3g9TBFx4ZR9HkXpwT6Z9I+6kbLerXPR0Gy3NSJFSUgxIfTpO8O1yqoWAyf0Ay17Mw==", "dependencies": { - "@cosmjs/stream": "^0.31.3", + "@cosmjs/stream": "^0.32.2", "isomorphic-ws": "^4.0.1", "ws": "^7", "xstream": "^11.14.0" } }, "node_modules/@cosmjs/stargate": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.31.3.tgz", - "integrity": "sha512-53NxnzmB9FfXpG4KjOUAYAvWLYKdEmZKsutcat/u2BrDXNZ7BN8jim/ENcpwXfs9/Og0K24lEIdvA4gsq3JDQw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.32.2.tgz", + "integrity": "sha512-AsJa29fT7Jd4xt9Ai+HMqhyj7UQu7fyYKdXj/8+/9PD74xe6lZSYhQPcitUmMLJ1ckKPgXSk5Dd2LbsQT0IhZg==", "dependencies": { "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/proto-signing": "^0.31.3", - "@cosmjs/stream": "^0.31.3", - "@cosmjs/tendermint-rpc": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", - "protobufjs": "~6.11.3", + "@cosmjs/amino": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/proto-signing": "^0.32.2", + "@cosmjs/stream": "^0.32.2", + "@cosmjs/tendermint-rpc": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "cosmjs-types": "^0.9.0", "xstream": "^11.14.0" } }, "node_modules/@cosmjs/stream": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.31.3.tgz", - "integrity": "sha512-8keYyI7X0RjsLyVcZuBeNjSv5FA4IHwbFKx7H60NHFXszN8/MvXL6aZbNIvxtcIHHsW7K9QSQos26eoEWlAd+w==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.32.2.tgz", + "integrity": "sha512-gpCufLfHAD8Zp1ZKge7AHbDf4RA0TZp66wZY6JaQR5bSiEF2Drjtp4mwXZPGejtaUMnaAgff3LrUzPJfKYdQwg==", "dependencies": { "xstream": "^11.14.0" } }, "node_modules/@cosmjs/tendermint-rpc": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.31.3.tgz", - "integrity": "sha512-s3TiWkPCW4QceTQjpYqn4xttUJH36mTPqplMl+qyocdqk5+X5mergzExU/pHZRWQ4pbby8bnR7kMvG4OC1aZ8g==", - "dependencies": { - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/json-rpc": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/socket": "^0.31.3", - "@cosmjs/stream": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "axios": "^0.21.2", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.2.tgz", + "integrity": "sha512-DXyJHDmcAfCix4H/7/dKR0UMdshP01KxJOXHdHxBCbLIpck94BsWD3B2ZTXwfA6sv98so9wOzhp7qGQa5malxg==", + "dependencies": { + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/json-rpc": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/socket": "^0.32.2", + "@cosmjs/stream": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "axios": "^1.6.0", "readonly-date": "^1.0.0", "xstream": "^11.14.0" } }, + "node_modules/@cosmjs/tendermint-rpc/node_modules/axios": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", + "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/@cosmjs/utils": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.31.3.tgz", - "integrity": "sha512-VBhAgzrrYdIe0O5IbKRqwszbQa7ZyQLx9nEQuHQ3HUplQW7P44COG/ye2n6AzCudtqxmwdX7nyX8ta1J07GoqA==" + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.32.2.tgz", + "integrity": "sha512-Gg5t+eR7vPJMAmhkFt6CZrzPd0EKpAslWwk5rFVYZpJsM8JG5KT9XQ99hgNM3Ov6ScNoIWbXkpX27F6A9cXR4Q==" }, "node_modules/@dabh/diagnostics": { "version": "2.0.3", @@ -909,9 +925,9 @@ } }, "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", "engines": { "node": ">= 16" }, @@ -1474,6 +1490,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/ava": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.1.tgz", @@ -1989,6 +2010,17 @@ "text-hex": "1.0.x" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz", @@ -2053,13 +2085,9 @@ } }, "node_modules/cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.9.0.tgz", + "integrity": "sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -2232,6 +2260,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/diff": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", @@ -3103,6 +3139,19 @@ "node": ">=8.0.0" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -4328,6 +4377,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -5544,6 +5612,11 @@ "pbts": "bin/pbts" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -7317,24 +7390,24 @@ } }, "@confio/relayer": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.10.0.tgz", - "integrity": "sha512-/WW5Eyfgylby9u0wz6XakA7yo5hamdWh6pxkOYHPz0ls7ikd7Ld+c2fpRbL0Qg5wZn9+9P+Uhfj4l0pVl3WPgw==", - "requires": { - "@cosmjs/cosmwasm-stargate": "^0.31.0", - "@cosmjs/crypto": "^0.31.0", - "@cosmjs/encoding": "^0.31.0", - "@cosmjs/faucet-client": "^0.31.0", - "@cosmjs/math": "^0.31.0", - "@cosmjs/proto-signing": "^0.31.0", - "@cosmjs/stargate": "^0.31.0", - "@cosmjs/stream": "^0.31.0", - "@cosmjs/tendermint-rpc": "^0.31.0", - "@cosmjs/utils": "^0.31.0", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.11.2.tgz", + "integrity": "sha512-xzTtY1HaV7qX5lsrWBAzaktzEc43Q2Q/bq7rard79JSyGKDfkR2GlFXZoSxYZ4j4L4ZXO50wf9gz5WcUbBl2kA==", + "requires": { + "@cosmjs/cosmwasm-stargate": "^0.32.1", + "@cosmjs/crypto": "^0.32.1", + "@cosmjs/encoding": "^0.32.1", + "@cosmjs/faucet-client": "^0.32.1", + "@cosmjs/math": "^0.32.1", + "@cosmjs/proto-signing": "^0.32.1", + "@cosmjs/stargate": "^0.32.1", + "@cosmjs/stream": "^0.32.1", + "@cosmjs/tendermint-rpc": "^0.32.1", + "@cosmjs/utils": "^0.32.1", "ajv": "7.1.1", "axios": "0.21.4", "commander": "7.1.0", - "cosmjs-types": "^0.8.0", + "cosmjs-types": "^0.9.0", "fast-safe-stringify": "2.0.4", "js-yaml": "4.0.0", "lodash": "4.17.21", @@ -7346,42 +7419,41 @@ } }, "@cosmjs/amino": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.31.3.tgz", - "integrity": "sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.32.2.tgz", + "integrity": "sha512-lcK5RCVm4OfdAooxKcF2+NwaDVVpghOq6o/A40c2mHXDUzUoRZ33VAHjVJ9Me6vOFxshrw/XEFn1f4KObntjYA==", "requires": { - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/utils": "^0.31.3" + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/utils": "^0.32.2" } }, "@cosmjs/cosmwasm-stargate": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.31.3.tgz", - "integrity": "sha512-Uv9TmCn3650gdFeZm7SEfUZF3uX3lfJfFhXOk6I2ZLr/FrKximnlb+vwAfZaZnWYvlA7qrKtHIjeRNHvT23zcw==", - "requires": { - "@cosmjs/amino": "^0.31.3", - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/proto-signing": "^0.31.3", - "@cosmjs/stargate": "^0.31.3", - "@cosmjs/tendermint-rpc": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.2.tgz", + "integrity": "sha512-OwJHzIx2CoJS6AULxOpNR6m+CI0GXxy8z9svHA1ZawzNM3ZGlL0GvHdhmF0WkpX4E7UdrYlJSLpKcgg5Fo6i7Q==", + "requires": { + "@cosmjs/amino": "^0.32.2", + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/proto-signing": "^0.32.2", + "@cosmjs/stargate": "^0.32.2", + "@cosmjs/tendermint-rpc": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "cosmjs-types": "^0.9.0", "pako": "^2.0.2" } }, "@cosmjs/crypto": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.31.3.tgz", - "integrity": "sha512-vRbvM9ZKR2017TO73dtJ50KxoGcFzKtKI7C8iO302BQ5p+DuB+AirUg1952UpSoLfv5ki9O416MFANNg8UN/EQ==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.32.2.tgz", + "integrity": "sha512-RuxrYKzhrPF9g6NmU7VEq++Hn1vZJjqqJpZ9Tmw9lOYOV8BUsv+j/0BE86kmWi7xVJ7EwxiuxYsKuM8IR18CIA==", "requires": { - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/utils": "^0.31.3", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/utils": "^0.32.2", "@noble/hashes": "^1", "bn.js": "^5.2.0", "elliptic": "^6.5.4", @@ -7389,9 +7461,9 @@ } }, "@cosmjs/encoding": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.3.tgz", - "integrity": "sha512-6IRtG0fiVYwyP7n+8e54uTx2pLYijO48V3t9TLiROERm5aUAIzIlz6Wp0NYaI5he9nh1lcEGJ1lkquVKFw3sUg==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.32.2.tgz", + "integrity": "sha512-WX7m1wLpA9V/zH0zRcz4EmgZdAv1F44g4dbXOgNj1eXZw1PIGR12p58OEkLN51Ha3S4DKRtCv5CkhK1KHEvQtg==", "requires": { "base64-js": "^1.3.0", "bech32": "^1.1.4", @@ -7399,103 +7471,124 @@ } }, "@cosmjs/faucet-client": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.31.3.tgz", - "integrity": "sha512-gsVD/UD1R2k00iRVcBwXRgTkwzsnapfw8n1eWfc7o44xg0aVG8YL84ntj2YmjC9+NHCp2rmK9xndQeUOFIszOA==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.32.2.tgz", + "integrity": "sha512-tRumHGAURhCV7xvxPltwqiMX2bwJYR6M8Im586hnwVC+Ww2+TwH9c0QjZiUmWzZgCDUPkaSwVswUgucB7H59xA==", "requires": { - "axios": "^0.21.2" + "axios": "^1.6.0" + }, + "dependencies": { + "axios": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", + "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + } } }, "@cosmjs/json-rpc": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.31.3.tgz", - "integrity": "sha512-7LVYerXjnm69qqYR3uA6LGCrBW2EO5/F7lfJxAmY+iII2C7xO3a0vAjMSt5zBBh29PXrJVS6c2qRP22W1Le2Wg==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.32.2.tgz", + "integrity": "sha512-lan2lOgmz4yVE/HR8eCOSiII/1OudIulk8836koyIDCsPEpt6eKBuctnAD168vABGArKccLAo7Mr2gy9nrKrOQ==", "requires": { - "@cosmjs/stream": "^0.31.3", + "@cosmjs/stream": "^0.32.2", "xstream": "^11.14.0" } }, "@cosmjs/math": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.31.3.tgz", - "integrity": "sha512-kZ2C6glA5HDb9hLz1WrftAjqdTBb3fWQsRR+Us2HsjAYdeE6M3VdXMsYCP5M3yiihal1WDwAY2U7HmfJw7Uh4A==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.32.2.tgz", + "integrity": "sha512-b8+ruAAY8aKtVKWSft2IvtCVCUH1LigIlf9ALIiY8n9jtM4kMASiaRbQ/27etnSAInV88IaezKK9rQZrtxTjcw==", "requires": { "bn.js": "^5.2.0" } }, "@cosmjs/proto-signing": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.3.tgz", - "integrity": "sha512-24+10/cGl6lLS4VCrGTCJeDRPQTn1K5JfknzXzDIHOx8THR31JxA7/HV5eWGHqWgAbudA7ccdSvEK08lEHHtLA==", - "requires": { - "@cosmjs/amino": "^0.31.3", - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.32.2.tgz", + "integrity": "sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw==", + "requires": { + "@cosmjs/amino": "^0.32.2", + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "cosmjs-types": "^0.9.0" } }, "@cosmjs/socket": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.31.3.tgz", - "integrity": "sha512-aqrDGGi7os/hsz5p++avI4L0ZushJ+ItnzbqA7C6hamFSCJwgOkXaOUs+K9hXZdX4rhY7rXO4PH9IH8q09JkTw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.32.2.tgz", + "integrity": "sha512-Qc8jaw4uSBJm09UwPgkqe3g9TBFx4ZR9HkXpwT6Z9I+6kbLerXPR0Gy3NSJFSUgxIfTpO8O1yqoWAyf0Ay17Mw==", "requires": { - "@cosmjs/stream": "^0.31.3", + "@cosmjs/stream": "^0.32.2", "isomorphic-ws": "^4.0.1", "ws": "^7", "xstream": "^11.14.0" } }, "@cosmjs/stargate": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.31.3.tgz", - "integrity": "sha512-53NxnzmB9FfXpG4KjOUAYAvWLYKdEmZKsutcat/u2BrDXNZ7BN8jim/ENcpwXfs9/Og0K24lEIdvA4gsq3JDQw==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.32.2.tgz", + "integrity": "sha512-AsJa29fT7Jd4xt9Ai+HMqhyj7UQu7fyYKdXj/8+/9PD74xe6lZSYhQPcitUmMLJ1ckKPgXSk5Dd2LbsQT0IhZg==", "requires": { "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/proto-signing": "^0.31.3", - "@cosmjs/stream": "^0.31.3", - "@cosmjs/tendermint-rpc": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", - "protobufjs": "~6.11.3", + "@cosmjs/amino": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/proto-signing": "^0.32.2", + "@cosmjs/stream": "^0.32.2", + "@cosmjs/tendermint-rpc": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "cosmjs-types": "^0.9.0", "xstream": "^11.14.0" } }, "@cosmjs/stream": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.31.3.tgz", - "integrity": "sha512-8keYyI7X0RjsLyVcZuBeNjSv5FA4IHwbFKx7H60NHFXszN8/MvXL6aZbNIvxtcIHHsW7K9QSQos26eoEWlAd+w==", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.32.2.tgz", + "integrity": "sha512-gpCufLfHAD8Zp1ZKge7AHbDf4RA0TZp66wZY6JaQR5bSiEF2Drjtp4mwXZPGejtaUMnaAgff3LrUzPJfKYdQwg==", "requires": { "xstream": "^11.14.0" } }, "@cosmjs/tendermint-rpc": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.31.3.tgz", - "integrity": "sha512-s3TiWkPCW4QceTQjpYqn4xttUJH36mTPqplMl+qyocdqk5+X5mergzExU/pHZRWQ4pbby8bnR7kMvG4OC1aZ8g==", - "requires": { - "@cosmjs/crypto": "^0.31.3", - "@cosmjs/encoding": "^0.31.3", - "@cosmjs/json-rpc": "^0.31.3", - "@cosmjs/math": "^0.31.3", - "@cosmjs/socket": "^0.31.3", - "@cosmjs/stream": "^0.31.3", - "@cosmjs/utils": "^0.31.3", - "axios": "^0.21.2", + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.2.tgz", + "integrity": "sha512-DXyJHDmcAfCix4H/7/dKR0UMdshP01KxJOXHdHxBCbLIpck94BsWD3B2ZTXwfA6sv98so9wOzhp7qGQa5malxg==", + "requires": { + "@cosmjs/crypto": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/json-rpc": "^0.32.2", + "@cosmjs/math": "^0.32.2", + "@cosmjs/socket": "^0.32.2", + "@cosmjs/stream": "^0.32.2", + "@cosmjs/utils": "^0.32.2", + "axios": "^1.6.0", "readonly-date": "^1.0.0", "xstream": "^11.14.0" + }, + "dependencies": { + "axios": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz", + "integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + } } }, "@cosmjs/utils": { - "version": "0.31.3", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.31.3.tgz", - "integrity": "sha512-VBhAgzrrYdIe0O5IbKRqwszbQa7ZyQLx9nEQuHQ3HUplQW7P44COG/ye2n6AzCudtqxmwdX7nyX8ta1J07GoqA==" + "version": "0.32.2", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.32.2.tgz", + "integrity": "sha512-Gg5t+eR7vPJMAmhkFt6CZrzPd0EKpAslWwk5rFVYZpJsM8JG5KT9XQ99hgNM3Ov6ScNoIWbXkpX27F6A9cXR4Q==" }, "@dabh/diagnostics": { "version": "2.0.3", @@ -7713,9 +7806,9 @@ } }, "@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", + "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==" }, "@nodelib/fs.scandir": { "version": "2.1.5", @@ -8105,6 +8198,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "ava": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.1.tgz", @@ -8491,6 +8589,14 @@ "text-hex": "1.0.x" } }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz", @@ -8546,13 +8652,9 @@ "dev": true }, "cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.9.0.tgz", + "integrity": "sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==" }, "cross-spawn": { "version": "7.0.3", @@ -8679,6 +8781,11 @@ } } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, "diff": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", @@ -9357,6 +9464,16 @@ "signal-exit": "^3.0.2" } }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", @@ -10237,6 +10354,19 @@ "picomatch": "^2.3.1" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, "mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -11136,6 +11266,11 @@ "long": "^4.0.0" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", diff --git a/ts-relayer-tests/package.json b/ts-relayer-tests/package.json index 2718a8a3..0fc49f0f 100644 --- a/ts-relayer-tests/package.json +++ b/ts-relayer-tests/package.json @@ -20,7 +20,7 @@ "test:unit": "nyc --silent ava --serial" }, "dependencies": { - "@confio/relayer": "^0.10" + "@confio/relayer": "^0.11" }, "devDependencies": { "@ava/typescript": "^3.0.1", diff --git a/ts-relayer-tests/src/controller.ts b/ts-relayer-tests/src/controller.ts index 05af7ec8..12af6e6c 100644 --- a/ts-relayer-tests/src/controller.ts +++ b/ts-relayer-tests/src/controller.ts @@ -13,7 +13,10 @@ export async function instantiateContract( codeId, msg, label, - "auto" + "auto", + { + admin: client.senderAddress, + } ); assert(result.contractAddress); return result; diff --git a/ts-relayer-tests/src/ics721-utils.ts b/ts-relayer-tests/src/ics721-utils.ts new file mode 100644 index 00000000..398eefac --- /dev/null +++ b/ts-relayer-tests/src/ics721-utils.ts @@ -0,0 +1,23 @@ +import { CosmWasmSigner } from "@confio/relayer"; + +// ######### execute + +export function migrate( + client: CosmWasmSigner, + contractAddress: string, + codeId: number, + incoming_proxy?: string, + outgoing_proxy?: string +) { + const msg = { + with_update: { incoming_proxy, outgoing_proxy }, + }; + return client.sign.migrate( + client.senderAddress, + contractAddress, + codeId, + msg, + "auto", + undefined + ); +} diff --git a/ts-relayer-tests/src/ics721.spec.ts b/ts-relayer-tests/src/ics721.spec.ts index 223e13d1..530de734 100644 --- a/ts-relayer-tests/src/ics721.spec.ts +++ b/ts-relayer-tests/src/ics721.spec.ts @@ -4,10 +4,12 @@ import { Order } from "cosmjs-types/ibc/core/channel/v1/channel"; import { instantiateContract } from "./controller"; import { mint, ownerOf, sendNft } from "./cw721-utils"; +import { migrate } from "./ics721-utils"; import { assertAckErrors, assertAckSuccess, - ChannelInfo, + bigIntReplacer, + ChannelAndLinkInfo, ContractMsg, createIbcConnectionAndChannel, MNEMONIC, @@ -26,15 +28,23 @@ interface TestContext { wasmCw721: string; wasmIcs721: string; + wasmCw721IncomingProxy: string; + osmoCw721: string; osmoIcs721: string; + osmoCw721OutgoingProxy: string; - channel: ChannelInfo; + channel: ChannelAndLinkInfo; + + otherChannel: ChannelAndLinkInfo; } const test = anyTest as TestFn; const WASM_FILE_CW721 = "./internal/cw721_base_v0.18.0.wasm"; +const WASM_FILE_CW721_INCOMING_PROXY = "./internal/cw721_incoming_proxy.wasm"; +const WASM_FILE_CW721_OUTGOING_PROXY = + "./internal/cw721_outgoing_proxy_rate_limit.wasm"; const WASM_FILE_CW_ICS721_ICS721 = "./internal/ics721_base.wasm"; const MALICIOUS_CW721 = "./internal/cw721_tester.wasm"; @@ -56,6 +66,10 @@ const standardSetup = async (t: ExecutionContext) => { minter: wasmClient.senderAddress, }, }, + cw721IncomingProxy: { + path: WASM_FILE_CW721_INCOMING_PROXY, + instantiateMsg: undefined, + }, ics721: { path: WASM_FILE_CW_ICS721_ICS721, instantiateMsg: undefined, @@ -64,6 +78,14 @@ const standardSetup = async (t: ExecutionContext) => { const osmoContracts: Record = { cw721: { path: WASM_FILE_CW721, + instantiateMsg: { + name: "ark", + symbol: "ark", + minter: osmoClient.senderAddress, + }, + }, + cw721OutgoingProxy: { + path: WASM_FILE_CW721_OUTGOING_PROXY, instantiateMsg: undefined, }, ics721: { @@ -82,31 +104,41 @@ const standardSetup = async (t: ExecutionContext) => { const wasmCw721Id = info.wasmContractInfos.cw721.codeId; const osmoCw721Id = info.osmoContractInfos.cw721.codeId; + const wasmCw721IncomingProxyId = + info.wasmContractInfos.cw721IncomingProxy.codeId; + const wasmIcs721Id = info.wasmContractInfos.ics721.codeId; const osmoIcs721Id = info.osmoContractInfos.ics721.codeId; + const osmoCw721OutgoingProxyId = + info.osmoContractInfos.cw721OutgoingProxy.codeId; + t.context.wasmCw721 = info.wasmContractInfos.cw721.address as string; + t.context.osmoCw721 = info.osmoContractInfos.cw721.address as string; t.log(`instantiating wasm ICS721 contract (${wasmIcs721Id})`); - const { contractAddress: wasmIcs721 } = await instantiateContract( wasmClient, wasmIcs721Id, { cw721_base_code_id: wasmCw721Id }, "label ics721" ); + t.log(`- wasm ICS721 contract address: ${wasmIcs721}`); t.context.wasmIcs721 = wasmIcs721; t.log(`instantiating osmo ICS721 contract (${osmoIcs721Id})`); - const { contractAddress: osmoIcs721 } = await instantiateContract( osmoClient, osmoIcs721Id, { cw721_base_code_id: osmoCw721Id }, "label ics721" ); + t.log(`- osmo ICS721 contract address: ${osmoIcs721}`); t.context.osmoIcs721 = osmoIcs721; + t.log( + `creating IBC connection and channel between ${wasmIcs721} <-> ${osmoIcs721}` + ); const channelInfo = await createIbcConnectionAndChannel( wasmClient, osmoClient, @@ -115,13 +147,73 @@ const standardSetup = async (t: ExecutionContext) => { Order.ORDER_UNORDERED, "ics721-1" ); - + t.log(`- channel: ${JSON.stringify(channelInfo, bigIntReplacer, 2)}`); t.context.channel = channelInfo; + t.log( + `instantiating wasm cw721-incoming-proxy (${wasmCw721IncomingProxyId}) for channel ${channelInfo.channel.src.channelId}` + ); + const { contractAddress: wasmCw721IncomingProxy } = await instantiateContract( + wasmClient, + wasmCw721IncomingProxyId, + { + origin: wasmIcs721, + channels: [channelInfo.channel.src.channelId], + }, + "label incoming proxy" + ); + t.log(`- wasm cw721-incoming-proxy address: ${wasmCw721IncomingProxy}`); + t.context.wasmCw721IncomingProxy = wasmCw721IncomingProxy; + + t.log( + `migrate ${wasmIcs721} contract to use incoming proxy ${wasmCw721IncomingProxy}` + ); + await migrate(wasmClient, wasmIcs721, wasmIcs721Id, wasmCw721IncomingProxy); + + const per_block = 10; // use high rate limit to avoid test failures + t.log( + `instantiating osmo cw721-outgoing-proxy (${osmoCw721OutgoingProxyId}) with ${per_block} per blocks rate limit` + ); + const { contractAddress: osmoCw721OutgoingProxy } = await instantiateContract( + osmoClient, + osmoCw721OutgoingProxyId, + { + origin: osmoIcs721, + rate_limit: { per_block }, + }, + "label outgoing proxy" + ); + t.log(`- osmo cw721-outgoing-proxy address: ${osmoCw721OutgoingProxy}`); + t.context.osmoCw721OutgoingProxy = osmoCw721OutgoingProxy; + + t.log( + `migrate ${osmoIcs721} contract to use outgoing proxy ${osmoCw721OutgoingProxy}` + ); + await migrate( + osmoClient, + osmoIcs721, + osmoIcs721Id, + undefined, + osmoCw721OutgoingProxy + ); + + t.log( + `creating another IBC connection and channel between wasm and osmo (${wasmIcs721} <-> ${osmoIcs721})` + ); + const otherChannelInfo = await createIbcConnectionAndChannel( + wasmClient, + osmoClient, + wasmIcs721, + osmoIcs721, + Order.ORDER_UNORDERED, + "ics721-1" + ); + t.context.otherChannel = otherChannelInfo; + t.pass(); }; -test.serial("transfer NFT", async (t) => { +test.serial("transfer NFT: wasmd -> osmo", async (t) => { await standardSetup(t); const { @@ -153,7 +245,7 @@ test.serial("transfer NFT", async (t) => { }, }; - t.log("transfering to osmo chain"); + t.log(`transfering to osmo chain via ${channel.channel.src.channelId}`); const transferResponse = await sendNft( wasmClient, @@ -175,8 +267,6 @@ test.serial("transfer NFT", async (t) => { tokenOwner = await ownerOf(wasmClient, wasmCw721, tokenId); t.is(wasmIcs721, tokenOwner.owner); - t.context.channel.channel.dest.channelId; - const osmoClassId = `${t.context.channel.channel.dest.portId}/${t.context.channel.channel.dest.channelId}/${t.context.wasmCw721}`; const osmoCw721 = await osmoClient.sign.queryContractSmart(osmoIcs721, { nft_contract: { class_id: osmoClassId }, @@ -186,17 +276,135 @@ test.serial("transfer NFT", async (t) => { t.is(osmoAddr, tokenOwner.owner); }); +test.serial( + "transfer NFT with osmo outgoing and wasm incoming proxy", + async (t) => { + await standardSetup(t); + + const { + wasmClient, + wasmAddr, + wasmIcs721, + osmoClient, + osmoAddr, + osmoCw721, + osmoIcs721, + osmoCw721OutgoingProxy, + channel, + otherChannel, + } = t.context; + + // test 1: transfer via outgoing proxy and using WLed channel by incoming proxy + let tokenId = "1"; + t.log(`transferring NFT #${tokenId} from osmo to wasmd chain`); + await mint(osmoClient, osmoCw721, tokenId, osmoAddr, undefined); + // assert token is minted + let tokenOwner = await ownerOf(osmoClient, osmoCw721, tokenId); + t.is(osmoAddr, tokenOwner.owner); + + let ibcMsg = { + receiver: wasmAddr, + channel_id: channel.channel.dest.channelId, + timeout: { + block: { + revision: 1, + height: 90000, + }, + }, + }; + + t.log( + `transfering to wasm chain via ${channel.channel.dest.channelId} and outgoing proxy ${osmoCw721OutgoingProxy}` + ); + + let transferResponse = await sendNft( + osmoClient, + osmoCw721, + osmoCw721OutgoingProxy, + ibcMsg, + tokenId + ); + t.truthy(transferResponse); + + t.log("relaying packets"); + + let info = await channel.link.relayAll(); + + // Verify we got a success + assertAckSuccess(info.acksFromA); + + // assert NFT on chain A is locked/owned by ICS contract + tokenOwner = await ownerOf(osmoClient, osmoCw721, tokenId); + t.is(osmoIcs721, tokenOwner.owner); + t.log(`NFT #${tokenId} locked by ICS721 contract`); + + const wasmClassId = `${t.context.channel.channel.src.portId}/${t.context.channel.channel.src.channelId}/${t.context.osmoCw721}`; + const wasmCw721 = await wasmClient.sign.queryContractSmart(wasmIcs721, { + nft_contract: { class_id: wasmClassId }, + }); + + tokenOwner = await ownerOf(wasmClient, wasmCw721, tokenId); + t.is(wasmAddr, tokenOwner.owner); + t.log(`NFT #${tokenId} transferred to ${wasmAddr}`); + + // test 2: transfer via outgoing proxy and using unknown channel by incoming proxy + tokenId = "2"; + t.log(`transferring NFT #${tokenId} from osmo to wasmd chain`); + await mint(osmoClient, osmoCw721, tokenId, osmoAddr, undefined); + // assert token is minted + tokenOwner = await ownerOf(osmoClient, osmoCw721, tokenId); + t.is(osmoAddr, tokenOwner.owner); + + ibcMsg = { + receiver: wasmAddr, + channel_id: otherChannel.channel.dest.channelId, + timeout: { + block: { + revision: 1, + height: 90000, + }, + }, + }; + + t.log( + `transfering to wasm chain via ${otherChannel.channel.dest.channelId}` + ); + + transferResponse = await sendNft( + osmoClient, + osmoCw721, + osmoCw721OutgoingProxy, + ibcMsg, + tokenId + ); + t.truthy(transferResponse); + + t.log("relaying packets"); + + info = await otherChannel.link.relayAll(); + + // Verify we got an error + assertAckErrors(info.acksFromA); + + // assert NFT on chain A is returned to owner + tokenOwner = await ownerOf(osmoClient, osmoCw721, tokenId); + t.is(osmoClient.senderAddress, tokenOwner.owner); + t.log(`NFT #${tokenId} returned to owner`); + } +); + test.serial("malicious NFT", async (t) => { await standardSetup(t); const { wasmClient, - osmoClient, - channel, - osmoAddr, wasmAddr, wasmIcs721, + osmoClient, + osmoAddr, osmoIcs721, + osmoCw721OutgoingProxy, + channel, } = t.context; const tokenId = "1"; @@ -227,7 +435,7 @@ test.serial("malicious NFT", async (t) => { }, }; - t.log("transfering to osmo chain"); + t.log("transferring to osmo chain"); let transferResponse = await sendNft( wasmClient, @@ -244,6 +452,8 @@ test.serial("malicious NFT", async (t) => { assertAckSuccess(info.acksFromB); + t.log("transferring back to wasm chain"); + const osmoClassId = `${t.context.channel.channel.dest.portId}/${t.context.channel.channel.dest.channelId}/${cw721}`; const osmoCw721 = await osmoClient.sign.queryContractSmart(osmoIcs721, { nft_contract: { class_id: osmoClassId }, @@ -263,7 +473,7 @@ test.serial("malicious NFT", async (t) => { transferResponse = await sendNft( osmoClient, osmoCw721, - osmoIcs721, + osmoCw721OutgoingProxy, ibcMsg, tokenId ); @@ -274,7 +484,7 @@ test.serial("malicious NFT", async (t) => { const pending = await channel.link.getPendingPackets("B"); t.is(pending.length, 1); - // Despite the transfer panicing, a fail ack should be returned. + // Despite the transfer panicking, a fail ack should be returned. info = await channel.link.relayAll(); assertAckErrors(info.acksFromA); }); diff --git a/ts-relayer-tests/src/utils.ts b/ts-relayer-tests/src/utils.ts index e3551cbf..d965be95 100644 --- a/ts-relayer-tests/src/utils.ts +++ b/ts-relayer-tests/src/utils.ts @@ -26,6 +26,13 @@ const { const osmosis = { ...oldOsmo, minFee: "0.025uosmo" }; +export function bigIntReplacer(_key: string, value: any) { + if (typeof value === "bigint") { + return value.toString(); + } + return value; +} + export const MNEMONIC = "harsh adult scrub stadium solution impulse company agree tomorrow poem dirt innocent coyote slight nice digital scissors cool pact person item moon double wagon"; @@ -46,7 +53,7 @@ export interface ContractInfo { address: string | undefined; } -export interface ChannelInfo { +export interface ChannelAndLinkInfo { channel: ChannelPair; link: Link; } @@ -118,7 +125,7 @@ export async function createIbcConnectionAndChannel( osmoContractAddress: string, ordering: Order, version: string -): Promise { +): Promise { const { ibcPortId: wasmContractIbcPortId } = await wasmClient.sign.getContract(wasmContractAddress); assert(wasmContractIbcPortId); @@ -126,7 +133,7 @@ export async function createIbcConnectionAndChannel( await osmoClient.sign.getContract(osmoContractAddress); assert(osmoContractIbcPortId); // create a connection and channel - const [src, dest] = await setup(wasmd, osmosis); + const [srcIbcClient, destIbcClient] = await setup(wasmd, osmosis); const logger: Logger = { debug(message: string, meta?: Record): Logger { const logMsg = meta ? message + ": " + JSON.stringify(meta) : message; @@ -158,7 +165,11 @@ export async function createIbcConnectionAndChannel( return this; }, }; - const link = await Link.createWithNewConnections(src, dest, logger); + const link = await Link.createWithNewConnections( + srcIbcClient, + destIbcClient, + logger + ); const channel = await link.createChannel( "A", wasmContractIbcPortId,