diff --git a/Cargo.lock b/Cargo.lock index e745da31..8caaec5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,7 +230,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -242,7 +242,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -253,7 +253,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -508,7 +508,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.89", + "syn 2.0.90", "which", ] @@ -781,17 +781,19 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chia" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074bbad06d32754e00ea5f10ac31314f18cad9254ca52ca413475a1ad4f55d75" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-client", "chia-consensus", "chia-protocol", "chia-puzzles", + "chia-secp", "chia-sha2", "chia-ssl", - "chia-traits 0.15.0", + "chia-traits 0.17.0", "clvm-traits", "clvm-utils", "clvmr", @@ -815,12 +817,13 @@ dependencies = [ [[package]] name = "chia-bls" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49bdd93d625cc003092aadadeb0bf06b2f9b49a991bd9ad4a354a5a0fe9e4dfc" dependencies = [ "blst", "chia-sha2", - "chia-traits 0.15.0", + "chia-traits 0.17.0", "hex", "hkdf", "linked-hash-map", @@ -830,29 +833,31 @@ dependencies = [ [[package]] name = "chia-client" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e76ded1f46fa4c6493791a63d385dc7889a17086151fef5ad11f649f3c686174" dependencies = [ "chia-protocol", - "chia-traits 0.15.0", + "chia-traits 0.17.0", "futures-util", "thiserror 1.0.69", "tokio", - "tokio-tungstenite", - "tungstenite", + "tokio-tungstenite 0.24.0", + "tungstenite 0.24.0", ] [[package]] name = "chia-consensus" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879cf6ec26b64a90af0bcae3546b73b18fc16236fbcb236b1afca38b51c7cf2c" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-protocol", "chia-puzzles", "chia-sha2", - "chia-traits 0.15.0", - "chia_streamable_macro 0.15.0", + "chia-traits 0.17.0", + "chia_streamable_macro 0.17.0", "clvm-traits", "clvm-utils", "clvmr", @@ -863,13 +868,14 @@ dependencies = [ [[package]] name = "chia-protocol" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b25bfb8bb364959246aafa74f29e0642feeed9d439bf1bfa85fcac24eab02c9" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-sha2", - "chia-traits 0.15.0", - "chia_streamable_macro 0.15.0", + "chia-traits 0.17.0", + "chia_streamable_macro 0.17.0", "clvm-traits", "clvm-utils", "clvmr", @@ -878,10 +884,11 @@ dependencies = [ [[package]] name = "chia-puzzles" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ff9f6dcc5a587993a23b52307bc9b36e13778f4aba090d50c7c15a520ba148f" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-protocol", "chia-sha2", "clvm-traits", @@ -893,104 +900,86 @@ dependencies = [ [[package]] name = "chia-sdk-client" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ "aws-lc-rs", "chia-protocol", "chia-sdk-types", "chia-ssl", - "chia-traits 0.15.0", + "chia-traits 0.17.0", "futures-util", "once_cell", "rustls 0.22.4", "rustls-pemfile", "thiserror 1.0.69", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.21.0", "tracing", - "tungstenite", + "tungstenite 0.21.0", ] [[package]] name = "chia-sdk-derive" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ "convert_case 0.6.0", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "chia-sdk-driver" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ + "bech32", "bigdecimal", - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-protocol", "chia-puzzles", "chia-sdk-types", + "chia-secp", + "chia-traits 0.17.0", "clvm-traits", "clvm-utils", "clvmr", + "flate2", "hex", "hex-literal", - "num-bigint", - "thiserror 1.0.69", -] - -[[package]] -name = "chia-sdk-offers" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" -dependencies = [ - "bech32", - "chia-bls 0.16.0", - "chia-protocol", - "chia-puzzles", - "chia-sdk-driver", - "chia-sdk-types", - "chia-traits 0.15.0", - "clvm-traits", - "clvm-utils", - "clvmr", - "flate2", "indexmap 2.6.0", + "num-bigint", "once_cell", "thiserror 1.0.69", ] [[package]] name = "chia-sdk-signer" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-consensus", "chia-protocol", "chia-sdk-types", + "chia-secp", "clvm-traits", "clvmr", + "k256", "thiserror 1.0.69", ] [[package]] name = "chia-sdk-test" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ "anyhow", "bip39", - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-consensus", "chia-protocol", "chia-puzzles", "chia-sdk-client", "chia-sdk-signer", "chia-sdk-types", - "chia-traits 0.15.0", + "chia-traits 0.17.0", "clvm-traits", "clvm-utils", "clvmr", @@ -1004,20 +993,22 @@ dependencies = [ "rand_chacha 0.3.1", "thiserror 1.0.69", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.21.0", "tracing", ] [[package]] name = "chia-sdk-types" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", "chia-consensus", "chia-protocol", + "chia-puzzles", "chia-sdk-derive", + "chia-secp", "clvm-traits", + "clvm-utils", "clvmr", "hex-literal", "once_cell", @@ -1025,8 +1016,7 @@ dependencies = [ [[package]] name = "chia-sdk-utils" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ "bech32", "chia-protocol", @@ -1037,18 +1027,32 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "chia-secp" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac31ae4205b92add186fd27ee81158c7d6ff5f069c8fe3365b2d8ed686010ce9" +dependencies = [ + "chia-sha2", + "hex", + "k256", + "p256", +] + [[package]] name = "chia-sha2" -version = "0.15.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf81d4042d28fabed0f0cbf06748c81b14a148548976717fb3a7710812f09c6f" dependencies = [ "sha2", ] [[package]] name = "chia-ssl" -version = "0.11.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13cceb06dae32d8c76354c85245b9376558d09ee3412d93be164ba77208b13" dependencies = [ "lazy_static", "rand 0.8.5", @@ -1071,22 +1075,21 @@ dependencies = [ [[package]] name = "chia-traits" -version = "0.15.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a90e39b3e52e458f2ee4365eefe2cb352174b675ca4ba586c3d9cff3ac41a72" dependencies = [ "chia-sha2", - "chia_streamable_macro 0.15.0", + "chia_streamable_macro 0.17.0", "thiserror 1.0.69", ] [[package]] name = "chia-wallet-sdk" -version = "0.19.1" -source = "git+https://github.com/xch-dev/chia-wallet-sdk?rev=1a2d2320050263f7f36cbf33a1424e6185d906f5#1a2d2320050263f7f36cbf33a1424e6185d906f5" +version = "0.20.0" dependencies = [ "chia-sdk-client", "chia-sdk-driver", - "chia-sdk-offers", "chia-sdk-signer", "chia-sdk-test", "chia-sdk-types", @@ -1102,18 +1105,19 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "chia_streamable_macro" -version = "0.15.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5e7ae41c5523feadb84ecda4cb05ec29954aad964f0789cb8c6cc774ea72e5" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1183,7 +1187,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1203,20 +1207,23 @@ dependencies = [ [[package]] name = "clvm-derive" -version = "0.13.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5e060b89a2281ab21c7d8e0866b55c8bd9c1dd0b0b115fd9841561ec7842b4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] name = "clvm-traits" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "792adc7f36ee2d544ffde86322a9b4460faa1813f6933b7a674c7521621d33f4" dependencies = [ - "chia-bls 0.16.0", + "chia-bls 0.17.0", + "chia-secp", "clvm-derive", "clvmr", "num-bigint", @@ -1225,8 +1232,9 @@ dependencies = [ [[package]] name = "clvm-utils" -version = "0.16.0" -source = "git+https://github.com/Chia-Network/chia_rs?rev=cb4f521fe32675a0238453a7c850083405f2952a#cb4f521fe32675a0238453a7c850083405f2952a" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f977c5af481a341386002b9dd406cbfb5c4f1c6c2ff3657aa03dfbdc06911a3" dependencies = [ "chia-sha2", "clvm-traits", @@ -1544,7 +1552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1554,7 +1562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1587,7 +1595,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1598,7 +1606,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1652,7 +1660,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1702,7 +1710,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -1725,7 +1733,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2004,7 +2012,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2103,7 +2111,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2380,7 +2388,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2470,7 +2478,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -2857,7 +2865,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -3578,7 +3586,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4100,7 +4108,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4147,7 +4155,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4255,7 +4263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -4661,9 +4669,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" dependencies = [ "const-oid", "digest", @@ -4991,7 +4999,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5071,7 +5079,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5082,7 +5090,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5115,7 +5123,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5166,7 +5174,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5387,7 +5395,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5502,7 +5510,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5525,7 +5533,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.89", + "syn 2.0.90", "tempfile", "tokio", "url", @@ -5713,9 +5721,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.89" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -5745,7 +5753,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5817,7 +5825,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -5917,7 +5925,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "syn 2.0.89", + "syn 2.0.90", "tauri-utils", "thiserror 2.0.3", "time", @@ -5935,7 +5943,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "tauri-codegen", "tauri-utils", ] @@ -6091,7 +6099,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6184,7 +6192,7 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6219,7 +6227,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6230,7 +6238,7 @@ checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6321,9 +6329,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -6345,7 +6353,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6393,10 +6401,22 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", - "tungstenite", + "tungstenite 0.21.0", "webpki-roots", ] +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.24.0", +] + [[package]] name = "tokio-util" version = "0.7.12" @@ -6556,7 +6576,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -6646,6 +6666,24 @@ dependencies = [ "utf-8", ] +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + [[package]] name = "typeid" version = "1.0.2" @@ -6921,7 +6959,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -6955,7 +6993,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7074,7 +7112,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7201,7 +7239,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7212,7 +7250,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7636,7 +7674,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -7658,7 +7696,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7678,7 +7716,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", "synstructure", ] @@ -7699,7 +7737,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] [[package]] @@ -7721,5 +7759,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.89", + "syn 2.0.90", ] diff --git a/Cargo.toml b/Cargo.toml index b8607b07..04b13699 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,9 +73,9 @@ specta-typescript = "0.0.7" tauri-specta = "2.0.0-rc.20" # Chia -chia = { git = "https://github.com/Chia-Network/chia_rs", rev = "cb4f521fe32675a0238453a7c850083405f2952a", version = "0.16.0" } +chia = "0.17.0" clvmr = "0.10.0" -chia-wallet-sdk = { features = ["rustls"], git = "https://github.com/xch-dev/chia-wallet-sdk", rev = "1a2d2320050263f7f36cbf33a1424e6185d906f5" } +chia-wallet-sdk = { features = ["rustls", "offers"], path = "../wallet-sdk" } bip39 = "2.0.0" bech32 = "0.9.1" diff --git a/crates/sage-api/src/requests.rs b/crates/sage-api/src/requests.rs index 99ac74a5..cd120cd2 100644 --- a/crates/sage-api/src/requests.rs +++ b/crates/sage-api/src/requests.rs @@ -2,6 +2,7 @@ mod actions; mod data; mod keys; mod offers; +mod options; mod settings; mod transactions; @@ -9,6 +10,7 @@ pub use actions::*; pub use data::*; pub use keys::*; pub use offers::*; +pub use options::*; pub use settings::*; pub use transactions::*; diff --git a/crates/sage-api/src/requests/options.rs b/crates/sage-api/src/requests/options.rs new file mode 100644 index 00000000..79930b3a --- /dev/null +++ b/crates/sage-api/src/requests/options.rs @@ -0,0 +1,23 @@ +use serde::{Deserialize, Serialize}; +use specta::Type; + +use crate::{Amount, CoinSpendJson, TransactionSummary}; + +use super::Assets; + +#[derive(Debug, Clone, Serialize, Deserialize, Type)] +pub struct MintOption { + pub requested_assets: Assets, + pub offered_assets: Assets, + pub fee: Amount, + pub expires_at_second: u64, + pub did_id: String, + #[serde(default)] + pub auto_submit: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Type)] +pub struct MintOptionResponse { + pub summary: TransactionSummary, + pub coin_spends: Vec, +} diff --git a/crates/sage-wallet/src/child_kind.rs b/crates/sage-wallet/src/child_kind.rs index 3dbe4e82..c64b36b1 100644 --- a/crates/sage-wallet/src/child_kind.rs +++ b/crates/sage-wallet/src/child_kind.rs @@ -3,7 +3,9 @@ use chia::{ protocol::{Bytes32, Coin, Program}, puzzles::{nft::NftMetadata, singleton::SINGLETON_LAUNCHER_PUZZLE_HASH, LineageProof, Proof}, }; -use chia_wallet_sdk::{run_puzzle, Cat, Condition, Did, DidInfo, HashedPtr, Nft, NftInfo, Puzzle}; +use chia_wallet_sdk::{ + run_puzzle, Cat, Condition, Did, DidInfo, HashedPtr, Memos, Nft, NftInfo, Puzzle, +}; use clvmr::{Allocator, NodePtr}; use tracing::{debug_span, warn}; @@ -77,23 +79,22 @@ impl ChildKind { return Ok(Self::Launcher); } - let Some(mut create_coin) = conditions + let Some(create_coin) = conditions .into_iter() .filter_map(Condition::into_create_coin) - .find(|cond| { - cond.puzzle_hash == coin.puzzle_hash - && cond.amount == coin.amount - && !cond.memos.is_empty() - && cond.memos[0].len() == 32 - }) + .find(|cond| cond.puzzle_hash == coin.puzzle_hash && cond.amount == coin.amount) else { return Ok(Self::Unknown { hint: None }); }; - let hint = Bytes32::try_from(create_coin.memos.remove(0).into_inner()) - .expect("the hint is always 32 bytes, as checked above"); + let hint = if let Some(memos) = create_coin.memos { + let memos = Memos::<(Bytes32, NodePtr)>::from_clvm(allocator, memos.value).ok(); + memos.map(|memos| memos.value.0) + } else { + None + }; - let unknown = Self::Unknown { hint: Some(hint) }; + let unknown = Self::Unknown { hint }; match Cat::parse_children(allocator, parent_coin, parent_puzzle, parent_solution) { // If there was an error parsing the CAT, we can exit early. diff --git a/crates/sage-wallet/src/wallet.rs b/crates/sage-wallet/src/wallet.rs index 8ee9d589..eb4aa69c 100644 --- a/crates/sage-wallet/src/wallet.rs +++ b/crates/sage-wallet/src/wallet.rs @@ -10,6 +10,7 @@ mod did_assign; mod dids; mod nfts; mod offer; +mod option; mod p2_coin_management; mod p2_send; mod p2_spends; @@ -17,6 +18,7 @@ mod signing; pub use nfts::WalletNftMint; pub use offer::*; +pub use option::*; #[derive(Debug)] pub struct Wallet { diff --git a/crates/sage-wallet/src/wallet/cat_coin_management.rs b/crates/sage-wallet/src/wallet/cat_coin_management.rs index 88ec6f08..944c1d0a 100644 --- a/crates/sage-wallet/src/wallet/cat_coin_management.rs +++ b/crates/sage-wallet/src/wallet/cat_coin_management.rs @@ -31,7 +31,7 @@ impl Wallet { } if fee_change > 0 { - fee_conditions = fee_conditions.create_coin(p2_puzzle_hash, fee_change, Vec::new()); + fee_conditions = fee_conditions.create_coin(p2_puzzle_hash, fee_change, None); } let mut ctx = SpendContext::new(); @@ -39,24 +39,27 @@ impl Wallet { self.spend_p2_coins(&mut ctx, fee_coins, fee_conditions) .await?; - self.spend_cat_coins( - &mut ctx, - cats.into_iter().enumerate().map(|(i, cat)| { - if i == 0 { - ( - cat, - Conditions::new().create_coin( - p2_puzzle_hash, - cat_total.try_into().expect("output amount overflow"), - vec![p2_puzzle_hash.into()], - ), - ) - } else { - (cat, Conditions::new()) - } - }), - ) - .await?; + let mut cat_spends = Vec::new(); + + let hint = ctx.hint(p2_puzzle_hash)?; + + for (i, cat) in cats.into_iter().enumerate() { + cat_spends.push(if i == 0 { + ( + cat, + Conditions::new().create_coin( + p2_puzzle_hash, + cat_total.try_into().expect("output amount overflow"), + Some(hint), + ), + ) + } else { + (cat, Conditions::new()) + }); + } + + self.spend_cat_coins(&mut ctx, cat_spends.into_iter()) + .await?; Ok(ctx.take()) } @@ -104,39 +107,40 @@ impl Wallet { } if fee_change > 0 { - fee_conditions = fee_conditions.create_coin(derivations[0], fee_change, Vec::new()); + fee_conditions = fee_conditions.create_coin(derivations[0], fee_change, None); } self.spend_p2_coins(&mut ctx, fee_coins, fee_conditions) .await?; - self.spend_cat_coins( - &mut ctx, - cats.into_iter().map(|cat| { - let mut conditions = Conditions::new(); + let mut cat_spends = Vec::new(); + + for cat in cats { + let mut conditions = Conditions::new(); - for &derivation in &derivations { - if remaining_count == 0 { - break; - } + for &derivation in &derivations { + if remaining_count == 0 { + break; + } - let amount: u64 = (max_individual_amount as u128) - .min(remaining_amount) - .try_into() - .expect("output amount overflow"); + let amount: u64 = (max_individual_amount as u128) + .min(remaining_amount) + .try_into() + .expect("output amount overflow"); - remaining_amount -= amount as u128; + remaining_amount -= amount as u128; - conditions = - conditions.create_coin(derivation, amount, vec![derivation.into()]); + let hint = ctx.hint(derivation)?; + conditions = conditions.create_coin(derivation, amount, Some(hint)); - remaining_count -= 1; - } + remaining_count -= 1; + } - (cat, conditions) - }), - ) - .await?; + cat_spends.push((cat, conditions)); + } + + self.spend_cat_coins(&mut ctx, cat_spends.into_iter()) + .await?; Ok(ctx.take()) } diff --git a/crates/sage-wallet/src/wallet/cats.rs b/crates/sage-wallet/src/wallet/cats.rs index 8009ee05..42dd9fff 100644 --- a/crates/sage-wallet/src/wallet/cats.rs +++ b/crates/sage-wallet/src/wallet/cats.rs @@ -31,11 +31,9 @@ impl Wallet { let mut ctx = SpendContext::new(); - let eve_conditions = Conditions::new().create_coin( - p2_puzzle_hash, - amount, - vec![p2_puzzle_hash.to_vec().into()], - ); + let hint = ctx.hint(p2_puzzle_hash)?; + + let eve_conditions = Conditions::new().create_coin(p2_puzzle_hash, amount, Some(hint)); let (mut conditions, eve) = match multi_issuance_key { Some(pk) => { @@ -49,7 +47,7 @@ impl Wallet { } if change > 0 { - conditions = conditions.create_coin(p2_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(p2_puzzle_hash, change, None); } self.spend_p2_coins(&mut ctx, coins, conditions).await?; @@ -95,7 +93,7 @@ impl Wallet { conditions = conditions.reserve_fee(fee); if fee_change > 0 { - conditions = conditions.create_coin(change_puzzle_hash, fee_change, Vec::new()); + conditions = conditions.create_coin(change_puzzle_hash, fee_change, None); } } @@ -106,6 +104,9 @@ impl Wallet { .await?; } + let hint = ctx.hint(puzzle_hash)?; + let change_hint = ctx.hint(change_puzzle_hash)?; + self.spend_cat_coins( &mut ctx, cats.into_iter().enumerate().map(|(i, cat)| { @@ -113,18 +114,12 @@ impl Wallet { return (cat, Conditions::new()); } - let mut conditions = mem::take(&mut conditions).create_coin( - puzzle_hash, - amount, - vec![puzzle_hash.into()], - ); + let mut conditions = + mem::take(&mut conditions).create_coin(puzzle_hash, amount, Some(hint)); if cat_change > 0 { - conditions = conditions.create_coin( - change_puzzle_hash, - cat_change, - vec![change_puzzle_hash.into()], - ); + conditions = + conditions.create_coin(change_puzzle_hash, cat_change, Some(change_hint)); } (cat, conditions) diff --git a/crates/sage-wallet/src/wallet/did_assign.rs b/crates/sage-wallet/src/wallet/did_assign.rs index a32f4910..f9534e3c 100644 --- a/crates/sage-wallet/src/wallet/did_assign.rs +++ b/crates/sage-wallet/src/wallet/did_assign.rs @@ -113,7 +113,7 @@ impl Wallet { .reserve_fee(fee); if change > 0 { - conditions = conditions.create_coin(change_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(change_puzzle_hash, change, None); } if let Some(did_coin_id) = did_coin_id { diff --git a/crates/sage-wallet/src/wallet/dids.rs b/crates/sage-wallet/src/wallet/dids.rs index af0284a3..6baf03fd 100644 --- a/crates/sage-wallet/src/wallet/dids.rs +++ b/crates/sage-wallet/src/wallet/dids.rs @@ -34,7 +34,7 @@ impl Wallet { } if change > 0 { - conditions = conditions.create_coin(p2_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(p2_puzzle_hash, change, None); } self.spend_p2_coins(&mut ctx, coins, conditions).await?; @@ -112,7 +112,7 @@ impl Wallet { .reserve_fee(fee); if change > 0 { - conditions = conditions.create_coin(p2_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(p2_puzzle_hash, change, None); } self.spend_p2_coins(&mut ctx, coins, conditions).await?; diff --git a/crates/sage-wallet/src/wallet/nfts.rs b/crates/sage-wallet/src/wallet/nfts.rs index 84812f5a..805c63a8 100644 --- a/crates/sage-wallet/src/wallet/nfts.rs +++ b/crates/sage-wallet/src/wallet/nfts.rs @@ -79,7 +79,7 @@ impl Wallet { } if change > 0 { - conditions = conditions.create_coin(p2_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(p2_puzzle_hash, change, None); } self.spend_p2_coins(&mut ctx, coins, conditions).await?; @@ -159,7 +159,7 @@ impl Wallet { .reserve_fee(fee); if change > 0 { - conditions = conditions.create_coin(change_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(change_puzzle_hash, change, None); } self.spend_p2_coins(&mut ctx, coins, conditions).await?; @@ -216,7 +216,7 @@ impl Wallet { .reserve_fee(fee); if change > 0 { - conditions = conditions.create_coin(p2_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(p2_puzzle_hash, change, None); } self.spend_p2_coins(&mut ctx, coins, conditions).await?; diff --git a/crates/sage-wallet/src/wallet/offer/lock_assets.rs b/crates/sage-wallet/src/wallet/offer/lock_assets.rs index 5b63d6b2..2ebed2a8 100644 --- a/crates/sage-wallet/src/wallet/offer/lock_assets.rs +++ b/crates/sage-wallet/src/wallet/offer/lock_assets.rs @@ -3,8 +3,7 @@ use std::{collections::HashMap, mem}; use chia::{ protocol::{Bytes32, Coin}, puzzles::offer::{ - Memos, NotarizedPayment, Payment, SettlementPaymentsSolution, - SETTLEMENT_PAYMENTS_PUZZLE_HASH, + NotarizedPayment, Payment, SettlementPaymentsSolution, SETTLEMENT_PAYMENTS_PUZZLE_HASH, }, }; use chia_wallet_sdk::{ @@ -79,7 +78,7 @@ impl Wallet { conditions = conditions.create_coin( SETTLEMENT_PAYMENTS_PUZZLE_HASH.into(), amounts.xch, - Vec::new(), + None, ); locked.xch.push(Coin::new( @@ -96,7 +95,7 @@ impl Wallet { conditions = conditions.create_coin( SETTLEMENT_PAYMENTS_PUZZLE_HASH.into(), royalty_amount, - Vec::new(), + None, ); let royalty_coin = Coin::new( @@ -117,7 +116,7 @@ impl Wallet { payments: vec![Payment::with_memos( royalty.p2_puzzle_hash, royalty.amount, - Memos(vec![royalty.p2_puzzle_hash.into()]), + vec![royalty.p2_puzzle_hash.into()], )], }) .collect(), @@ -131,7 +130,7 @@ impl Wallet { let change = total_amount - amounts.xch - fee - royalties.xch_amount(); if change > 0 { - conditions = conditions.create_coin(change_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(change_puzzle_hash, change, None); } if fee > 0 { @@ -151,13 +150,15 @@ impl Wallet { let total_amount = cat_coins.iter().map(|cat| cat.coin.amount).sum::(); let change = total_amount - amount - royalties.cat_amount(asset_id); + let settlement_hint = ctx.hint(SETTLEMENT_PAYMENTS_PUZZLE_HASH.into())?; + let mut conditions = primary_conditions .remove(&primary_cat.coin.coin_id()) .unwrap_or_default() .create_coin( SETTLEMENT_PAYMENTS_PUZZLE_HASH.into(), amount, - vec![Bytes32::from(SETTLEMENT_PAYMENTS_PUZZLE_HASH).into()], + Some(settlement_hint), ); locked @@ -167,11 +168,9 @@ impl Wallet { .push(primary_cat.wrapped_child(SETTLEMENT_PAYMENTS_PUZZLE_HASH.into(), amount)); if change > 0 { - conditions = conditions.create_coin( - change_puzzle_hash, - change, - vec![change_puzzle_hash.into()], - ); + let change_hint = ctx.hint(change_puzzle_hash)?; + + conditions = conditions.create_coin(change_puzzle_hash, change, Some(change_hint)); } // Handle royalties. @@ -181,7 +180,7 @@ impl Wallet { conditions = conditions.create_coin( SETTLEMENT_PAYMENTS_PUZZLE_HASH.into(), royalty_amount, - vec![Bytes32::from(SETTLEMENT_PAYMENTS_PUZZLE_HASH).into()], + Some(settlement_hint), ); let royalty_cat = primary_cat @@ -197,7 +196,7 @@ impl Wallet { payments: vec![Payment::with_memos( royalty.p2_puzzle_hash, royalty.amount, - Memos(vec![royalty.p2_puzzle_hash.into()]), + vec![royalty.p2_puzzle_hash.into()], )], }) .collect(), diff --git a/crates/sage-wallet/src/wallet/offer/make_offer.rs b/crates/sage-wallet/src/wallet/offer/make_offer.rs index 6e9b78c8..4ee337cf 100644 --- a/crates/sage-wallet/src/wallet/offer/make_offer.rs +++ b/crates/sage-wallet/src/wallet/offer/make_offer.rs @@ -1,9 +1,8 @@ use chia::{ - clvm_utils::CurriedProgram, protocol::{Bytes32, CoinSpend, Program}, puzzles::{ cat::CatArgs, - offer::{Memos, Payment, SETTLEMENT_PAYMENTS_PUZZLE_HASH}, + offer::{Payment, SETTLEMENT_PAYMENTS_PUZZLE_HASH}, }, }; use chia_wallet_sdk::{Conditions, Layer, NftInfo, OfferBuilder, Partial, SpendContext}; @@ -87,7 +86,6 @@ impl Wallet { let mut builder = OfferBuilder::new(maker_coins.nonce()); let mut ctx = SpendContext::new(); let settlement = ctx.settlement_payments_puzzle()?; - let cat = ctx.cat_puzzle()?; // Add requested XCH payments. if taker.xch > 0 { @@ -97,23 +95,21 @@ impl Wallet { vec![Payment::with_memos( p2_puzzle_hash, taker.xch, - Memos(vec![p2_puzzle_hash.into()]), + vec![p2_puzzle_hash.into()], )], )?; } // Add requested CAT payments. for (&asset_id, &amount) in &taker.cats { + let cat_puzzle = ctx.curry(CatArgs::new(asset_id, settlement))?; builder = builder.request( &mut ctx, - &CurriedProgram { - program: cat, - args: CatArgs::new(asset_id, settlement), - }, + &cat_puzzle, vec![Payment::with_memos( p2_puzzle_hash, amount, - Memos(vec![p2_puzzle_hash.into()]), + vec![p2_puzzle_hash.into()], )], )?; } @@ -138,7 +134,7 @@ impl Wallet { vec![Payment::with_memos( p2_puzzle_hash, 1, - Memos(vec![p2_puzzle_hash.into()]), + vec![p2_puzzle_hash.into()], )], )?; } diff --git a/crates/sage-wallet/src/wallet/offer/royalties.rs b/crates/sage-wallet/src/wallet/offer/royalties.rs index 02c92cce..b1810724 100644 --- a/crates/sage-wallet/src/wallet/offer/royalties.rs +++ b/crates/sage-wallet/src/wallet/offer/royalties.rs @@ -2,7 +2,7 @@ use chia::{ protocol::Bytes32, puzzles::{ cat::CatArgs, - offer::{Memos, NotarizedPayment, Payment, SETTLEMENT_PAYMENTS_PUZZLE_HASH}, + offer::{NotarizedPayment, Payment, SETTLEMENT_PAYMENTS_PUZZLE_HASH}, }, }; use chia_wallet_sdk::{ @@ -82,7 +82,7 @@ impl RoyaltyPayment { payments: vec![Payment::with_memos( self.p2_puzzle_hash, self.amount, - Memos(vec![self.p2_puzzle_hash.into()]), + vec![self.p2_puzzle_hash.into()], )], } } diff --git a/crates/sage-wallet/src/wallet/offer/unlock_assets.rs b/crates/sage-wallet/src/wallet/offer/unlock_assets.rs index 5b4f7bed..ec5817a8 100644 --- a/crates/sage-wallet/src/wallet/offer/unlock_assets.rs +++ b/crates/sage-wallet/src/wallet/offer/unlock_assets.rs @@ -2,7 +2,7 @@ use std::mem; use chia::{ protocol::Bytes32, - puzzles::offer::{Memos, NotarizedPayment, Payment, SettlementPaymentsSolution}, + puzzles::offer::{NotarizedPayment, Payment, SettlementPaymentsSolution}, }; use chia_wallet_sdk::{ payment_assertion, AssertPuzzleAnnouncement, Cat, CatSpend, Layer, SettlementLayer, @@ -27,7 +27,7 @@ pub fn unlock_assets( payments: vec![Payment::with_memos( p2_puzzle_hash, coin.amount, - Memos(vec![p2_puzzle_hash.into()]), + vec![p2_puzzle_hash.into()], )], }; @@ -51,7 +51,7 @@ pub fn unlock_assets( payments: vec![Payment::with_memos( p2_puzzle_hash, cat.coin.amount, - Memos(vec![p2_puzzle_hash.into()]), + vec![p2_puzzle_hash.into()], )], }; @@ -74,7 +74,7 @@ pub fn unlock_assets( payments: vec![Payment::with_memos( p2_puzzle_hash, nft.coin.amount, - Memos(vec![p2_puzzle_hash.into()]), + vec![p2_puzzle_hash.into()], )], }; diff --git a/crates/sage-wallet/src/wallet/option.rs b/crates/sage-wallet/src/wallet/option.rs new file mode 100644 index 00000000..b0a45d75 --- /dev/null +++ b/crates/sage-wallet/src/wallet/option.rs @@ -0,0 +1,3 @@ +mod mint_option; + +pub use mint_option::*; diff --git a/crates/sage-wallet/src/wallet/option/mint_option.rs b/crates/sage-wallet/src/wallet/option/mint_option.rs new file mode 100644 index 00000000..3c5c9337 --- /dev/null +++ b/crates/sage-wallet/src/wallet/option/mint_option.rs @@ -0,0 +1,231 @@ +use std::{collections::HashMap, mem}; + +use chia::{ + protocol::{Bytes32, CoinSpend}, + puzzles::nft::{NftMetadata, NFT_METADATA_UPDATER_PUZZLE_HASH}, +}; +use chia_wallet_sdk::{ + Conditions, DidOwner, HashedPtr, Launcher, Mod, NftMint, OptionContract, SpendContext, + StandardLayer, +}; +use indexmap::IndexMap; + +use crate::{ + calculate_royalties, MakerSide, NftRoyaltyInfo, OfferAmounts, TakerSide, Wallet, WalletError, +}; + +#[derive(Debug, Clone)] +pub struct Option { + pub did_id: Bytes32, + pub maker: MakerSide, + pub taker: TakerSide, + pub nft_metadata: NftMetadata, + pub expiration_seconds: u64, +} + +impl Wallet { + pub async fn mint_option( + &self, + Option { + did_id, + maker, + taker, + nft_metadata, + expiration_seconds, + }: Option, + hardened: bool, + reuse: bool, + ) -> Result, WalletError> { + let ctx = &mut SpendContext::new(); + + let Some(did) = self.db.spendable_did(did_id).await? else { + return Err(WalletError::MissingDid(did_id)); + }; + + let p2_puzzle_hash = self.p2_puzzle_hash(hardened, reuse).await?; + + let did_metadata_ptr = ctx.alloc(&did.info.metadata)?; + let did = did.with_metadata(HashedPtr::from_ptr(&ctx.allocator, did_metadata_ptr)); + + let synthetic_key = self.db.synthetic_key(did.info.p2_puzzle_hash).await?; + let did_p2 = StandardLayer::new(synthetic_key); + + let nft_mint = NftMint { + metadata: nft_metadata, + metadata_updater_puzzle_hash: NFT_METADATA_UPDATER_PUZZLE_HASH.into(), + royalty_puzzle_hash: p2_puzzle_hash, + royalty_ten_thousandths: 0, + p2_puzzle_hash, + owner: Some(DidOwner::from_did_info(&did.info)), + }; + + let (mint_nft, nft) = Launcher::new(did.coin.coin_id(), 0) + .with_singleton_amount(1) + .mint_nft(ctx, nft_mint)?; + let _new_did = did.update(ctx, &did_p2, mint_nft)?; + + // TODO: SPLIT THIS APART, BUT HERE BEGINS THE OFFER CODE + let maker_amounts = OfferAmounts { + xch: maker.xch, + cats: maker.cats.clone(), + }; + + let maker_royalties = calculate_royalties( + &maker_amounts, + &taker + .nfts + .iter() + .map(|(nft_id, requested_nft)| NftRoyaltyInfo { + launcher_id: *nft_id, + royalty_puzzle_hash: requested_nft.royalty_puzzle_hash, + royalty_ten_thousandths: requested_nft.royalty_ten_thousandths, + }) + .collect::>(), + )?; + + let total_amounts = maker_amounts.clone() + + maker_royalties.amounts() + + OfferAmounts { + xch: maker.fee + 1, + cats: IndexMap::new(), + }; + + let coins = self + .fetch_offer_coins(&total_amounts, maker.nfts.clone()) + .await?; + + let option_contract = OptionContract { + nft_info: nft.info, + p2_puzzle_hash, + expiration_seconds, + }; + + let assertions = Conditions::::default(); + + let mut extra_conditions = Conditions::new(); + + let primary_coins = coins.primary_coin_ids(); + + // Calculate conditions for each primary coin. + let mut primary_conditions = HashMap::new(); + + if primary_coins.len() == 1 { + primary_conditions.insert(primary_coins[0], extra_conditions); + } else { + for (i, &coin_id) in primary_coins.iter().enumerate() { + let relation = if i == 0 { + *primary_coins.last().expect("empty primary coins") + } else { + primary_coins[i - 1] + }; + + primary_conditions.insert( + coin_id, + mem::take(&mut extra_conditions).assert_concurrent_spend(relation), + ); + } + } + + // TODO: Keep track of the coins that are locked? + + // Spend the XCH. + if let Some(primary_xch_coin) = coins.xch.first().copied() { + let offered_amount = maker_amounts.xch + maker_royalties.xch_amount(); + + let mut conditions = primary_conditions + .remove(&primary_xch_coin.coin_id()) + .unwrap_or_default(); + + if offered_amount > 0 { + let p2_option_puzzle = option_contract.p2_option_puzzle( + ctx, + offered_amount, + assertions.clone(), + false, + )?; + + conditions = conditions.create_coin( + p2_option_puzzle.curry_tree_hash().into(), + offered_amount, + None, + ); + } + + let total_amount = coins.xch.iter().map(|coin| coin.amount).sum::(); + let change = total_amount - offered_amount - maker.fee; + + if change > 0 { + conditions = conditions.create_coin(p2_puzzle_hash, change, None); + } + + if maker.fee > 0 { + conditions = conditions.reserve_fee(maker.fee); + } + + self.spend_p2_coins(ctx, coins.xch, conditions).await?; + } + + // Spend the CATs. + for (asset_id, cat_coins) in coins.cats { + let Some(primary_cat) = cat_coins.first().copied() else { + continue; + }; + + let offered_amount = maker.cats.get(&asset_id).copied().unwrap_or(0) + + maker_royalties.cat_amount(asset_id); + let total_amount = cat_coins.iter().map(|cat| cat.coin.amount).sum::(); + let change = total_amount - offered_amount; + + let p2_option_puzzle = + option_contract.p2_option_puzzle(ctx, offered_amount, assertions.clone(), true)?; + + let mut conditions = primary_conditions + .remove(&primary_cat.coin.coin_id()) + .unwrap_or_default() + .create_coin( + p2_option_puzzle.curry_tree_hash().into(), + offered_amount, + None, + ); + + if change > 0 { + let change_hint = ctx.hint(p2_puzzle_hash)?; + + conditions = conditions.create_coin(p2_puzzle_hash, change, Some(change_hint)); + } + + self.spend_cat_coins( + ctx, + cat_coins + .into_iter() + .map(|cat| (cat, mem::take(&mut conditions))), + ) + .await?; + } + + // Spend the NFTs. + for nft in coins.nfts.into_values() { + let metadata_ptr = ctx.alloc(&nft.info.metadata)?; + let nft = nft.with_metadata(HashedPtr::from_ptr(&ctx.allocator, metadata_ptr)); + + let synthetic_key = self.db.synthetic_key(nft.info.p2_puzzle_hash).await?; + let p2 = StandardLayer::new(synthetic_key); + + let p2_option_puzzle = + option_contract.p2_option_puzzle(ctx, nft.coin.amount, assertions.clone(), true)?; + + let conditions = primary_conditions + .remove(&nft.coin.coin_id()) + .unwrap_or_default(); + + let _nft = nft.transfer( + ctx, + &p2, + p2_option_puzzle.curry_tree_hash().into(), + conditions, + )?; + } + + Ok(ctx.take()) + } +} diff --git a/crates/sage-wallet/src/wallet/p2_coin_management.rs b/crates/sage-wallet/src/wallet/p2_coin_management.rs index f13c9447..fb25b100 100644 --- a/crates/sage-wallet/src/wallet/p2_coin_management.rs +++ b/crates/sage-wallet/src/wallet/p2_coin_management.rs @@ -35,7 +35,7 @@ impl Wallet { } if change > 0 { - conditions = conditions.create_coin(p2_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(p2_puzzle_hash, change, None); } let mut ctx = SpendContext::new(); @@ -106,7 +106,7 @@ impl Wallet { remaining_amount -= amount as u128; - conditions = conditions.create_coin(derivation, amount, Vec::new()); + conditions = conditions.create_coin(derivation, amount, None); remaining_count -= 1; } @@ -144,17 +144,13 @@ impl Wallet { // If there is excess amount in this coin after the fee is paid, create a new output. if consumed < coin.amount { - Conditions::new().create_coin( - puzzle_hash, - coin.amount - consumed, - Vec::new(), - ) + Conditions::new().create_coin(puzzle_hash, coin.amount - consumed, None) } else { Conditions::new() } } else { // Otherwise, just create a new output coin at the given puzzle hash. - Conditions::new().create_coin(puzzle_hash, coin.amount, Vec::new()) + Conditions::new().create_coin(puzzle_hash, coin.amount, None) }; // Ensure that there is a ring of assertions for all of the coins. diff --git a/crates/sage-wallet/src/wallet/p2_send.rs b/crates/sage-wallet/src/wallet/p2_send.rs index c659f726..8c087b7b 100644 --- a/crates/sage-wallet/src/wallet/p2_send.rs +++ b/crates/sage-wallet/src/wallet/p2_send.rs @@ -1,5 +1,5 @@ use chia::protocol::{Bytes, Bytes32, CoinSpend}; -use chia_wallet_sdk::{Conditions, SpendContext}; +use chia_wallet_sdk::{Conditions, Memos, SpendContext}; use crate::WalletError; @@ -26,18 +26,22 @@ impl Wallet { .try_into() .expect("change amount overflow"); - let mut conditions = Conditions::new().create_coin(puzzle_hash, amount, memos); + let mut ctx = SpendContext::new(); + + let mut conditions = Conditions::new().create_coin( + puzzle_hash, + amount, + Some(Memos::new(ctx.alloc(&memos)?)), + ); if fee > 0 { conditions = conditions.reserve_fee(fee); } if change > 0 { - conditions = conditions.create_coin(change_puzzle_hash, change, Vec::new()); + conditions = conditions.create_coin(change_puzzle_hash, change, None); } - let mut ctx = SpendContext::new(); - self.spend_p2_coins(&mut ctx, coins, conditions).await?; Ok(ctx.take()) diff --git a/crates/sage-wallet/src/wallet/signing.rs b/crates/sage-wallet/src/wallet/signing.rs index f776423d..4ee45976 100644 --- a/crates/sage-wallet/src/wallet/signing.rs +++ b/crates/sage-wallet/src/wallet/signing.rs @@ -69,7 +69,11 @@ impl Wallet { let mut indices = HashMap::new(); for required in &required_signatures { - let pk = required.public_key(); + let RequiredSignature::Bls(required) = required else { + return Err(WalletError::UnknownPublicKey); + }; + + let pk = required.public_key; let Some(index) = self.db.synthetic_key_index(pk).await? else { if partial { continue; @@ -92,8 +96,12 @@ impl Wallet { let mut aggregated_signature = Signature::default(); for required in required_signatures { - let sk = secret_keys[&required.public_key()].clone(); - aggregated_signature += &sign(&sk, required.final_message()); + let RequiredSignature::Bls(required) = required else { + return Err(WalletError::UnknownPublicKey); + }; + + let sk = secret_keys[&required.public_key].clone(); + aggregated_signature += &sign(&sk, required.message()); } Ok(SpendBundle::new(coin_spends, aggregated_signature)) diff --git a/crates/sage/src/endpoints.rs b/crates/sage/src/endpoints.rs index d1dd7f0f..8af9b72f 100644 --- a/crates/sage/src/endpoints.rs +++ b/crates/sage/src/endpoints.rs @@ -2,6 +2,7 @@ mod actions; mod data; mod keys; mod offers; +mod options; mod settings; mod transactions; mod wallet_connect; diff --git a/crates/sage/src/endpoints/options.rs b/crates/sage/src/endpoints/options.rs new file mode 100644 index 00000000..17fe981c --- /dev/null +++ b/crates/sage/src/endpoints/options.rs @@ -0,0 +1,88 @@ +use chia::{bls::Signature, protocol::SpendBundle, puzzles::nft::NftMetadata}; +use chia_wallet_sdk::Offer; +use indexmap::IndexMap; +use sage_api::{CatAmount, MintOption, TransactionResponse}; +use sage_wallet::{fetch_nft_offer_details, MakerSide, Option, TakerSide}; +use tracing::debug; + +use crate::{parse_asset_id, parse_cat_amount, parse_did_id, parse_nft_id, Error, Result, Sage}; + +impl Sage { + pub async fn mint_option(&self, req: MintOption) -> Result { + let wallet = self.wallet()?; + + let offered_xch = self.parse_amount(req.offered_assets.xch)?; + + let mut offered_cats = IndexMap::new(); + + for CatAmount { asset_id, amount } in req.offered_assets.cats { + offered_cats.insert(parse_asset_id(asset_id)?, parse_cat_amount(amount)?); + } + + let mut offered_nfts = Vec::new(); + + for nft_id in req.offered_assets.nfts { + offered_nfts.push(parse_nft_id(nft_id)?); + } + + let requested_xch = self.parse_amount(req.requested_assets.xch)?; + + let mut requested_cats = IndexMap::new(); + + for CatAmount { asset_id, amount } in req.requested_assets.cats { + requested_cats.insert(parse_asset_id(asset_id)?, parse_cat_amount(amount)?); + } + + let mut requested_nfts = IndexMap::new(); + let mut peer = None; + + for nft_id in req.requested_assets.nfts { + if peer.is_none() { + peer = self.peer_state.lock().await.acquire_peer(); + } + + let peer = peer.as_ref().ok_or(Error::NoPeers)?; + + let nft_id = parse_nft_id(nft_id)?; + + let Some(offer_details) = fetch_nft_offer_details(peer, nft_id).await? else { + return Err(Error::CouldNotFetchNft(nft_id)); + }; + + requested_nfts.insert(nft_id, offer_details); + } + + let fee = self.parse_amount(req.fee)?; + let did_id = parse_did_id(req.did_id)?; + + let coin_spends = wallet + .mint_option( + Option { + maker: MakerSide { + xch: offered_xch, + cats: offered_cats, + nfts: offered_nfts, + fee, + }, + taker: TakerSide { + xch: requested_xch, + cats: requested_cats, + nfts: requested_nfts, + }, + expiration_seconds: req.expires_at_second, + nft_metadata: NftMetadata::default(), + did_id, + }, + false, + true, + ) + .await?; + + debug!( + "coin_spends: {:?}", + Offer::from(SpendBundle::new(coin_spends.clone(), Signature::default())).encode()? + ); + + self.transact(coin_spends, req.auto_submit).await + } +} diff --git a/crates/sage/src/endpoints/transactions.rs b/crates/sage/src/endpoints/transactions.rs index 5b059489..61be78bb 100644 --- a/crates/sage/src/endpoints/transactions.rs +++ b/crates/sage/src/endpoints/transactions.rs @@ -319,7 +319,7 @@ impl Sage { Ok(SubmitTransactionResponse {}) } - async fn transact( + pub(crate) async fn transact( &self, coin_spends: Vec, auto_submit: bool, diff --git a/crates/sage/src/endpoints/wallet_connect.rs b/crates/sage/src/endpoints/wallet_connect.rs index f222d54c..5fbcb08f 100644 --- a/crates/sage/src/endpoints/wallet_connect.rs +++ b/crates/sage/src/endpoints/wallet_connect.rs @@ -1,6 +1,6 @@ use chia::{ bls::{master_to_wallet_unhardened, sign}, - clvm_utils::{CurriedProgram, ToTreeHash}, + clvm_utils::ToTreeHash, protocol::{Bytes, Coin, CoinSpend, SpendBundle}, puzzles::{cat::CatArgs, standard::StandardArgs, DeriveSynthetic, Proof}, }; @@ -87,14 +87,8 @@ impl Sage { let synthetic_key = wallet.db.synthetic_key(cat.p2_puzzle_hash).await?; let mut ctx = SpendContext::new(); - let p2_puzzle = CurriedProgram { - program: ctx.standard_puzzle()?, - args: StandardArgs::new(synthetic_key), - }; - let cat_puzzle = CurriedProgram { - program: ctx.cat_puzzle()?, - args: CatArgs::new(cat.asset_id, p2_puzzle), - }; + let p2_puzzle = ctx.curry(StandardArgs::new(synthetic_key))?; + let cat_puzzle = ctx.curry(CatArgs::new(cat.asset_id, p2_puzzle))?; items.push(SpendableCoin { coin: wallet_connect::Coin { @@ -167,10 +161,7 @@ impl Sage { wallet.db.synthetic_key(did.info.p2_puzzle_hash).await?; let mut ctx = SpendContext::new(); - let p2_puzzle = CurriedProgram { - program: ctx.standard_puzzle()?, - args: StandardArgs::new(synthetic_key), - }; + let p2_puzzle = ctx.curry(StandardArgs::new(synthetic_key))?; let did_puzzle = did.info.into_layers(p2_puzzle).construct_puzzle(&mut ctx)?; @@ -252,10 +243,7 @@ impl Sage { wallet.db.synthetic_key(nft.info.p2_puzzle_hash).await?; let mut ctx = SpendContext::new(); - let p2_puzzle = CurriedProgram { - program: ctx.standard_puzzle()?, - args: StandardArgs::new(synthetic_key), - }; + let p2_puzzle = ctx.curry(StandardArgs::new(synthetic_key))?; let nft_puzzle = nft.info.into_layers(p2_puzzle).construct_puzzle(&mut ctx)?; @@ -315,10 +303,7 @@ impl Sage { let synthetic_key = wallet.db.synthetic_key(cs.coin.puzzle_hash).await?; let mut ctx = SpendContext::new(); - let puzzle = CurriedProgram { - program: ctx.standard_puzzle()?, - args: StandardArgs::new(synthetic_key), - }; + let puzzle = ctx.curry(StandardArgs::new(synthetic_key))?; items.push(SpendableCoin { coin: wallet_connect::Coin { diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index e58b9104..c2d6b60c 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -286,6 +286,15 @@ pub async fn delete_offer( Ok(state.lock().await.delete_offer(req).await?) } +#[command] +#[specta] +pub async fn mint_option( + state: State<'_, AppState>, + req: MintOption, +) -> Result { + Ok(state.lock().await.mint_option(req).await?) +} + #[command] #[specta] pub async fn get_sync_status( diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index a277ae38..8a2d50ad 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -65,6 +65,7 @@ pub fn run() { commands::get_offers, commands::get_offer, commands::delete_offer, + commands::mint_option, commands::network_config, commands::set_discover_peers, commands::set_target_peers, diff --git a/src/bindings.ts b/src/bindings.ts index 5ecabfd8..887d8426 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -149,6 +149,9 @@ async getOffer(req: GetOffer) : Promise { async deleteOffer(req: DeleteOffer) : Promise { return await TAURI_INVOKE("delete_offer", { req }); }, +async mintOption(req: MintOption) : Promise { + return await TAURI_INVOKE("mint_option", { req }); +}, async networkConfig() : Promise { return await TAURI_INVOKE("network_config"); }, @@ -308,6 +311,7 @@ export type Logout = Record export type LogoutResponse = Record export type MakeOffer = { requested_assets: Assets; offered_assets: Assets; fee: Amount; expires_at_second: number | null } export type MakeOfferResponse = { offer: string; offer_id: string } +export type MintOption = { requested_assets: Assets; offered_assets: Assets; fee: Amount; expires_at_second: number; did_id: string; auto_submit?: boolean } export type Network = { default_port: number; ticker: string; address_prefix: string; precision: number; genesis_challenge: string; agg_sig_me: string; dns_introducers: string[] } export type NetworkConfig = { network_id: string; target_peers: number; discover_peers: boolean } export type NftCollectionRecord = { collection_id: string; did_id: string; metadata_collection_id: string; visible: boolean; name: string | null; icon: string | null; nfts: number; visible_nfts: number } diff --git a/src/pages/MakeOffer.tsx b/src/pages/MakeOffer.tsx index fef8d594..5fe41c36 100644 --- a/src/pages/MakeOffer.tsx +++ b/src/pages/MakeOffer.tsx @@ -1,4 +1,5 @@ -import { Assets, commands } from '@/bindings'; +import { Amount, Assets, commands, TransactionResponse } from '@/bindings'; +import ConfirmationDialog from '@/components/ConfirmationDialog'; import Container from '@/components/Container'; import { CopyBox } from '@/components/CopyBox'; import Header from '@/components/Header'; @@ -15,7 +16,15 @@ import { import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { TokenAmountInput } from '@/components/ui/masked-input'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; import { Switch } from '@/components/ui/switch'; +import { useDids } from '@/hooks/useDids'; import { useErrors } from '@/hooks/useErrors'; import { toMojos } from '@/lib/utils'; import { clearOffer, useOfferState, useWalletState } from '@/state'; @@ -35,50 +44,80 @@ export function MakeOffer() { const navigate = useNavigate(); const { addError } = useErrors(); + const { dids } = useDids(); const [offer, setOffer] = useState(''); + const [response, setResponse] = useState(null); + + const offeredAssets = (): Assets => { + return { + xch: toMojos( + (state.offered.xch || '0').toString(), + walletState.sync.unit.decimals, + ), + cats: state.offered.cats.map((cat) => ({ + asset_id: cat.asset_id, + amount: toMojos((cat.amount || '0').toString(), 3), + })), + nfts: state.offered.nfts, + }; + }; + + const requestedAssets = (): Assets => { + return { + xch: toMojos( + (state.requested.xch || '0').toString(), + walletState.sync.unit.decimals, + ), + cats: state.requested.cats.map((cat) => ({ + asset_id: cat.asset_id, + amount: toMojos((cat.amount || '0').toString(), 3), + })), + nfts: state.requested.nfts, + }; + }; + + const calculateFee = (): Amount => { + return toMojos( + (state.fee || '0').toString(), + walletState.sync.unit.decimals, + ); + }; + + const expiration = () => { + return state.expiration === null + ? null + : Math.ceil(Date.now() / 1000) + + Number(state.expiration.days || '0') * 24 * 60 * 60 + + Number(state.expiration.hours || '0') * 60 * 60 + + Number(state.expiration.minutes || '0') * 60; + }; const make = () => { commands .makeOffer({ - offered_assets: { - xch: toMojos( - (state.offered.xch || '0').toString(), - walletState.sync.unit.decimals, - ), - cats: state.offered.cats.map((cat) => ({ - asset_id: cat.asset_id, - amount: toMojos((cat.amount || '0').toString(), 3), - })), - nfts: state.offered.nfts, - }, - requested_assets: { - xch: toMojos( - (state.requested.xch || '0').toString(), - walletState.sync.unit.decimals, - ), - cats: state.requested.cats.map((cat) => ({ - asset_id: cat.asset_id, - amount: toMojos((cat.amount || '0').toString(), 3), - })), - nfts: state.requested.nfts, - }, - fee: toMojos( - (state.fee || '0').toString(), - walletState.sync.unit.decimals, - ), - expires_at_second: - state.expiration === null - ? null - : Math.ceil(Date.now() / 1000) + - Number(state.expiration.days || '0') * 24 * 60 * 60 + - Number(state.expiration.hours || '0') * 60 * 60 + - Number(state.expiration.minutes || '0') * 60, + offered_assets: offeredAssets(), + requested_assets: requestedAssets(), + fee: calculateFee(), + expires_at_second: expiration(), }) .then((data) => setOffer(data.offer)) .catch(addError); }; + const mintOption = () => { + commands + .mintOption({ + offered_assets: offeredAssets(), + requested_assets: requestedAssets(), + fee: calculateFee(), + expires_at_second: expiration()!, + did_id: state.did, + }) + .then((data) => setResponse(data)) + .catch(addError); + }; + const invalid = state.expiration !== null && (isNaN(Number(state.expiration.days)) || @@ -160,7 +199,65 @@ export function MakeOffer() {
- + + { + if (value) { + useOfferState.setState({ + option: true, + expiration: { + days: '7', + hours: '', + minutes: '', + }, + }); + } else { + useOfferState.setState({ + option: false, + }); + } + }} + /> +
+
+ + {state.option && ( + + )} + +
+
+ Cancel Offer - + + {state.option ? ( + + ) : ( + + )}
setOffer('')}> @@ -296,6 +400,12 @@ export function MakeOffer() { + + setResponse(null)} + onConfirm={() => navigate('/nfts')} + /> ); } diff --git a/src/pages/Offers.tsx b/src/pages/Offers.tsx index 7e4de1ba..48dbaa03 100644 --- a/src/pages/Offers.tsx +++ b/src/pages/Offers.tsx @@ -117,11 +117,11 @@ export function Offers() {
- +
diff --git a/src/state.ts b/src/state.ts index 42f1a845..b3c19dd7 100644 --- a/src/state.ts +++ b/src/state.ts @@ -19,6 +19,8 @@ export interface OfferState { requested: Assets; fee: string; expiration: OfferExpiration | null; + option: boolean; + did: string; } export interface OfferExpiration { @@ -135,6 +137,8 @@ export function defaultOffer(): OfferState { }, fee: '', expiration: null, + option: false, + did: '', }; }