diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c7c0c9..5708a9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,7 +65,7 @@ jobs: strategy: fail-fast: false matrix: - toolchain: [ nightly, beta, stable, 1.76.0 ] + toolchain: [ nightly, beta, stable, 1.77.0 ] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master diff --git a/.rustfmt.toml b/.rustfmt.toml index 9017cd7..6d14899 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,5 +1,5 @@ edition = "2021" -version = "Two" +style_edition = "2021" max_width = 100 array_width = 100 diff --git a/Cargo.lock b/Cargo.lock index 02edff3..9b874c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "aluvm" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04c1d697d7f5b86d935bfe06cfd0310fd8a6c491b043118bec228597dcede9" +checksum = "f2a6767842958f458dc7010a2a1005db96dfaceadd366d07532c5045bbc81f24" dependencies = [ "amplify", "ascii-armor", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -131,36 +131,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -199,15 +199,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" +checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d" dependencies = [ "aws-lc-sys", "mirai-annotations", @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.21.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234314bd569802ec87011d653d6815c6d7b9ffb969e9fee5b8b20ef860e8dce9" +checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972" dependencies = [ "bindgen", "cc", @@ -265,9 +265,9 @@ checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ "bitflags 2.6.0", "cexpr", @@ -282,16 +282,32 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.77", + "syn 2.0.85", "which", ] +[[package]] +name = "bitcoin-io" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" + [[package]] name = "bitcoin-private" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" +[[package]] +name = "bitcoin_hashes" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +dependencies = [ + "bitcoin-io", + "hex-conservative", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -328,14 +344,14 @@ dependencies = [ [[package]] name = "bp-consensus" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae3a99a46063d23d20a3177a04923652b245f31c2a04a6d0c47d5a93dc201a80" +checksum = "54db63118d55e32ea78f8775e98871d442a33e3bdef6419c7964d71b308316c0" dependencies = [ "amplify", "chrono", "commit_verify", - "secp256k1", + "secp256k1 0.30.0", "serde", "strict_encoding", "strict_types", @@ -343,9 +359,9 @@ dependencies = [ [[package]] name = "bp-core" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8caf04291e2703ce267b1f8baf14f03879a6d1a5afe76e011ada489f172f9" +checksum = "2e51a329150531b12243adf51d978490c796a6a20ec76c506b41c8e1226022bc" dependencies = [ "amplify", "bp-consensus", @@ -362,40 +378,40 @@ dependencies = [ [[package]] name = "bp-dbc" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11fc4081db2147411381b9650765ce683e5065559f1125508696f79cc4cbfedf" +checksum = "9286fb448160672148262317f4647ebdcdd4699ed2bd34401f9799d0920cc376" dependencies = [ "amplify", "base85", "bp-consensus", "commit_verify", - "secp256k1", + "secp256k1 0.30.0", "serde", "strict_encoding", ] [[package]] name = "bp-derive" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2687829a365ba79a22d91737fa7404fd3e2aaeee6b8f5780fa3e94e6cb36c2" +checksum = "394f8a2c3f4df405aff7269d1727b463e2cf74ec35a077fe7425084cdbdd0448" dependencies = [ "amplify", "bp-consensus", "bp-invoice", "commit_verify", "hmac", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "sha2", ] [[package]] name = "bp-electrum" -version = "0.11.0-beta.8.1" +version = "0.11.0-beta.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0db2dc3a49489718e6e06cb796c536ca39eef8c036051afcb3f8d51cbc610fb8" +checksum = "cc58108a622b07755bf4a9468325b76e74f47042b1b493ff30a9059a20c2c34a" dependencies = [ "amplify", "bp-std", @@ -412,23 +428,9 @@ dependencies = [ [[package]] name = "bp-esplora" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93ec91cf6d037996044e90223ef0fba7f8a465e24eeed73ca9651271b03a964" -dependencies = [ - "amplify", - "bp-std", - "log", - "serde", - "serde_with", - "sha2", - "ureq", -] - -[[package]] -name = "bp-esplora" -version = "0.11.0-beta.8" -source = "git+https://github.com/BP-WG/bp-esplora-client?branch=master#4cdad88d83e660a06aae5457cd2c7eeed369baa5" +checksum = "d5b002e82289784e579f130ebdc22aa0b19a7b873620ea1dab16628999ba404d" dependencies = [ "amplify", "bp-std", @@ -441,9 +443,9 @@ dependencies = [ [[package]] name = "bp-invoice" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29c4f672b4b82ce7a218b2900254ac8e4b15b0022ed13abffa722571e73d375" +checksum = "2cfe7be7b2d740de57e895f2ac93b305bbd67a2a0914dac424f8569bb9981679" dependencies = [ "amplify", "bech32", @@ -454,9 +456,9 @@ dependencies = [ [[package]] name = "bp-seals" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d607238c2bf2c34d048d14cd798a6365306e0fb6b02211235f3ccad0bc7fa8f1" +checksum = "9873cfe420f4ce5cc539c394c75df0669cdbe2c23eed1930dffe024cb0f13a57" dependencies = [ "amplify", "baid64", @@ -471,32 +473,32 @@ dependencies = [ [[package]] name = "bp-std" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c9642f7b303791ba5696ff4be52c8d21ac2d2265bf9552692c8b03c741c11c" +checksum = "e23c585b49b6d3112b0ea1a2d2e143f493fd0ecbb3bb11bbbe41c69b63a4411c" dependencies = [ "amplify", "bp-consensus", + "bp-core", "bp-derive", "bp-invoice", "descriptors", "getrandom", "psbt", - "secp256k1", + "secp256k1 0.30.0", "serde", "wasm-bindgen", ] [[package]] name = "bp-wallet" -version = "0.11.0-beta.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b3cda17bafd67254e6f0be1b401a31d942dc54be138d5cc7976bb58291dff0" +version = "0.11.0-beta.9" +source = "git+https://github.com/BP-WG/bp-wallet?branch=master#784ff20685693324e76380a703ecc4cc6d613145" dependencies = [ "amplify", "base64", "bp-electrum", - "bp-esplora 0.11.0-beta.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bp-esplora", "bp-std", "clap", "colored", @@ -528,9 +530,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.1.19" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", @@ -580,9 +582,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -590,9 +592,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -602,14 +604,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] @@ -629,9 +631,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" @@ -658,9 +660,9 @@ dependencies = [ [[package]] name = "commit_verify" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a1982dc6c54d2dcfa2bf4398d97e4e80a93f24d2537e58d6110b2b272cff0c" +checksum = "3bf08c4941e147937551f6a3d370552d67f98cf72c9eb18948142596beadd31e" dependencies = [ "amplify", "commit_encoding_derive", @@ -750,7 +752,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] @@ -761,7 +763,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] @@ -776,13 +778,13 @@ dependencies = [ [[package]] name = "descriptors" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e15b0f1ea4c1b7f66b86153341f08961122f5bad3fa68546b9ac5b199c99c39" +checksum = "49798157ca640745a3c898714b5805c28482295de8819cb7b2c530b8f9246df1" dependencies = [ "amplify", "bp-derive", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", ] @@ -871,15 +873,15 @@ dependencies = [ [[package]] name = "fast32" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ea9bdb2356e5a92403cf23ac493f9b43bd71e4ffd0f800862b841dd723994c" +checksum = "a35a73237400bde66c82e38387343f90d7182a2f2f22729e096a2abd57d75db9" [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -962,9 +964,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" @@ -978,6 +980,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1004,9 +1015,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1054,12 +1065,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "serde", ] @@ -1095,9 +1106,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1116,9 +1127,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libloading" @@ -1166,9 +1177,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minicov" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" +checksum = "def6d99771d7c499c26ad4d40eb6645eafd3a1553b35fc26ea5a489a45e82d9a" dependencies = [ "cc", "walkdir", @@ -1238,9 +1249,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ea5043e58958ee56f3e15a90aee535795cd7dfd319846288d93c5b57d85cbe" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "option-ext" @@ -1277,28 +1288,28 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] [[package]] name = "psbt" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5b2f8fb596a1caffa486595c66eae3ebc3fb05c74063348b9a987373ba0cdb" +checksum = "1d36b72ab550141a04a368c25611bf04c87178b65d3be5165529e0b010ee551b" dependencies = [ "amplify", "base64", @@ -1307,7 +1318,7 @@ dependencies = [ "chrono", "commit_verify", "descriptors", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "strict_encoding", ] @@ -1364,9 +1375,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1376,9 +1387,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1387,15 +1398,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rgb-core" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43dc70212f5eff8189f3cdfef2d11f53f7be4c4128db9839b5d56a0f9ef60c98" +checksum = "1cf48c4e395882c5228cd788a78e04674c94f7c177d82afdd87def8619f5dff8" dependencies = [ "aluvm", "amplify", @@ -1413,30 +1424,10 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "rgb-interfaces" -version = "0.11.0-beta.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37dea80df39205f6c1d0fc4a6d2ea0401d5e6b9b28ed852b707cb01517b3c991" -dependencies = [ - "aluvm", - "amplify", - "bp-core", - "chrono", - "getrandom", - "rgb-std", - "serde_json", - "sha2", - "strict_encoding", - "strict_types", - "wasm-bindgen", -] - [[package]] name = "rgb-invoice" -version = "0.11.0-beta.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d42e9d284f857f3dccce63521789f3da75568f55488d255ebacc8fe343012a5d" +version = "0.11.0-beta.9" +source = "git+https://github.com/RGB-WG/rgb-std?branch=master#ddee8898e4d6a2f156587feabb6f19fca08946c0" dependencies = [ "amplify", "baid64", @@ -1444,7 +1435,7 @@ dependencies = [ "bp-invoice", "fast32", "fluent-uri", - "indexmap 2.5.0", + "indexmap 2.6.0", "percent-encoding", "rand", "rgb-core", @@ -1455,7 +1446,7 @@ dependencies = [ [[package]] name = "rgb-psbt" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" dependencies = [ "amplify", "baid64", @@ -1463,7 +1454,6 @@ dependencies = [ "bp-std", "commit_verify", "getrandom", - "psbt", "rand", "rgb-std", "strict_encoding", @@ -1473,20 +1463,19 @@ dependencies = [ [[package]] name = "rgb-runtime" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" dependencies = [ "amplify", "baid64", "bp-core", "bp-electrum", - "bp-esplora 0.11.0-beta.8 (git+https://github.com/BP-WG/bp-esplora-client?branch=master)", + "bp-esplora", "bp-std", "bp-wallet", "chrono", "commit_verify", - "descriptors", "getrandom", - "indexmap 2.5.0", + "indexmap 2.6.0", "log", "nonasync", "rand", @@ -1501,9 +1490,8 @@ dependencies = [ [[package]] name = "rgb-std" -version = "0.11.0-beta.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a97b5e58521f41837b1a92f480041fd72a0659f22cb132354d2bbcba25b25" +version = "0.11.0-beta.9" +source = "git+https://github.com/RGB-WG/rgb-std?branch=master#ddee8898e4d6a2f156587feabb6f19fca08946c0" dependencies = [ "aluvm", "amplify", @@ -1514,7 +1502,7 @@ dependencies = [ "chrono", "commit_verify", "getrandom", - "indexmap 2.5.0", + "indexmap 2.6.0", "nonasync", "rand", "rgb-core", @@ -1527,19 +1515,16 @@ dependencies = [ [[package]] name = "rgb-wallet" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" dependencies = [ "amplify", "baid64", - "bp-seals", "bp-std", "bp-wallet", "clap", "commit_verify", "env_logger", "log", - "psbt", - "rgb-interfaces", "rgb-runtime", "rgb-std", "serde", @@ -1582,9 +1567,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.6.0", "errno", @@ -1595,9 +1580,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.13" +version = "0.23.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" dependencies = [ "aws-lc-rs", "log", @@ -1611,9 +1596,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -1659,6 +1644,18 @@ dependencies = [ "serde", ] +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +dependencies = [ + "bitcoin_hashes", + "rand", + "secp256k1-sys", + "serde", +] + [[package]] name = "secp256k1-sys" version = "0.10.1" @@ -1676,16 +1673,16 @@ checksum = "52a44aed3002b5ae975f8624c5df3a949cfbf00479e18778b6058fcd213b76e3" dependencies = [ "bitcoin-private", "rand", - "secp256k1", + "secp256k1 0.29.1", "secp256k1-zkp-sys", "serde", ] [[package]] name = "secp256k1-zkp-sys" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6eea7919e0cab992510edfbf40bd9342c0a3c2bb910f2c51355c2cb2d69839" +checksum = "57f08b2d0b143a22e07f798ae4f0ab20d5590d7c68e0d090f2088a48a21d1654" dependencies = [ "cc", "secp256k1-sys", @@ -1693,29 +1690,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -1725,9 +1722,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -1744,15 +1741,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_derive", "serde_json", @@ -1762,14 +1759,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.9.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] @@ -1778,7 +1775,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "itoa", "ryu", "serde", @@ -1813,9 +1810,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "single_use_seals" -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a4c51f21507cf63984c367507f281215073e85b08711ed7da4fc63dbd709e0" +checksum = "ec071f3b3153217f1cb2bca5ba7ac87eeafc446cb35a5c0643dec33495a37244" dependencies = [ "amplify_derive", ] @@ -1865,15 +1862,15 @@ dependencies = [ [[package]] name = "strict_types" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f16e8855a575633815f01482ac927ebaca3d2485aec8e17226c6826de29154e" +checksum = "8bae7475fc901144d8a35d25e36d76aa020b840f233d60532d6d52318718781b" dependencies = [ "amplify", "ascii-armor", "baid64", "half", - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_json", "serde_yaml", @@ -1919,9 +1916,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -1930,22 +1927,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] @@ -2017,11 +2014,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.5.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -2036,9 +2033,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" @@ -2048,9 +2045,9 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -2137,9 +2134,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -2148,24 +2145,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -2175,9 +2172,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2185,28 +2182,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-bindgen-test" -version = "0.3.43" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" +checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" dependencies = [ "console_error_panic_hook", "js-sys", @@ -2219,20 +2216,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.43" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" +checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -2240,9 +2237,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.5" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] @@ -2449,9 +2446,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -2474,7 +2471,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.85", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cabccb7..77e3ec7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,34 +10,30 @@ default-members = [ ] [workspace.package] -version = "0.11.0-beta.8" +version = "0.11.0-beta.9" keywords = ["bitcoin", "lightning", "rgb", "smart-contracts", "lnp-bp"] categories = ["cryptography::cryptocurrencies"] authors = ["Dr Maxim Orlovsky "] homepage = "https://rgb.tech" repository = "https://github.com/RGB-WG/rgb" -rust-version = "1.76.0" +rust-version = "1.77.0" edition = "2021" license = "Apache-2.0" [workspace.dependencies] amplify = "4.7.0" -nonasync = { version = "0.1.0", features = ["log"] } +nonasync = { version = "0.1.2", features = ["log"] } baid64 = "0.2.2" strict_encoding = "2.7.0" -strict_types = "2.7.0" -commit_verify = "0.11.0-beta.8" -bp-core = "0.11.0-beta.8" -bp-seals = "0.11.0-beta.8" -bp-std = "0.11.0-beta.8" -bp-electrum = "0.11.0-beta.8" -bp-esplora = { version = "0.11.0-beta.8", default-features = false, git = "https://github.com/BP-WG/bp-esplora-client", branch = "master" } -descriptors = "0.11.0-beta.8" -psbt = { version = "0.11.0-beta.8", features = ["client-side-validation"] } -bp-wallet = { version = "0.11.0-beta.8" } -rgb-std = { version = "0.11.0-beta.8" } -rgb-psbt = { version = "0.11.0-beta.8", path = "psbt" } -rgb-interfaces = "0.11.0-beta.8" +strict_types = "2.7.2" +commit_verify = "0.11.0-beta.9" +bp-core = "0.11.0-beta.9" +bp-std = { version = "0.11.0-beta.9", features = ["client-side-validation"] } +bp-electrum = "0.11.0-beta.9" +bp-esplora = { version = "0.11.0-beta.9", default-features = false } +bp-wallet = { version = "0.11.0-beta.9" } +rgb-std = { version = "0.11.0-beta.9" } +rgb-psbt = { version = "0.11.0-beta.9", path = "psbt" } indexmap = "2.4.0" chrono = "0.4.38" serde_crate = { package = "serde", version = "1", features = ["derive"] } @@ -72,7 +68,6 @@ strict_types = { workspace = true } bp-core = { workspace = true } bp-std = { workspace = true } bp-esplora = { workspace = true, optional = true } -descriptors = { workspace = true } bp-wallet = { workspace = true } rgb-std = { workspace = true } rgb-psbt = { workspace = true } @@ -99,7 +94,12 @@ esplora_blocking = ["bp-esplora", "bp-esplora/blocking"] esplora_blocking-wasm = ["bp-esplora", "bp-esplora/blocking-wasm"] electrum_blocking = ["bp-electrum"] mempool_blocking = ["esplora_blocking"] -serde = ["serde_crate", "serde_yaml", "bp-std/serde", "descriptors/serde", "rgb-psbt/serde"] +serde = ["serde_crate", "serde_yaml", "bp-std/serde", "rgb-psbt/serde"] [package.metadata.docs.rs] features = ["all"] + +[patch.crates-io] +bp-wallet = { git = "https://github.com/BP-WG/bp-wallet", branch = "master" } +rgb-invoice = { git = "https://github.com/RGB-WG/rgb-std", branch = "master" } +rgb-std = { git = "https://github.com/RGB-WG/rgb-std", branch = "master" } diff --git a/Dockerfile b/Dockerfile index 592c468..43d7119 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ARG SRC_DIR=/usr/local/src/rgb ARG BUILDER_DIR=/srv/rgb # Base image -FROM rust:1.76.0-slim-bookworm as chef +FROM rust:1.77.0-slim-bookworm as chef ARG SRC_DIR ARG BUILDER_DIR diff --git a/MANIFEST.yml b/MANIFEST.yml index 0cf78b4..5258264 100644 --- a/MANIFEST.yml +++ b/MANIFEST.yml @@ -3,7 +3,7 @@ Type: Binary Kind: Free software License: Apache-2.0 Language: Rust -Compiler: 1.76 +Compiler: 1.77 Author: Maxim Orlovsky Maintained: LNP/BP Standards Association, Switzerland Maintainers: diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 2905353..b408432 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -21,13 +21,10 @@ amplify = { workspace = true } baid64 = { workspace = true } strict_types = { workspace = true, features = ["serde"] } commit_verify = { workspace = true } -bp-seals = { workspace = true } bp-std = { workspace = true, features = ["serde"] } bp-wallet = { workspace = true, features = ["cli"] } -psbt = { workspace = true } rgb-std = { workspace = true, features = ["serde"] } -rgb-interfaces = { workspace = true } -rgb-runtime = { version = "0.11.0-beta.7", path = "..", features = ["electrum_blocking", "esplora_blocking", "mempool_blocking", "log", "serde", "fs", "cli"] } +rgb-runtime = { version = "0.11.0-beta.8", path = "..", features = ["electrum_blocking", "esplora_blocking", "mempool_blocking", "log", "serde", "fs", "cli"] } log = { workspace = true } env_logger = "0.11.5" clap = { version = "4.5.17", features = ["derive", "env"] } diff --git a/cli/src/args.rs b/cli/src/args.rs index 4f4697a..4614f5d 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -104,19 +104,27 @@ impl RgbArgs { } let provider = FsBinStore::new(stock_path.clone())?; - let mut stock = Stock::load(provider, true).map_err(WalletError::WalletPersist).or_else(|err| { - if matches!(err, WalletError::Deserialize(DeserializeError::Decode(DecodeError::Io(ref err))) if err.kind() == ErrorKind::NotFound) { + let mut stock = Stock::load(provider, true).or_else(|err| { + if err + .0 + .downcast_ref::() + .map(|e| matches!(e, DeserializeError::Decode(DecodeError::Io(ref e)) if e.kind() == ErrorKind::NotFound)) + .unwrap_or_default() + { if self.verbose > 1 { eprint!("stock file is absent, creating a new one ... "); } fs::create_dir_all(&stock_path)?; let provider = FsBinStore::new(stock_path)?; let mut stock = Stock::in_memory(); - stock.make_persistent(provider, true).map_err(WalletError::StockPersist)?; + stock + .make_persistent(provider, true) + .map_err(WalletError::StockPersist)?; return Ok(stock); } eprintln!("stock file is damaged, failing"); - Err(err) + error!("Unable to load stock data: {err:?}"); + Err(WalletError::StockPersist(err)) })?; if self.sync { diff --git a/cli/src/command.rs b/cli/src/command.rs index 2541e47..f14b5c2 100644 --- a/cli/src/command.rs +++ b/cli/src/command.rs @@ -21,34 +21,37 @@ use std::fs; use std::fs::File; +use std::ops::ControlFlow; use std::path::PathBuf; use std::str::FromStr; use amplify::confinement::{SmallOrdMap, TinyOrdMap, TinyOrdSet, U16 as MAX16}; use baid64::DisplayBaid64; +use bpstd::psbt::{Psbt, PsbtVer}; +use bpstd::seals::SecretSeal; use bpstd::{Sats, XpubDerivable}; use bpwallet::cli::{BpCommand, Config, Exec}; use bpwallet::Wallet; -use ifaces::{IfaceStandard, Rgb20, Rgb21, Rgb25}; -use psbt::{Psbt, PsbtVer}; use rgb::containers::{ - BuilderSeal, ContainerVer, ContentId, ContentSigs, Contract, FileContent, Supplement, Transfer, - UniversalFile, + BuilderSeal, ConsignmentExt, ContainerVer, ContentId, ContentSigs, Contract, FileContent, + Supplement, Transfer, UniversalFile, }; -use rgb::interface::{AmountChange, IfaceId, OutpointFilter}; +use rgb::interface::{AssignmentsFilter, ContractOp, IfaceId}; use rgb::invoice::{Beneficiary, Pay2Vout, RgbInvoice, RgbInvoiceBuilder, XChainNet}; -use rgb::persistence::StashReadProvider; +use rgb::persistence::{MemContract, StashReadProvider, Stock}; +use rgb::resolvers::ContractIssueResolver; use rgb::schema::SchemaId; use rgb::validation::Validity; -use rgb::vm::RgbIsa; +use rgb::vm::{RgbIsa, WitnessOrd}; use rgb::{ - BundleId, ContractId, DescriptorRgb, GenesisSeal, GraphSeal, Identity, OutputSeal, RgbDescr, - RgbKeychain, RgbWallet, StateType, TransferParams, WalletError, WalletProvider, XChain, - XOutpoint, XOutputSeal, XWitnessId, + Allocation, BundleId, ContractId, DescriptorRgb, GenesisSeal, GraphSeal, Identity, OpId, + OutputSeal, OwnedFraction, RgbDescr, RgbKeychain, RgbWallet, StateType, TokenIndex, + TransferParams, WalletError, WalletProvider, XChain, XOutpoint, XWitnessId, }; -use rgbstd::containers::ConsignmentExt; -use rgbstd::persistence::{MemContract, Stock}; -use seals::SecretSeal; +use rgbstd::interface::{AllocatedState, ContractIface, OwnedIface}; +use rgbstd::persistence::{MemContractState, StockError}; +use rgbstd::stl::rgb_contract_stl; +use rgbstd::{KnownState, OutputAssignment}; use serde_crate::{Deserialize, Serialize}; use strict_types::encoding::{FieldName, TypeName}; use strict_types::StrictVal; @@ -74,10 +77,7 @@ pub enum Command { /// Prints out list of known RGB contracts #[display("contracts")] - Contracts { - /// Select only contracts using specific interface standard - standard: Option, - }, + Contracts, /// Imports RGB data into the stash: contracts, schema, interfaces, etc #[display("import")] @@ -120,26 +120,30 @@ pub enum Command { /// Reports information about state of a contract #[display("state")] State { - /// Show all state - not just the one owned by the wallet - #[clap(short, long)] + /// Show all state, including already spent and not owned by the wallet + #[arg(short, long)] all: bool, /// Contract identifier contract_id: ContractId, /// Interface to interpret the state data - iface: String, + iface: Option, }, /// Print operation history for a default fungible token under a given /// interface - #[display("history-fungible")] - HistoryFungible { + #[display("history")] + History { + /// Print detailed information + #[arg(long)] + details: bool, + /// Contract identifier contract_id: ContractId, /// Interface to interpret the state data - iface: String, + iface: Option, }, /// Display all known UTXOs belonging to this wallet @@ -162,21 +166,45 @@ pub enum Command { #[display("invoice")] Invoice { /// Force address-based invoice - #[clap(short, long)] + #[arg(short, long)] address_based: bool, + /// Interface to interpret the state data + #[arg(short, long)] + iface: Option, + + /// Operation to use for the invoice + /// + /// If no operation is provided, the interface default operation is used. + #[arg(short, long)] + operation: Option, + + /// State name to use for the invoice + /// + /// If no state name is provided, the interface default state name for the operation is + /// used. + #[arg(short, long, requires = "operation")] + state: Option, + /// Contract identifier contract_id: ContractId, - /// Interface to interpret the state data - iface: String, + /// Amount of tokens (in the smallest unit) to transfer + #[arg(short, long)] + amount: Option, - /// Value to transfer - value: u64, + /// Token index for NFT transfer + #[arg(long)] + token_index: Option, + + /// Fraction of an NFT token to transfer + #[arg(long, requires = "token_index")] + token_fraction: Option, }, - /// Prepare PSBT file for transferring RGB assets. In the most of cases you - /// need to use `transfer` command instead of `prepare` and `consign`. + /// Prepare PSBT file for transferring RGB assets + /// + /// In the most of cases you need to use `transfer` command instead of `prepare` and `consign`. #[display("prepare")] Prepare { /// Encode PSBT as V2 @@ -185,7 +213,7 @@ pub enum Command { /// Amount of satoshis which should be paid to the address-based /// beneficiary - #[clap(long, default_value = "2000")] + #[arg(long, default_value = "2000")] sats: Sats, /// Invoice data @@ -198,8 +226,9 @@ pub enum Command { psbt: Option, }, - /// Prepare consignment for transferring RGB assets. In the most of the - /// cases you need to use `transfer` command instead of `prepare` and + /// Prepare consignment for transferring RGB assets + /// + /// In the most of the cases you need to use `transfer` command instead of `prepare` and /// `consign`. #[display("prepare")] Consign { @@ -217,19 +246,19 @@ pub enum Command { #[display("transfer")] Transfer { /// Encode PSBT as V2 - #[clap(short = '2')] + #[arg(short = '2')] v2: bool, /// Amount of satoshis which should be paid to the address-based /// beneficiary - #[clap(long, default_value = "2000")] + #[arg(long, default_value = "2000")] sats: Sats, /// Invoice data invoice: RgbInvoice, /// Fee for bitcoin transaction, in satoshis - #[clap(short, long, default_value = "400")] + #[arg(short, long, default_value = "400")] fee: Sats, /// File for generated transfer consignment @@ -299,6 +328,7 @@ pub enum Command { #[display(lowercase)] #[clap(hide = true)] pub enum DebugCommand { + /// List known tapret tweaks for a wallet Taprets, } @@ -338,57 +368,66 @@ impl Exec for RgbArgs { print!("{info}"); } } - Command::Contracts { standard: None } => { + Command::Contracts => { let stock = self.rgb_stock()?; for info in stock.contracts()? { print!("{info}"); } } - Command::Contracts { - standard: Some(IfaceStandard::Rgb20), - } => { - let stock = self.rgb_stock()?; - for info in stock.contracts_by::()? { - print!("{info}"); - } - } - Command::Contracts { - standard: Some(IfaceStandard::Rgb21), - } => { - let stock = self.rgb_stock()?; - for info in stock.contracts_by::()? { - print!("{info}"); - } - } - Command::Contracts { - standard: Some(IfaceStandard::Rgb25), - } => { - let stock = self.rgb_stock()?; - for info in stock.contracts_by::()? { - print!("{info}"); - } - } - Command::HistoryFungible { contract_id, iface } => { + Command::History { + contract_id, + iface, + details, + } => { let wallet = self.rgb_wallet(&config)?; - let iface: TypeName = tn!(iface.clone()); - let history = wallet.fungible_history(*contract_id, iface)?; - println!("Amount\tCounterparty\tWitness Id"); - for (id, op) in history { - let (cparty, more) = match op.state_change { - AmountChange::Dec(_) => { - (op.beneficiaries.first(), op.beneficiaries.len().saturating_sub(1)) - } - AmountChange::Zero => continue, - AmountChange::Inc(_) => { - (op.payers.first(), op.payers.len().saturating_sub(1)) - } - }; - let more = if more > 0 { format!(" (+{more})") } else { s!("") }; - let cparty = cparty - .map(XOutputSeal::to_string) - .unwrap_or_else(|| s!("none")); - println!("{}\t{}{}\t{}", op.state_change, cparty, more, id); + let iface = match contract_default_iface_name(*contract_id, wallet.stock(), iface)? + { + ControlFlow::Continue(name) => name, + ControlFlow::Break(_) => return Ok(()), + }; + let mut history = wallet.history(*contract_id, iface)?; + history.sort_by_key(|op| op.witness.map(|w| w.ord).unwrap_or(WitnessOrd::Archived)); + if *details { + println!("Operation\tValue \tState\t{:78}\tWitness", "Seal"); + } else { + println!("Operation\tValue \t{:78}\tWitness", "Seal"); + } + for ContractOp { + direction, + ty, + opids, + state, + to, + witness, + } in history + { + print!("{:9}\t", direction.to_string()); + if let AllocatedState::Amount(amount) = state { + print!("{: >9}", amount.value()); + } else { + print!("{state:>9}"); + } + if *details { + print!("\t{ty}"); + } + println!( + "\t{}\t{}", + to.first().expect("at least one receiver is always present"), + witness + .map(|info| format!("{} ({})", info.id, info.ord)) + .unwrap_or_else(|| s!("~")) + ); + if *details { + println!( + "\topid={}", + opids + .iter() + .map(OpId::to_string) + .collect::>() + .join("\n\topid=") + ) + } } } @@ -498,6 +537,11 @@ impl Exec for RgbArgs { } } + let iface = match contract_default_iface_name(*contract_id, &stock, iface)? { + ControlFlow::Continue(name) => name, + ControlFlow::Break(_) => return Ok(()), + }; + let stock_wallet = match self.rgb_wallet_from_stock(&config, stock) { Ok(wallet) => StockOrWallet::Wallet(wallet), Err((stock, _)) => StockOrWallet::Stock(stock), @@ -530,91 +574,94 @@ impl Exec for RgbArgs { WalletAll(&'w RgbWallet>), NoWallet, } - impl<'w> OutpointFilter for Filter<'w> { - fn include_outpoint(&self, outpoint: impl Into) -> bool { + impl<'w> AssignmentsFilter for Filter<'w> { + fn should_include( + &self, + outpoint: impl Into, + id: Option, + ) -> bool { match self { - Filter::Wallet(wallet) => { - wallet.wallet().filter().include_outpoint(outpoint) - } + Filter::Wallet(wallet) => wallet + .wallet() + .filter_unspent() + .should_include(outpoint, id), _ => true, } } } impl<'w> Filter<'w> { fn comment(&self, outpoint: XOutpoint) -> &'static str { + let outpoint = outpoint + .into_bp() + .into_bitcoin() + .expect("liquid is not yet supported"); match self { - Filter::Wallet(wallet) | Filter::WalletAll(wallet) - if wallet.wallet().filter().include_outpoint(outpoint) => - { - "" + Filter::Wallet(rgb) if rgb.wallet().is_unspent(outpoint) => "", + Filter::WalletAll(rgb) if rgb.wallet().is_unspent(outpoint) => { + "-- unspent" + } + Filter::WalletAll(rgb) if rgb.wallet().has_outpoint(outpoint) => { + "-- spent" } - _ => "-- owner unknown", + _ => "-- third-party", } } } println!("\nOwned:"); + fn witness( + allocation: &OutputAssignment, + contract: &ContractIface>, + ) -> String { + allocation + .witness + .and_then(|w| contract.witness_info(w)) + .map(|info| format!("{} ({})", info.id, info.ord)) + .unwrap_or_else(|| s!("~")) + } for owned in &contract.iface.assignments { + println!(" State \t{:78}\tWitness", "Seal"); println!(" {}:", owned.name); if let Ok(allocations) = contract.fungible(owned.name.clone(), &filter) { for allocation in allocations { - let witness = allocation - .witness - .as_ref() - .map(XWitnessId::to_string) - .unwrap_or(s!("~")); println!( - " value={}, utxo={}, witness={} {}", + " {: >9}\t{}\t{} {}", allocation.state.value(), allocation.seal, - witness, + witness(&allocation, &contract), filter.comment(allocation.seal.to_outpoint()) ); } } if let Ok(allocations) = contract.data(owned.name.clone(), &filter) { for allocation in allocations { - let witness = allocation - .witness - .as_ref() - .map(XWitnessId::to_string) - .unwrap_or(s!("~")); println!( - " data={}, utxo={}, witness={} {}", + " {: >9}\t{}\t{} {}", allocation.state, allocation.seal, - witness, + witness(&allocation, &contract), filter.comment(allocation.seal.to_outpoint()) ); } } if let Ok(allocations) = contract.attachments(owned.name.clone(), &filter) { for allocation in allocations { - let witness = allocation - .witness - .as_ref() - .map(XWitnessId::to_string) - .unwrap_or(s!("~")); println!( - " file={}, utxo={}, witness={} {}", + " {: >9}\t{}\t{} {}", allocation.state, allocation.seal, - witness, + witness(&allocation, &contract), filter.comment(allocation.seal.to_outpoint()) ); } } if let Ok(allocations) = contract.rights(owned.name.clone(), &filter) { for allocation in allocations { - let witness = allocation - .witness - .as_ref() - .map(XWitnessId::to_string) - .unwrap_or(s!("~")); println!( - " utxo={}, witness={} {}", + " {: >9}\t{}\t{} {}", + "right", allocation.seal, - witness, + witness(&allocation, &contract), filter.comment(allocation.seal.to_outpoint()) ); } @@ -750,8 +797,7 @@ impl Exec for RgbArgs { let contract = builder.issue_contract()?; let id = contract.contract_id(); - let resolver = self.resolver()?; - stock.import_contract(contract, &resolver)?; + stock.import_contract(contract, &ContractIssueResolver)?; eprintln!( "A new contract {id} is issued and added to the stash.\nUse `export` command \ to export the contract." @@ -759,12 +805,15 @@ impl Exec for RgbArgs { } Command::Invoice { address_based, + operation, + state, contract_id, iface, - value, + amount, + token_index, + token_fraction, } => { let mut wallet = self.rgb_wallet(&config)?; - let iface = TypeName::try_from(iface.to_owned()).expect("invalid interface name"); let outpoint = wallet .wallet() @@ -801,11 +850,128 @@ impl Exec for RgbArgs { Beneficiary::BlindedSeal(*seal.to_secret_seal().as_reduced_unsafe()) } }; - let invoice = RgbInvoiceBuilder::new(XChainNet::bitcoin(network, beneficiary)) + + let iface = match contract_default_iface_name(*contract_id, wallet.stock(), iface)? + { + ControlFlow::Continue(name) => wallet.stock().iface(name)?, + ControlFlow::Break(_) => return Ok(()), + }; + let iface_name = &iface.name; + let Some(op_name) = operation + .clone() + .map(FieldName::try_from) + .transpose() + .map_err(|e| WalletError::Invoicing(format!("invalid operation name - {e}")))? + .or(iface.default_operation.clone()) + else { + return Err(WalletError::Invoicing(format!( + "interface {iface_name} doesn't have default operation" + ))); + }; + let Some(iface_op) = iface.transitions.get(&op_name) else { + return Err(WalletError::Invoicing(format!( + "interface {iface_name} doesn't have operation {op_name}" + ))); + }; + let state_name = state + .clone() + .map(FieldName::try_from) + .transpose() + .map_err(|e| WalletError::Invoicing(format!("invalid state name - {e}")))? + .or_else(|| iface_op.default_assignment.clone()) + .ok_or_else(|| { + WalletError::Invoicing(format!( + "interface {iface_name} doesn't have a default state for the \ + operation {op_name}" + )) + })?; + let Some(assign_iface) = iface.assignments.get(&state_name) else { + return Err(WalletError::Invoicing(format!( + "interface {iface_name} doesn't have state {state_name} in operation \ + {op_name}" + ))); + }; + + let mut builder = RgbInvoiceBuilder::new(XChainNet::bitcoin(network, beneficiary)) .set_contract(*contract_id) - .set_interface(iface) - .set_amount_raw(*value) - .finish(); + .set_interface(iface_name.clone()); + + if operation.is_some() { + builder = builder.set_operation(op_name); + if let Some(state) = state { + builder = builder.set_operation(fname!(state.clone())); + } + } + + match (assign_iface.owned_state, amount, token_index.map(|i| (i, token_fraction))) { + ( + OwnedIface::Rights + | OwnedIface::Amount + | OwnedIface::AnyData + | OwnedIface::Data(_), + None, + None, + ) => { + // There is no state which has to be added to the invoice + } + (OwnedIface::Rights, Some(_), None | Some(_)) + | (OwnedIface::Rights, None, Some(_)) => { + return Err(WalletError::Invoicing(format!( + "state {state_name} in interface {iface_name} defines a right and it \ + can't has a value or a token information" + ))); + } + (OwnedIface::Amount, _, Some(_)) => { + return Err(WalletError::Invoicing(format!( + "state {state_name} in interface {iface_name} defines a fungible \ + state, while a non-fungible token index is provided for the invoice. \ + Please use only --amount argument" + ))); + } + (OwnedIface::Amount, Some(amount), None) => { + builder = builder.set_amount_raw(*amount); + } + (OwnedIface::Data(_) | OwnedIface::AnyData, Some(_), _) => { + return Err(WalletError::Invoicing(format!( + "state {state_name} in interface {iface_name} defines a non-fungible \ + state, while a fungible amount is provided for the invoice. Please \ + use only --token-index and --token-fraction arguments" + ))); + } + (OwnedIface::Data(sem_id), None, Some(_)) + if sem_id + != rgb_contract_stl() + .types + .get(&tn!("Allocation")) + .expect("STL is broken") + .sem_id_named(&tn!("Allocation")) => + { + return Err(WalletError::Invoicing(format!( + "state {state_name} in interface {iface_name} has a type which can't \ + be used with a non-fungible state allocation" + ))); + } + (OwnedIface::AnyData | OwnedIface::Data(_), None, Some((index, fraction))) => { + builder = builder.set_allocation_raw(Allocation::with( + index, + fraction.unwrap_or(OwnedFraction::from(0)), + )) + } + + (OwnedIface::Any, _, _) => { + return Err(WalletError::Invoicing(format!( + "state {state_name} in interface {iface_name} can be of any type; \ + adding it to the invoice is impossible" + ))); + } + (OwnedIface::AnyAttach, _, _) => { + return Err(WalletError::Invoicing(s!( + "invoicing with attachments is not yet supported" + ))); + } + } + + let invoice = builder.finish(); println!("{invoice}"); } Command::Prepare { @@ -1109,8 +1275,42 @@ impl Exec for RgbArgs { eprintln!("Transfer accepted into the stash"); } } - println!(); - Ok(()) } } + +fn contract_default_iface_name( + contract_id: ContractId, + stock: &Stock, + iface: &Option, +) -> Result, StockError> { + if let Some(iface) = iface { + return Ok(ControlFlow::Continue(tn!(iface.clone()))); + }; + let info = stock.contract_info(contract_id)?; + let schema = stock.schema(info.schema_id)?; + Ok(match schema.iimpls.len() { + 0 => { + eprintln!("contract doesn't implement any interface and thus can't be read"); + ControlFlow::Break(()) + } + 1 => ControlFlow::Continue( + schema + .iimpls + .first_key_value() + .expect("one interface is present") + .0 + .clone(), + ), + _ => { + eprintln!( + "contract implements multiple interface, please select one of them to read the \ + contract:" + ); + for iface in schema.iimpls.keys() { + eprintln!("{iface}"); + } + ControlFlow::Break(()) + } + }) +} diff --git a/cli/src/main.rs b/cli/src/main.rs index 8475d3a..3d94c02 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -63,5 +63,7 @@ fn run() -> Result<(), WalletError> { let conf = Config::load(&args.conf_path("rgb")); debug!("Executing command: {:?}", args.command); - args.exec(conf, "rgb") + args.exec(conf, "rgb")?; + println!(); + Ok(()) } diff --git a/examples/rgb20-demo.con b/examples/rgb20-demo.con index a6abe6f..bfeef2c 100644 --- a/examples/rgb20-demo.con +++ b/examples/rgb20-demo.con @@ -1,25 +1,34 @@ -contract Test: RGB20 - spec: - "TEST" "Test Asset" centiMicro - terms: - """ - SUBJECT TO, AND WITHOUT IN ANY WAY LIMITING, THE REPRESENTATIONS AND WARRANTIES OF ANY SELLER - EXPRESSLY SET FORTH IN THIS AGREEMENT OR ANY OTHER EXPRESS OBLIGATION OF SELLERS PURSUANT TO THE - TERMS HEREOF, AND ACKNOWLEDGING THE PRIOR USE OF THE PROPERTY AND PURCHASER’S OPPORTUNITY - TO INSPECT THE PROPERTY, PURCHASER AGREES TO PURCHASE THE PROPERTY “AS IS”, “WHERE IS”, - WITH ALL FAULTS AND CONDITIONS THEREON. ANY WRITTEN OR ORAL INFORMATION, REPORTS, STATEMENTS, - DOCUMENTS OR RECORDS CONCERNING THE PROPERTY PROVIDED OR MADE AVAILABLE TO PURCHASER, ITS AGENTS - OR CONSTITUENTS BY ANY SELLER, ANY SELLER’S AGENTS, EMPLOYEES OR THIRD PARTIES REPRESENTING OR - PURPORTING TO REPRESENT ANY SELLER, SHALL NOT BE REPRESENTATIONS OR WARRANTIES, UNLESS - SPECIFICALLY SET FORTH HEREIN. IN PURCHASING THE PROPERTY OR TAKING OTHER ACTION HEREUNDER, - PURCHASER HAS NOT AND SHALL NOT RELY ON ANY SUCH DISCLOSURES, BUT RATHER, PURCHASER SHALL RELY - ONLY ON PURCHASER’S OWN INSPECTION OF THE PROPERTY AND THE REPRESENTATIONS AND WARRANTIES - HEREIN. PURCHASER ACKNOWLEDGES THAT THE PURCHASE PRICE REFLECTS AND TAKES INTO ACCOUNT THAT THE - PROPERTY IS BEING SOLD “AS IS”. - """ +contract Test: NonInflatableAsset + global spec + ticker = "Demo", + name = "Demo asset" + details = "Pay attention: the asset has no value" + precision = centiMicro - issuedSupply: + global terms + text = """ + SUBJECT TO, AND WITHOUT IN ANY WAY LIMITING, THE REPRESENTATIONS AND WARRANTIES OF ANY SELLER + EXPRESSLY SET FORTH IN THIS AGREEMENT OR ANY OTHER EXPRESS OBLIGATION OF SELLERS PURSUANT TO THE + TERMS HEREOF, AND ACKNOWLEDGING THE PRIOR USE OF THE PROPERTY AND PURCHASER’S OPPORTUNITY + TO INSPECT THE PROPERTY, PURCHASER AGREES TO PURCHASE THE PROPERTY “AS IS”, “WHERE IS”, + WITH ALL FAULTS AND CONDITIONS THEREON. ANY WRITTEN OR ORAL INFORMATION, REPORTS, STATEMENTS, + DOCUMENTS OR RECORDS CONCERNING THE PROPERTY PROVIDED OR MADE AVAILABLE TO PURCHASER, ITS AGENTS + OR CONSTITUENTS BY ANY SELLER, ANY SELLER’S AGENTS, EMPLOYEES OR THIRD PARTIES REPRESENTING OR + PURPORTING TO REPRESENT ANY SELLER, SHALL NOT BE REPRESENTATIONS OR WARRANTIES, UNLESS + SPECIFICALLY SET FORTH HEREIN. IN PURCHASING THE PROPERTY OR TAKING OTHER ACTION HEREUNDER, + PURCHASER HAS NOT AND SHALL NOT RELY ON ANY SUCH DISCLOSURES, BUT RATHER, PURCHASER SHALL RELY + ONLY ON PURCHASER’S OWN INSPECTION OF THE PROPERTY AND THE REPRESENTATIONS AND WARRANTIES + HEREIN. PURCHASER ACKNOWLEDGES THAT THE PURCHASE PRICE REFLECTS AND TAKES INTO ACCOUNT THAT THE + PROPERTY IS BEING SOLD “AS IS”. + """ + media = ~ + + global issuedSupply 1_000_000__000_000_00 - assetOwner: - 1_000_000__000_000_00 tapret1st:01d46e52c4bdb51931a0eae83e958c78bdef9cac2057b36d55370410edafdd42:0 + owned assetOwner + state = 1_000_000__000_000_00 + seal = + method := tapret1st + txid = #01d46e52c4bdb51931a0eae83e958c78bdef9cac2057b36d55370410edafdd42 + vout = 0 diff --git a/examples/rgb20-demo.rgb b/examples/rgb20-demo.rgb index 1e777f5..0e2644a 100644 Binary files a/examples/rgb20-demo.rgb and b/examples/rgb20-demo.rgb differ diff --git a/examples/rgb20-demo.rgba b/examples/rgb20-demo.rgba new file mode 100644 index 0000000..e8bd385 --- /dev/null +++ b/examples/rgb20-demo.rgba @@ -0,0 +1,120 @@ +-----BEGIN RGB CONSIGNMENT----- +Id: rgb:csg:qX!1P1VF-il9DLFx-yjcpNvH-31pdCbd-gXhPSiG-7hvhtYY#austria-ricardo-demand +Version: 2 +Type: contract +Contract: rgb:Dl4Difx7-VxSWda4-Bv!Z89y-CbiVUkF-0vIxjRy-vvqO77A +Schema: rgb:sch:RDYhMTR!9gv8Y2GLv9UNBEK1hcrCmdLDFk9Qd5fnO8k#brave-dinner-banana +Interface: RGB20Fixed +Check-SHA256: db958c5cca1988c753665fc9a3da383615cbea62f0e1e1e6d7a7add2539d17ec + +0ssI2002ZbAu%+5_6z)DVT-@j4Fp29h04O2(!&-{P^aZh38Qb#nm# +0iX|oIUs*Z=yeHROa_%`=El@tIJ|sRf`I8Lo365whq9yq1JDNn05|{xL_$XkL}g-iXCPs7b7gb^B~W2` +AYpWLWo~q7Z*DpubZBKDVRLh3bRcM9b0BVSAa-GFb!7t42LS+;1d;?(RYFQdLsTGCPb?roPDCJANmNKr +Ra78JP9Q-}Ss+(ISs+YFO-WQqPDd;tR7gc2QbkZwMN>siR6$fpPfk-HK~6* +Ss+tIOiV>mARt9pP*O!xQ%qSPQ$6cNl#87Peve9MNCXZQd1yMRZ>$`K~7X4R8JsONJSu2MN&;uAV@`0MNdX7AVE$w%R9PS(R8JsDPE$}tLsTGCNJSt}QcqAtQdC(iAW&6OLr6hWMN%L^M^Z&aQy^4NAW&6OLr6hWMIcm2 +MIca8Pf$ftR9PV6fSf^7AW2i=fSoKL;((l2NJUabAW2i=fSoKLAXiCLNFYH>Odv)tPf|flAW2R}Pf|@mR7p=xEFe-vP)|}+Q!F4;R6$fl +O+`*rQ!F4LL{CFiO+`*rQy@=LAW}s`Pf|ovAVW`1Lq$?fNlr%~R7gc2P*P7&MN(8*AW%|IR!KxfL?BO6 +AWcC;MIb>|K}k$OLQF*GpK~qIiEFei#Qy@V{MNU*xAWu>tLr+dqR7q4-MNU*xAVOInK~7m9 +Q$tR7gouL?BQ>QdCJrQy@}BP*O!x +MNU*nPDdb5QXo)OQczD)R7p-pAXHBvQbkZwMN>siR3Jf4Ss+tIOiV>mEFe=zK}<{_PES-ILPa1_MNm>j +Q$uAX899LrF$SLqSYTSs+tIR3JuAQdCGFNJUabNlq>x +NlqY8RZ>GpK~qUiM<7&4MIca8Pf$ftR9PTTQXo`8OG!>gAWu|CMN%L^LsUsmP9R7{QbkoxL`708AW&6O +Lr6hWMN%M0K~o@3PgEd5PDCJ6NI^_YAWlzIAW}t4Ss+hNAVE%9AX8OCNFYQ>Q$tKoQ&mz$Q!F4tRa78S +K~zXZQY;`)RZ>GpK~qIiAX7*|OiUnBMNC;BPfko(AWu#pP*qYxNI_FYQsRJ_Qy@=QP9RB6Q&2@iR7p=x +AWudhR7gc2P*P7&MN(8*AVE$4jM@3U0R7gQoAXG?2AW&6OLr6hWMIca8Nkc^-Qbk5gMMG3mAVE$kh3aTNI4>qw4obv;hDB01)TImdq$#?)UpynIxG +faxfkuCkJcvZMe200000000000000001{4bZb@!tY+-a^Vr*qWb8}^Mkc}T^00000GyrpRX*x_=Q!#aT +EoW*(Ic```MlDZcWpq_lYga8cax-;PLsK>_VNqyvIaf7iEjUU=H+KL7&<6n5{J!HJ@Tgs1mpj@U3yhwA +`^&{wC3iS1tkb=;A&LP3007Yk09%X4R5&sPN*yA;lp<^AQ;QQiCWsumMiT;fc;H-Y_W=L^+6MrLj96u3 +I`KP|x6K-jit^gQ+!PC!a#7jT+VjUz9FBwm0004?4*>`O00Ynm0RRC2(FXwl0RY+u0RRC20iX{70RR60 +0juzt(u?g--(Ch+6*7N1n=+qwe6YFx|MoP&lb}4dCJ6ul0T3qu00E#60RaF10iX{70RR600juzt(u?g- +-(Ch+6*7N1n=+qwe6YFx|MoP&lb}4dCIA2c00000000010SZz_LNYK$X?SI11XfR6o;2qj;#=~;t^vidEtAC%IlVX)dgF*wOtts}w(E1kon`A59t%UgjW&i*H0009FX>)UR +Wn@!zaBysS0f>xPWn((=JC(Q18jXtb+QHlu3zu?H+0@$e$59-PgaH5qb8uy20oVM#;~wy+U0;_w+8Yau +o__nw#aAVFI4rEwy|f{U0RaF7bY*gFa{*h6$5c2n1xg(vzLX+s=TnOlIwpu5x<(TMczEDkZ1({G0SaMr +b7gc-cWz~J0ssL4000033~6(7b!B8zb#QQOc>w?c00eVzWn%#V0RRPbWpZtE0RRC20SaMrb7gc-cWz~J +0RaF1009nZb8~fNWKC&vZDDj{XaNXxa$#Ze?--0RR613So0|Wpqz>Ze?-- +0RR600S|6(Zbfl*VQfKdZ*^{Ta{&rrb8}^MPj_x*asUAcbaG*Cb7p070uE_&b9H58O=)v&VRU0?WOH?J +aBO)Xb8uy2X=Z6#(b7gc-cWz~J00000009su2y}8`ZgXa3 +asU7T000624{mR6MR9duY(Z^rb#8QX000000S;+%b9H58O=)v&VRU0?00000GyrpRX*x_=Q!#aTEoW*( +Ic```MlDZcWpq_lYga8cax-;PLsK>_VNqyvIaf7iEjUU=H+KLd000X1U)Cjo-i6E2P9x&mnv%Qki+Oba +;k67*blZ=H=TQh>UMA(m1w0!?L{VGDpk+OvDhHAKF%fNXr25$w;Zs!r0000000007000000000O%am^t +lg}6qop{{FTg974FaQ3n`}K{nn9PGH_DcZ;0agu`_oR6wvcum54rF6FkJew+k!36?Lqfl$`8gF)R2-|n +!`LRkztQP;3W%Qi%!_9htpQ3t>=3qD6)+-@LI6MnH0sEektM3d!V}o +0nEa3l8<>f1KA&4t&LI4m}^5aI1iE}_s79eO?HmEkSbfMtWb&n35^vCNG$%?ywDnvz}K{0G9hl&cB^sg +-3J`2zr)xjz`xPycM6D}`pk=G7OeqFKI{;-SrsrMkU}5;FWB;W7bg;sK59Oe@c3K=fV3eR7p&1RS^QDd +q`TfM1OfmAZf|a7*gwADFAe3iZ1@l19{2t5VaJV^T`{fc?xMUvnKPbj0R(ezZDp`<(~tJj3|i&b2NlXO +R2^DUyWY#wQk^*F-L`Td370(4qMgjGn~{4aFkgwNr28QlFe*-S#jFZ=4d$x=UULI21Z8+*Y#{__VRL9B +24rt+Y+-UF17U4&CIoP7b#p5OWMOk?Edyk4bS?yXWpZyY18;6+F#~jWZ!!gRXmVv`GX!RDb#gQWW@&b1 +H3M^Lcs2!dWp-t5Hw9&BXJ~Xd1a4_=WjO_7VRB`3UIuJ$WMOk?UjboZ0b*hSV`BkiWC3Mm0cK_aXJ-Lu +XaQ+y0cvUiYij{)YyoX;0d8&qZ*Ku`Z~<{~0djHyb8`W7bOCjB0d{r)cXt7Jcma8N0eX5rD{{BQuNq?v +w$uLzi?1~hlkP@ao_$9uVE}^UN!R2B0b{Bo6zH)>$g+grvznd|(VVK)`s##^Jh_COk!RL4N<*rD#rE}N +PvxSnUK**8Le1-kltSZ7azFKgf3Y*(iUtA%ba`-Pu?^n-fFP~dpvnj-AyBKaJW)+{-ce}5$#DguerIN2 +24rbxWpi{YTdJ&3iT??W6$?l#{@A?G8j--)v|TbGZq;_HaqHbhw}2&v0mUY=J6lL$MhcKn;XgI|zJmp* +01;Q@0XT>R0ssVVZ*FDSKfd5E4dt|K_z&S8_xG@u4Q3HlB(d+LiLJm-R=h;`?dxC37Wb8ul}WgrA) +cw=lK261(7bY*iQ1ZZJ%Xd?z>Z)|K~awG?EWpZO>ZgeFHVQp|_a&uvBWF`t>aBp*Ta&K^GWhV$?a$#d@ +Wpqp^2x4+!V{2t}QYi>wb97~LX>)5T1aNG1b1Ma7Z*6U1ECp?8Zgq1l17vS>E(LRJVRL9N1bSt1Z!iOI +Ze=k8ba!tu1$1a~Wo0u2W^Z+JGz4a8c4ajKb7^=s1#@L~Wo|bGWoc(MgX1!He)Z*DpXb7gI5 +LvL(vZaV~QWpi^p1!Zw{VQf7IXL4m>bY*fr2yt~~b98BMZa)HHbU*@MK|umvLP7#xLqh^zL_`8#MMVN% +Mn(c(M@Ir*NJs)-Nl5}OG^S@OiTh_O-%w{PEG<}Pfr40P*4J2QBeY4Qc?n6Q&R$8R8#_ARaF9C +R#pOES62dGSXcsISy=*KT3QNoaYAxoV{2t}Oj`+JVPk7kY+-X~Tnck>LULhaYh`p&T?J!da%FU025fI+ +VRL9-2x4JlYjkO2YhVFkVF6-d0b^qUWMlzlWdUYp0cU3cXlMaxX#r|#0c&dkY-|B-Z2@j>0dH>saBu-} +aRG920dsQ!baVlAbpdvE0e5!+cz6MMc>#KQ31dQXVPk7$bWD2$aA|O5dyr3U)7OiEGa`mzoq#(6;V_O`>9xR8a*>q2D50xZ(4$R31H0PIsUw_;fcDKIn~;D +0000000000|Nj6000000TX!suv0v9m0LPL+_79KRH|I99{YEOV7tT#ZPWpkW1p!`O$dXTU&2q#dT$Zax +d1hGe8*-eZ2I646q$?$f9S>WJ$5c2n1xg(vzLX+s=TnOlIwpu5x<(TMczEDkZ1)BN1axJ1bQsH&ZxWNw +7!I9y+{RnQn@2DI{;m7Md`c4>2IVr*pq1Y~7nX#oXeWo~q70tIbpY;0)*31nqsX-#QtY-t1vV`Xl1X-#QtY-t4rZE0h2 +Zw3iuWn*bgX=8G42MS|lZggo)X=8G42n23nZf^+)WMyM%PGN3u3JGInZggo*VQy~=1aN6%Zwv@zWn*bj +X=85<31ek$bZJm&V{Z-xW@T-3Zx0D%Wn*bZWo>kC5DH^uZggozWo>kC5d>j$bZ-(~UdWP9bIo$ZB3zcM +M|oyg?;CQQqXyz&yre57i5(9G0)iue^mXvL0b>G|!V30Z)+K@7h0D=S +BjVedlDqGVd368bwG2#j+mD9lQD0sr<;4X&8%0D>TgISeJ)kNFk^3Xf*%skbRRcZ*dS!BNFavLH +WibPEcW*KUbZByAWite3Z*_7s1ZHV=WiUrS2@UrbB_UrkK{UrtT}Ur$d0Ur8 +UsO~AUsY8CUshHEUsqQGUszZIUs+iKUs_rLVPOGcVgX}g0c2zWWn}?oW&vks0cdCeX=wp!Y5{9&0c>mm +ZEXQ=ZUJv^0dQ~uad821ashL50d#Z$b#(!Db^&*H0eE-;d3gbPdSj|16zH)>$g+grvznd|(VVK)`s##^ +Jh_COk!RL4N(lR@SaKRYGgJn%Xv1$>f_VvG%;GuzyszPjx|liD+IRr~000000093000000004kq#k^Az +$U%@qU7>2Bz={du0O&G0&#r1CLJBFZ06hf(#5#SRxw8U!bIFfg*5RxK^~=*jK)}Ad3JOG^S@OiTh_O-%w{PEG<}Pfr40P*4J2QBeY4Qc?n6Q&R$8R8#_ARaF9CR#pOES62dGSXcsI +Sy=*KT3P{NVF6-d0b^qUWMlzlWdUYp0cU3cXlMaxX#r|#0c&dkY-|B-Z2@j>0dH>saBu-}aRG920dsQ! +baVlAbpdvE0e5!+cz6MMc>#KQh>TceV>4NmyOwH13hJ +J{u?^n-fFP~dpvnj-AyBKaJW)+{-ce}5$#DguerIN21_K0id2nSM +uyu|U!T^j90F36+)E=H0H{s0>nH0sEektM3d!V}qb9G{Ld2nSf*z$T8ClZi8YCe|m_*?{lv>_T7tkE!8 +{87}TyWT7ZV`yP=b7gcd*z$T8ClZi8YCe|m_*?{lv>_T7tkE!8{87}TyWT9nkIU)BIae{Jw9R4r0N>}O +)+shqImKG);D@8R3aUm3Jkg?^%&nV|dnPbniKwLeAs8?!PIJYq3V03Xs{mee0000000000KL7v#00000 +#5#SRxw8U!bIFfg*5RxK^~=*jK)}Ad3JH<(%oY0=TGqa6l5KfYJkC@$v(fAa&d%-e7ws4kFK+d0H97bAybczVb@xPq-Dzr4oJgUK7Oif +U&jRjKPz&##IG7-47St%2#c>Z5R>jkTb_MKDq#SEVo@@XB+#WAdR)2C|*D$SwhJOvD$-0{Gfin@` +^Yz +>$s@6fa*%L>wyFU00eGtZe`d%zThtn<+N=058)p7{qSMOjh9_9t?BNfyg->Vo@@aGb8l^B+#WAdR)2C| +*D$SwhJOvD$-0{Gfin@`G@u4Q3HlB(d+LiLJm-R=h;`?dxBvhE0000004D$d000000QnaP1l_I#dHB_@bgMhk0_N&La@nc5 +HwP6O+keCip#vHLVPOGcVgX}g0c2zWWn}?oW&vks0cdCeX=wp!Y5{9&0c>mmZEXQ=ZUJv^0dQ~uad821 +ashL50d#Z$b#(!Db^&*H0eE-;d3gbPdi$wZavD7|R0gwX!*5!Gc?n?5;yM1jui=Thm^szjcmV+b0|P-! +RR}^*L`g?QQ&a;|M?xV03jhEB(4Y?i2MYiJ01F5J01E*E0La=00XZ-L(V!0j2Lu2B0RR910000 + +-----END RGB CONSIGNMENT----- + + diff --git a/examples/rgb20-demo.yaml b/examples/rgb20-demo.yaml index 6938c47..575c6d7 100644 --- a/examples/rgb20-demo.yaml +++ b/examples/rgb20-demo.yaml @@ -2,8 +2,8 @@ interface: RGB20Fixed globals: spec: - ticker: DBG - name: Debug asset + ticker: DEMO + name: Demo asset details: "Pay attention: the asset has no value" precision: 2 terms: @@ -26,5 +26,5 @@ globals: assignments: assetOwner: - seal: tapret1st:fb9ae7ae4b70a27e7fdfdefac91b37967b549d65007dbf25470b0817a2ae810a:1 + seal: tapret1st:b449f7eaa3f98c145b27ad0eeb7b5679ceb567faef7a52479bc995792b65f804:1 amount: 100000000 # this is 1 million (we have two digits for cents) diff --git a/psbt/Cargo.toml b/psbt/Cargo.toml index 90b7712..0771446 100644 --- a/psbt/Cargo.toml +++ b/psbt/Cargo.toml @@ -23,7 +23,6 @@ commit_verify = { workspace = true } strict_encoding = { workspace = true } bp-core = { workspace = true } bp-std = { workspace = true } -psbt = { workspace = true } rgb-std = { workspace = true } [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -37,7 +36,7 @@ wasm-bindgen-test = "0.3" [features] default = [] all = ["serde"] -serde = ["bp-core/serde", "bp-std/serde", "psbt/serde", "rgb-std/serde"] +serde = ["bp-core/serde", "bp-std/serde", "rgb-std/serde"] [package.metadata.docs.rs] features = ["all"] diff --git a/psbt/src/lib.rs b/psbt/src/lib.rs index 551ccc9..ad736c4 100644 --- a/psbt/src/lib.rs +++ b/psbt/src/lib.rs @@ -26,7 +26,7 @@ mod rgb; use bp::dbc::opret::OpretProof; use bp::dbc::tapret::TapretProof; -pub use psbt::*; +pub use bpstd::psbt::*; pub use rgb::*; use rgbstd::containers::{AnchorSet, Batch, CloseMethodSet, Fascia, PubWitness, XPubWitness}; use rgbstd::XChain; diff --git a/psbt/src/rgb.rs b/psbt/src/rgb.rs index 08a4797..0a1f14d 100644 --- a/psbt/src/rgb.rs +++ b/psbt/src/rgb.rs @@ -25,8 +25,9 @@ use amplify::confinement::{Confined, SmallOrdMap, U24}; use amplify::{confinement, FromSliceError}; use bp::dbc::Method; use bp::seals::txout::CloseMethod; +use bpstd::psbt; +use bpstd::psbt::{KeyAlreadyPresent, KeyMap, MpcPsbtError, PropKey, Psbt}; use commit_verify::mpc; -use psbt::{KeyAlreadyPresent, KeyMap, MpcPsbtError, PropKey, Psbt}; use rgbstd::containers::{BundleDichotomy, VelocityHint}; use rgbstd::{ ContractId, InputMap, MergeReveal, MergeRevealError, OpId, Operation, Transition, @@ -417,7 +418,11 @@ pub trait RgbOutExt { impl RgbOutExt for psbt::Output { fn rgb_velocity_hint(&self) -> Option { let data = self.proprietary.get(&PropKey::rgb_out_velocity_hint())?; - if data.len() != 1 { None } else { data.first().map(VelocityHint::with_value) } + if data.len() != 1 { + None + } else { + data.first().map(VelocityHint::with_value) + } } fn set_rgb_velocity_hint(&mut self, hint: VelocityHint) -> bool { diff --git a/src/descriptor.rs b/src/descriptor.rs index b695f60..103eee2 100644 --- a/src/descriptor.rs +++ b/src/descriptor.rs @@ -30,12 +30,12 @@ use bp::dbc::Method; use bp::seals::txout::CloseMethod; use bp::{LegacyPk, SigScript, Witness}; use bpstd::{ - Derive, DeriveCompr, DeriveSet, DeriveXOnly, DerivedScript, Idx, IdxBase, IndexError, - IndexParseError, KeyOrigin, Keychain, NormalIndex, TapDerivation, TapScript, TapTree, Terminal, - XOnlyPk, XpubAccount, XpubDerivable, + Derive, DeriveCompr, DeriveSet, DeriveXOnly, DerivedScript, Descriptor, Idx, IdxBase, + IndexError, IndexParseError, KeyOrigin, Keychain, LegacyKeySig, NormalIndex, SpkClass, + StdDescr, TapDerivation, TapScript, TapTree, TaprootKeySig, Terminal, TrKey, Wpkh, XOnlyPk, + XpubAccount, XpubDerivable, }; use commit_verify::CommitVerify; -use descriptors::{Descriptor, LegacyKeySig, SpkClass, StdDescr, TaprootKeySig, TrKey, Wpkh}; use indexmap::IndexMap; #[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)] diff --git a/src/errors.rs b/src/errors.rs index 70bfce9..72d32b8 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -34,7 +34,7 @@ use rgbstd::persistence::{ ComposeError, ConsignError, ContractIfaceError, FasciaError, Stock, StockError, StockErrorAll, StockErrorMem, }; -use strict_types::encoding::{DeserializeError, Ident, SerializeError}; +use strict_types::encoding::Ident; use crate::{validation, TapTweakAlreadyAssigned}; @@ -43,13 +43,7 @@ use crate::{validation, TapTweakAlreadyAssigned}; pub enum WalletError { #[from] #[from(io::Error)] - Io(IoError), - - #[from] - Serialize(SerializeError), - - #[from] - Deserialize(DeserializeError), + File(IoError), #[from] StockLoad(LoadError), @@ -60,17 +54,16 @@ pub enum WalletError { #[cfg(feature = "cli")] #[from] - WalletExect(bpwallet::cli::ExecError), + WalletExec(bpwallet::cli::ExecError), #[from] Builder(BuilderError), - #[from] - History(HistoryError), - #[from] Contract(ContractError), + Invoicing(String), + #[from] PsbtDecode(psrgbt::DecodeError), @@ -118,17 +111,6 @@ impl From<(Stock, WalletError)> for WalletError { fn from((_, e): (Stock, WalletError)) -> Self { e } } -#[derive(Debug, Display, Error, From)] -#[display(doc_comments)] -pub enum HistoryError { - /// interface doesn't define default operation - NoDefaultOp, - /// default operation defined by the interface is not a state transition - DefaultOpNotTransition, - /// interface doesn't define default fungible state - NoDefaultAssignment, -} - #[allow(clippy::large_enum_variant)] #[derive(Debug, Display, Error, From)] pub enum PayError { diff --git a/src/filters.rs b/src/filters.rs new file mode 100644 index 0000000..2cdbd44 --- /dev/null +++ b/src/filters.rs @@ -0,0 +1,85 @@ +// RGB wallet library for smart contracts on Bitcoin & Lightning network +// +// SPDX-License-Identifier: Apache-2.0 +// +// Written in 2019-2023 by +// Dr Maxim Orlovsky +// +// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use bp::Bp; +use bpwallet::{Layer2, Wallet}; +use rgbstd::interface::AssignmentsFilter; + +use crate::{DescriptorRgb, XChain, XOutpoint, XWitnessId}; + +pub struct WalletOutpointsFilter<'a, K, D: DescriptorRgb, L2: Layer2>(pub &'a Wallet); + +// We need manual derivation to ensure we can be copied and cloned even if descriptor is not +// copyable/clonable. +impl<'a, K, D: DescriptorRgb, L2: Layer2> Copy for WalletOutpointsFilter<'a, K, D, L2> {} +impl<'a, K, D: DescriptorRgb, L2: Layer2> Clone for WalletOutpointsFilter<'a, K, D, L2> { + fn clone(&self) -> Self { *self } +} + +impl<'a, K, D: DescriptorRgb, L2: Layer2> AssignmentsFilter + for WalletOutpointsFilter<'a, K, D, L2> +{ + fn should_include(&self, output: impl Into, _: Option) -> bool { + match output.into().into_bp() { + Bp::Bitcoin(outpoint) => self.0.has_outpoint(outpoint), + Bp::Liquid(_) => false, + } + } +} + +pub struct WalletUnspentFilter<'a, K, D: DescriptorRgb, L2: Layer2>(pub &'a Wallet); + +// We need manual derivation to ensure we can be copied and cloned even if descriptor is not +// copyable/clonable. +impl<'a, K, D: DescriptorRgb, L2: Layer2> Copy for WalletUnspentFilter<'a, K, D, L2> {} +impl<'a, K, D: DescriptorRgb, L2: Layer2> Clone for WalletUnspentFilter<'a, K, D, L2> { + fn clone(&self) -> Self { *self } +} + +impl<'a, K, D: DescriptorRgb, L2: Layer2> AssignmentsFilter + for WalletUnspentFilter<'a, K, D, L2> +{ + fn should_include(&self, output: impl Into, _: Option) -> bool { + match output.into().into_bp() { + Bp::Bitcoin(outpoint) => self.0.is_unspent(outpoint), + Bp::Liquid(_) => false, + } + } +} + +pub struct WalletWitnessFilter<'a, K, D: DescriptorRgb, L2: Layer2>(pub &'a Wallet); + +// We need manual derivation to ensure we can be copied and cloned even if descriptor is not +// copyable/clonable. +impl<'a, K, D: DescriptorRgb, L2: Layer2> Copy for WalletWitnessFilter<'a, K, D, L2> {} +impl<'a, K, D: DescriptorRgb, L2: Layer2> Clone for WalletWitnessFilter<'a, K, D, L2> { + fn clone(&self) -> Self { *self } +} + +impl<'a, K, D: DescriptorRgb, L2: Layer2> AssignmentsFilter + for WalletWitnessFilter<'a, K, D, L2> +{ + fn should_include(&self, _: impl Into, witness_id: Option) -> bool { + self.0 + .history() + .any(|row| !row.our_inputs.is_empty() && witness_id == Some(XChain::Bitcoin(row.txid))) + } +} diff --git a/src/indexers/electrum_blocking.rs b/src/indexers/electrum_blocking.rs index 599d369..98aad72 100644 --- a/src/indexers/electrum_blocking.rs +++ b/src/indexers/electrum_blocking.rs @@ -22,10 +22,12 @@ // limitations under the License. use std::iter; +use std::num::NonZeroU32; use bp::ConsensusDecode; use bpstd::{Network, Tx, Txid}; -use electrum::{Client, ElectrumApi, Error, Param}; +use electrum::{Client, ElectrumApi, Param}; +pub use electrum::{Config, ConfigBuilder, Error, Socks5Config}; use rgbstd::vm::WitnessPos; use super::RgbResolver; @@ -93,21 +95,17 @@ impl RgbResolver for Client { let Some(confirmations) = tx_details.get("confirmations") else { return Ok(WitnessOrd::Tentative); }; - let confirmations = check!( - confirmations - .as_u64() - .and_then(|x| u32::try_from(x).ok()) - .ok_or(Error::InvalidResponse(tx_details.clone())) - ); + let confirmations = check!(confirmations + .as_u64() + .and_then(|x| u32::try_from(x).ok()) + .ok_or(Error::InvalidResponse(tx_details.clone()))); if confirmations == 0 { return Ok(WitnessOrd::Tentative); } - let block_time = check!( - tx_details - .get("blocktime") - .and_then(|v| v.as_i64()) - .ok_or(Error::InvalidResponse(tx_details.clone())) - ); + let block_time = check!(tx_details + .get("blocktime") + .and_then(|v| v.as_i64()) + .ok_or(Error::InvalidResponse(tx_details.clone()))); let tip_height = u32::try_from(header.height).map_err(|_| s!("impossible height value"))?; let height: isize = (tip_height - confirmations) as isize; @@ -123,10 +121,10 @@ impl RgbResolver for Client { let tx_height = u32::try_from(get_merkle_res.block_height) .map_err(|_| s!("impossible height value"))?; - let pos = check!( - WitnessPos::new(tx_height, block_time) - .ok_or(Error::InvalidResponse(tx_details.clone())) - ); + let height = + check!(NonZeroU32::new(tx_height).ok_or(Error::InvalidResponse(tx_details.clone()))); + let pos = check!(WitnessPos::bitcoin(height, block_time) + .ok_or(Error::InvalidResponse(tx_details.clone()))); Ok(WitnessOrd::Mined(pos)) } diff --git a/src/indexers/esplora_blocking.rs b/src/indexers/esplora_blocking.rs index 9b25ebd..e72e2fa 100644 --- a/src/indexers/esplora_blocking.rs +++ b/src/indexers/esplora_blocking.rs @@ -19,9 +19,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::num::NonZeroU32; + use bp::Tx; use bpstd::{Network, Txid}; -use esplora::{BlockingClient, Error}; +use esplora::BlockingClient; +pub use esplora::{Builder, Config, Error}; use rgbstd::vm::WitnessPos; use super::RgbResolver; @@ -47,7 +50,10 @@ impl RgbResolver for BlockingClient { .and_then(|h| status.block_time.map(|t| (h, t))) { Some((h, t)) => { - WitnessOrd::Mined(WitnessPos::new(h, t as i64).ok_or(Error::InvalidServerData)?) + let height = NonZeroU32::new(h).ok_or(Error::InvalidServerData)?; + WitnessOrd::Mined( + WitnessPos::bitcoin(height, t as i64).ok_or(Error::InvalidServerData)?, + ) } None => WitnessOrd::Tentative, }; diff --git a/src/lib.rs b/src/lib.rs index 7dd5e57..d37fcf1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,19 +27,35 @@ extern crate serde_crate as serde; mod descriptor; mod indexers; -mod wrapper; +mod filters; pub mod pay; mod errors; mod wallet; pub use descriptor::{DescriptorRgb, RgbDescr, RgbKeychain, TapTweakAlreadyAssigned, TapretKey}; -pub use errors::{CompletionError, CompositionError, HistoryError, PayError, WalletError}; +pub use errors::{CompletionError, CompositionError, PayError, WalletError}; pub use pay::{TransferParams, WalletProvider}; pub use rgbstd::*; pub mod resolvers { #[cfg(any(feature = "electrum_blocking", feature = "esplora_blocking"))] pub use super::indexers::*; pub use super::indexers::{AnyResolver, RgbResolver}; + use super::validation::{ResolveWitness, WitnessResolverError}; + use super::vm::{WitnessOrd, XWitnessTx}; + use super::XWitnessId; + + pub struct ContractIssueResolver; + impl ResolveWitness for ContractIssueResolver { + fn resolve_pub_witness(&self, _: XWitnessId) -> Result { + panic!("contract issue resolver must not be used for an already-existing contracts") + } + fn resolve_pub_witness_ord( + &self, + _: XWitnessId, + ) -> Result { + panic!("contract issue resolver must not be used for an already-existing contracts") + } + } } +pub use filters::{WalletOutpointsFilter, WalletUnspentFilter, WalletWitnessFilter}; pub use wallet::RgbWallet; -pub use wrapper::WalletWrapper; diff --git a/src/pay.rs b/src/pay.rs index 3d7374c..43fc017 100644 --- a/src/pay.rs +++ b/src/pay.rs @@ -26,13 +26,13 @@ use bp::dbc::tapret::TapretProof; use bp::seals::txout::ExplicitSeal; use bp::{Outpoint, Sats, ScriptPubkey, Vout}; use bpstd::{psbt, Address}; -use bpwallet::{Wallet, WalletDescr}; +use bpwallet::{Layer2, Layer2Tx, NoLayer2, TxRow, Wallet, WalletDescr}; use psrgbt::{ Beneficiary as BpBeneficiary, Psbt, PsbtConstructor, PsbtMeta, RgbPsbt, TapretKeyError, TxParams, }; use rgbstd::containers::Transfer; -use rgbstd::interface::OutpointFilter; +use rgbstd::interface::AssignmentsFilter; use rgbstd::invoice::{Amount, Beneficiary, InvoiceState, RgbInvoice}; use rgbstd::persistence::{IndexProvider, StashProvider, StateProvider, Stock}; use rgbstd::validation::ResolveWitness; @@ -41,9 +41,9 @@ use rgbstd::{ContractId, DataState, XChain, XOutpoint}; use crate::invoice::NonFungible; use crate::validation::WitnessResolverError; use crate::vm::{WitnessOrd, XWitnessTx}; -use crate::wrapper::WalletWrapper; use crate::{ - CompletionError, CompositionError, DescriptorRgb, PayError, RgbKeychain, Txid, XWitnessId, + CompletionError, CompositionError, DescriptorRgb, PayError, RgbKeychain, Txid, + WalletOutpointsFilter, WalletUnspentFilter, WalletWitnessFilter, XWitnessId, }; #[derive(Clone, PartialEq, Debug)] @@ -64,51 +64,56 @@ impl TransferParams { struct ContractOutpointsFilter< 'stock, 'wallet, - W: WalletProvider + ?Sized, + W: WalletProvider + ?Sized, K, S: StashProvider, H: StateProvider, P: IndexProvider, + L2: Layer2 = NoLayer2, > where W::Descr: DescriptorRgb { contract_id: ContractId, stock: &'stock Stock, wallet: &'wallet W, - _phantom: PhantomData, + _key_phantom: PhantomData, + _layer2_phantom: PhantomData, } impl< - 'stock, - 'wallet, - W: WalletProvider + ?Sized, - K, - S: StashProvider, - H: StateProvider, - P: IndexProvider, -> OutpointFilter for ContractOutpointsFilter<'stock, 'wallet, W, K, S, H, P> + 'stock, + 'wallet, + W: WalletProvider + ?Sized, + K, + S: StashProvider, + H: StateProvider, + P: IndexProvider, + L2: Layer2, + > AssignmentsFilter for ContractOutpointsFilter<'stock, 'wallet, W, K, S, H, P, L2> where W::Descr: DescriptorRgb { - fn include_outpoint(&self, output: impl Into) -> bool { + fn should_include(&self, output: impl Into, id: Option) -> bool { let output = output.into(); - if !self.wallet.filter().include_outpoint(output) { + if !self.wallet.filter_unspent().should_include(output, id) { return false; } matches!(self.stock.contract_assignments_for(self.contract_id, [output]), Ok(list) if !list.is_empty()) } } -pub trait WalletProvider: PsbtConstructor +pub trait WalletProvider: PsbtConstructor where Self::Descr: DescriptorRgb { - type Filter<'a>: Copy + OutpointFilter - where Self: 'a; - fn filter(&self) -> Self::Filter<'_>; + fn filter_outpoints(&self) -> impl AssignmentsFilter + Clone; + fn filter_unspent(&self) -> impl AssignmentsFilter + Clone; + fn filter_witnesses(&self) -> impl AssignmentsFilter + Clone; fn with_descriptor_mut( &mut self, - f: impl FnOnce(&mut WalletDescr) -> R, + f: impl FnOnce(&mut WalletDescr) -> R, ) -> R; - fn outpoints(&self) -> impl Iterator; + fn utxos(&self) -> impl Iterator; + fn txos(&self) -> impl Iterator; fn txids(&self) -> impl Iterator; + fn history(&self) -> impl Iterator> + '_; // TODO: Add method `color` to add RGB information to an already existing PSBT @@ -162,7 +167,8 @@ where Self::Descr: DescriptorRgb contract_id, stock, wallet: self, - _phantom: PhantomData, + _key_phantom: PhantomData, + _layer2_phantom: PhantomData, }; let contract = stock .contract_iface(contract_id, iface_name) @@ -350,14 +356,19 @@ where Self::Descr: DescriptorRgb } } -impl> WalletProvider for Wallet { - type Filter<'a> = WalletWrapper<'a, K, D> - where - Self: 'a; - fn filter(&self) -> Self::Filter<'_> { WalletWrapper(self) } - fn with_descriptor_mut(&mut self, f: impl FnOnce(&mut WalletDescr) -> R) -> R { +impl, L2: Layer2> WalletProvider for Wallet { + fn filter_outpoints(&self) -> impl AssignmentsFilter + Clone { WalletOutpointsFilter(self) } + fn filter_unspent(&self) -> impl AssignmentsFilter + Clone { WalletUnspentFilter(self) } + fn filter_witnesses(&self) -> impl AssignmentsFilter + Clone { WalletWitnessFilter(self) } + fn with_descriptor_mut( + &mut self, + f: impl FnOnce(&mut WalletDescr) -> R, + ) -> R { self.descriptor_mut(f) } - fn outpoints(&self) -> impl Iterator { self.coins().map(|coin| coin.outpoint) } + fn utxos(&self) -> impl Iterator { self.coins().map(|coin| coin.outpoint) } + fn txos(&self) -> impl Iterator { self.txos().map(|txo| txo.outpoint) } fn txids(&self) -> impl Iterator { self.transactions().keys().copied() } + + fn history(&self) -> impl Iterator> + '_ { self.history() } } diff --git a/src/wallet.rs b/src/wallet.rs index 0041360..172c82b 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -19,7 +19,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::HashMap; use std::marker::PhantomData; #[cfg(feature = "fs")] use std::path::PathBuf; @@ -29,41 +28,46 @@ use bpstd::XpubDerivable; use bpwallet::fs::FsTextStore; #[cfg(feature = "fs")] use bpwallet::Wallet; +use bpwallet::{Layer2, NoLayer2}; #[cfg(not(target_arch = "wasm32"))] use nonasync::persistence::PersistenceProvider; use psrgbt::{Psbt, PsbtMeta}; use rgbstd::containers::Transfer; -use rgbstd::interface::{AmountChange, IfaceOp, IfaceRef}; +use rgbstd::interface::{ContractOp, IfaceRef}; #[cfg(feature = "fs")] use rgbstd::persistence::fs::FsBinStore; use rgbstd::persistence::{ - IndexProvider, MemIndex, MemStash, MemState, StashProvider, StateProvider, Stock, + ContractIfaceError, IndexProvider, MemIndex, MemStash, MemState, StashProvider, StateProvider, + Stock, StockError, }; use super::{ - CompletionError, CompositionError, ContractId, DescriptorRgb, HistoryError, PayError, - TransferParams, WalletError, WalletProvider, XWitnessId, + CompletionError, CompositionError, ContractId, DescriptorRgb, PayError, TransferParams, + WalletError, WalletProvider, }; use crate::invoice::RgbInvoice; #[derive(Getters)] pub struct RgbWallet< - W: WalletProvider, + W: WalletProvider, K = XpubDerivable, S: StashProvider = MemStash, H: StateProvider = MemState, P: IndexProvider = MemIndex, + L2: Layer2 = NoLayer2, > where W::Descr: DescriptorRgb { stock: Stock, wallet: W, #[getter(skip)] - _phantom: PhantomData, + _key_phantom: PhantomData, + #[getter(skip)] + _layer2_phantom: PhantomData, } #[cfg(feature = "fs")] -impl, S: StashProvider, H: StateProvider, P: IndexProvider> - RgbWallet, K, S, H, P> +impl, S: StashProvider, H: StateProvider, P: IndexProvider, L2: Layer2> + RgbWallet, K, S, H, P, L2> { #[allow(clippy::result_large_err)] pub fn load( @@ -73,31 +77,46 @@ impl, S: StashProvider, H: StateProvider, P: IndexProvide ) -> Result where D: serde::Serialize + for<'de> serde::Deserialize<'de>, + L2::Descr: serde::Serialize + for<'de> serde::Deserialize<'de>, + L2::Data: serde::Serialize + for<'de> serde::Deserialize<'de>, + L2::Cache: serde::Serialize + for<'de> serde::Deserialize<'de>, FsBinStore: PersistenceProvider, FsBinStore: PersistenceProvider, FsBinStore: PersistenceProvider

, + FsTextStore: PersistenceProvider, { - let provider = FsBinStore::new(stock_path)?; + use nonasync::persistence::PersistenceError; + let provider = FsBinStore::new(stock_path) + .map_err(|e| WalletError::StockPersist(PersistenceError::with(e)))?; let stock = Stock::load(provider, autosave).map_err(WalletError::StockPersist)?; - let provider = FsTextStore::new(wallet_path)?; + let provider = FsTextStore::new(wallet_path) + .map_err(|e| WalletError::WalletPersist(PersistenceError::with(e)))?; let wallet = Wallet::load(provider, autosave).map_err(WalletError::WalletPersist)?; Ok(Self { wallet, stock, - _phantom: PhantomData, + _key_phantom: PhantomData, + _layer2_phantom: PhantomData, }) } } -impl, S: StashProvider, H: StateProvider, P: IndexProvider> - RgbWallet +impl< + K, + W: WalletProvider, + S: StashProvider, + H: StateProvider, + P: IndexProvider, + L2: Layer2, + > RgbWallet where W::Descr: DescriptorRgb { pub fn new(stock: Stock, wallet: W) -> Self { Self { stock, wallet, - _phantom: PhantomData, + _key_phantom: PhantomData, + _layer2_phantom: PhantomData, } } @@ -105,34 +124,14 @@ where W::Descr: DescriptorRgb pub fn wallet_mut(&mut self) -> &mut W { &mut self.wallet } - #[allow(clippy::result_large_err)] - pub fn fungible_history( + pub fn history( &self, contract_id: ContractId, iface: impl Into, - ) -> Result>, WalletError> { + ) -> Result, StockError> { + let contract = self.stock.contract_iface(contract_id, iface.into())?; let wallet = &self.wallet; - let iref = iface.into(); - let iface = self.stock.iface(iref.clone()).map_err(|e| e.to_string())?; - let default_op = iface - .default_operation - .as_ref() - .ok_or(HistoryError::NoDefaultOp)?; - let state_name = iface - .transitions - .get(default_op) - .ok_or(HistoryError::DefaultOpNotTransition)? - .default_assignment - .as_ref() - .ok_or(HistoryError::NoDefaultAssignment)? - .clone(); - let contract = self - .stock - .contract_iface(contract_id, iref) - .map_err(|e| e.to_string())?; - Ok(contract - .fungible_ops::(state_name, wallet.filter()) - .map_err(|e| e.to_string())?) + Ok(contract.history(wallet.filter_outpoints(), wallet.filter_witnesses())) } #[allow(clippy::result_large_err)] diff --git a/src/wrapper.rs b/src/wrapper.rs deleted file mode 100644 index fd46e1e..0000000 --- a/src/wrapper.rs +++ /dev/null @@ -1,41 +0,0 @@ -// RGB wallet library for smart contracts on Bitcoin & Lightning network -// -// SPDX-License-Identifier: Apache-2.0 -// -// Written in 2019-2023 by -// Dr Maxim Orlovsky -// -// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use bpwallet::Wallet; -use rgbstd::interface::OutpointFilter; - -use crate::{DescriptorRgb, WalletProvider, XChain, XOutpoint}; - -pub struct WalletWrapper<'a, K, D: DescriptorRgb>(pub &'a Wallet); - -impl<'a, K, D: DescriptorRgb> Copy for WalletWrapper<'a, K, D> {} -impl<'a, K, D: DescriptorRgb> Clone for WalletWrapper<'a, K, D> { - fn clone(&self) -> Self { *self } -} - -impl<'a, K, D: DescriptorRgb> OutpointFilter for WalletWrapper<'a, K, D> { - fn include_outpoint(&self, output: impl Into) -> bool { - let output = output.into(); - self.0 - .outpoints() - .any(|outpoint| XChain::Bitcoin(outpoint) == *output) - } -}