From 95e66c5297fa0222b9a29c2e9b4fe82edeae2e49 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 19 Mar 2021 16:00:01 +0100 Subject: [PATCH] Extracting LNP/BP invoices into separate library --- Cargo.lock | 681 +-------------------------------- Cargo.toml | 6 +- invoice/Cargo.toml | 68 ---- invoice/README.md | 18 - invoice/src/base.rs | 908 -------------------------------------------- invoice/src/lib.rs | 40 -- invoice/src/main.rs | 250 ------------ 7 files changed, 13 insertions(+), 1958 deletions(-) delete mode 100644 invoice/Cargo.toml delete mode 100644 invoice/README.md delete mode 100644 invoice/src/base.rs delete mode 100644 invoice/src/lib.rs delete mode 100644 invoice/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 021bf656..c53184b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,15 +8,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array 0.14.4", -] - [[package]] name = "aho-corasick" version = "0.7.15" @@ -37,7 +28,7 @@ dependencies = [ "serde_json", "serde_yaml", "stringly_conversions", - "toml 0.5.8", + "toml", ] [[package]] @@ -94,12 +85,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "base32" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" - [[package]] name = "base58" version = "0.1.0" @@ -157,34 +142,13 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", + "generic-array", ] [[package]] @@ -193,24 +157,12 @@ version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "bytes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16" - [[package]] name = "cc" version = "1.0.67" @@ -223,29 +175,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha20" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed8738f14471a99f0e316c327e68fc82a3611cc2895fcb604b89eedaf8f39d95" -dependencies = [ - "cipher", - "zeroize 1.2.0", -] - -[[package]] -name = "chacha20poly1305" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1fc18e6d90c40164bf6c317476f2a98f04661e310e79830366b7e914c58a8e" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize 1.2.0", -] - [[package]] name = "chrono" version = "0.4.19" @@ -255,20 +184,10 @@ dependencies = [ "libc", "num-integer", "num-traits", - "serde", "time", "winapi 0.3.9", ] -[[package]] -name = "cipher" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array 0.14.4", -] - [[package]] name = "clap" version = "3.0.0-beta.2" @@ -334,37 +253,12 @@ dependencies = [ "bitflags", ] -[[package]] -name = "cmake" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855" -dependencies = [ - "cc", -] - [[package]] name = "cpuid-bool" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" -[[package]] -name = "cpuid-bool" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" - -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - [[package]] name = "curve25519-dalek" version = "3.0.2" @@ -372,9 +266,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f627126b946c25a4638eec0ea634fc52506dea98db118aae985118ce7c3d723f" dependencies = [ "byteorder", - "digest 0.9.0", + "digest", "rand_core 0.5.1", - "subtle 2.4.0", + "subtle", "zeroize 1.2.0", ] @@ -423,20 +317,6 @@ dependencies = [ "byteorder", ] -[[package]] -name = "derive_more" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" -dependencies = [ - "lazy_static", - "proc-macro2 0.4.30", - "quote 0.6.13", - "regex", - "rustc_version", - "syn 0.15.44", -] - [[package]] name = "descriptor-wallet" version = "0.4.0" @@ -457,22 +337,13 @@ dependencies = [ "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array", ] [[package]] @@ -500,7 +371,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2 0.9.3", + "sha2", "zeroize 1.2.0", ] @@ -520,64 +391,18 @@ dependencies = [ "webpki-roots", ] -[[package]] -name = "error-chain" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -645,33 +470,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hmac" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" -dependencies = [ - "crypto-mac", - "digest 0.8.1", -] - [[package]] name = "ident_case" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -[[package]] -name = "idna" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "indexmap" version = "1.6.2" @@ -682,37 +486,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "inet2_addr" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d17de954f78b83e7327701a1be5e67878691eaabf6b3d83c8f07db800759b0c" -dependencies = [ - "amplify", - "amplify_derive", - "ed25519-dalek", - "parse_arg", - "serde", - "serde_json", - "serde_yaml", - "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "stringly_conversions", - "toml 0.5.8", - "torut", -] - -[[package]] -name = "inet2_derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c62ffe0c3f4e7c0e557a7e2833daf409555e547e977d6712f640835c83a14c" -dependencies = [ - "amplify", - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", -] - [[package]] name = "inflate" version = "0.4.5" @@ -722,28 +495,6 @@ dependencies = [ "adler32", ] -[[package]] -name = "internet2" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a07ae295e404b850980559ea28bd42e3bd43cdfd59ea704ad12e056bf510f7" -dependencies = [ - "amplify", - "amplify_derive", - "bitcoin", - "chacha20poly1305", - "inet2_addr", - "inet2_derive", - "lazy_static", - "lightning_encoding", - "serde", - "serde_with", - "serde_with_macros", - "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url", - "zmq", -] - [[package]] name = "itoa" version = "0.4.7" @@ -759,12 +510,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - [[package]] name = "lazy_static" version = "1.4.0" @@ -810,25 +555,6 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" -[[package]] -name = "lnp-core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c0d979dd4b7da78d2711d80f20fa8d68563109dbacb356f0d774153dad080c" -dependencies = [ - "amplify", - "amplify_derive", - "bitcoin", - "descriptor-wallet", - "internet2", - "lazy_static", - "lightning_encoding", - "lnpbp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde", - "serde_with", - "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lnpbp" version = "0.4.0" @@ -857,61 +583,6 @@ dependencies = [ "strict_encoding_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "lnpbp" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82895efc2bfbd69b26e60650a22839536ff0cfc2d2301cba76502ed51cf21f83" -dependencies = [ - "amplify", - "amplify_derive", - "bech32", - "bitcoin", - "bitcoin_hashes", - "client_side_validation 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "deflate", - "descriptor-wallet", - "inflate", - "lazy_static", - "lightning_encoding", - "miniscript", - "serde", - "serde_with", - "serde_with_macros", - "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strict_encoding_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lnpbp-invoice" -version = "0.1.0" -dependencies = [ - "amplify", - "amplify_derive", - "base58", - "base64-compat", - "bech32", - "bitcoin", - "chrono", - "clap", - "descriptor-wallet", - "internet2", - "lightning_encoding", - "lnp-core", - "lnpbp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "miniscript", - "openssl", - "rgb-core", - "serde", - "serde_json", - "serde_with", - "serde_yaml", - "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strict_encoding_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.8", - "url", -] - [[package]] name = "log" version = "0.4.14" @@ -921,29 +592,12 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" - [[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" -[[package]] -name = "metadeps" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b122901b3a675fac8cecf68dcb2f0d3036193bc861d1ac0e1c337f7d5254c2" -dependencies = [ - "error-chain", - "pkg-config", - "toml 0.2.1", -] - [[package]] name = "miniscript" version = "5.1.0" @@ -960,17 +614,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2 1.0.24", - "quote 1.0.9", - "syn 1.0.64", -] - [[package]] name = "num-integer" version = "0.1.44" @@ -1002,101 +645,24 @@ version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61075b62a23fef5a29815de7536d940aa35ce96d18ce0cc5076272db678a577" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-src" -version = "111.14.0+1.1.1j" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b569b5bd7e5462a1700f595c7c7d487691d73b5ce064176af7f9f0cbb80a9" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "313752393519e876837e09e1fa183ddef0be7735868dced3196f4472d536277f" -dependencies = [ - "autocfg 1.0.1", - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - [[package]] name = "os_str_bytes" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" -[[package]] -name = "parse_arg" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14248cc8eced350e20122a291613de29e4fa129ba2731818c4cdbb44fccd3e55" - [[package]] name = "paste" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pin-project-lite" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" - -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - -[[package]] -name = "poly1305" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7456bc1ad2d4cf82b3a016be4c2ac48daf11bf990c1603ebd447fe6f30fca8" -dependencies = [ - "cpuid-bool 0.2.0", - "universal-hash", -] - [[package]] name = "ppv-lite86" version = "0.2.10" @@ -1349,36 +915,6 @@ version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" -[[package]] -name = "rgb-core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abf30a6bd99279a794f8e9b2a71db895195726150071f35cdcaa9ae7e7503d2" -dependencies = [ - "amplify", - "amplify_derive", - "bech32", - "bitcoin", - "bitcoin_hashes", - "chrono", - "deflate", - "descriptor-wallet", - "ed25519-dalek", - "grin_secp256k1zkp", - "inflate", - "lazy_static", - "lightning_encoding", - "lnpbp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "miniscript", - "num-derive", - "num-traits", - "regex", - "serde", - "serde_with", - "serde_with_macros", - "strict_encoding 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ring" version = "0.16.20" @@ -1400,15 +936,6 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "rustls" version = "0.16.0" @@ -1458,21 +985,6 @@ dependencies = [ "cc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.124" @@ -1549,48 +1061,17 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - [[package]] name = "sha2" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" dependencies = [ - "block-buffer 0.9.0", + "block-buffer", "cfg-if", - "cpuid-bool 0.1.2", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sha3" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" -dependencies = [ - "block-buffer 0.7.3", - "byte-tools", - "digest 0.8.1", - "keccak", - "opaque-debug 0.2.3", + "cpuid-bool", + "digest", + "opaque-debug", ] [[package]] @@ -1652,8 +1133,6 @@ dependencies = [ "amplify_derive", "bitcoin", "chrono", - "ed25519-dalek", - "grin_secp256k1zkp", "miniscript", "strict_encoding_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1703,12 +1182,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.4.0" @@ -1790,39 +1263,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "tinyvec" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46409491c9375a693ce7032101970a54f8a2010efb77e13f70788f0d84489e39" -dependencies = [ - "autocfg 1.0.1", - "bytes", - "memchr", - "pin-project-lite", -] - -[[package]] -name = "toml" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" - [[package]] name = "toml" version = "0.5.8" @@ -1832,52 +1272,12 @@ dependencies = [ "serde", ] -[[package]] -name = "torut" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0f9ee72e91955797223909df23bab7c857abf33806fd6b2cc66726b9b16bdb6" -dependencies = [ - "base32", - "base64", - "derive_more", - "ed25519-dalek", - "hex", - "hmac", - "openssl", - "rand 0.7.3", - "serde", - "serde_derive", - "sha1", - "sha2 0.8.2", - "sha3", - "tokio", -] - [[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" -[[package]] -name = "unicode-bidi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -dependencies = [ - "matches", -] - -[[package]] -name = "unicode-normalization" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-segmentation" version = "1.7.1" @@ -1902,41 +1302,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -[[package]] -name = "universal-hash" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" -dependencies = [ - "generic-array 0.14.4", - "subtle 2.4.0", -] - [[package]] name = "untrusted" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "url" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", - "serde", -] - -[[package]] -name = "vcpkg" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" - [[package]] name = "vec_map" version = "0.8.2" @@ -2147,35 +1518,3 @@ dependencies = [ "syn 1.0.64", "synstructure 0.12.4", ] - -[[package]] -name = "zeromq-src" -version = "0.1.10+4.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9133d366817fcffe22e4356043ba187ae122ec5db63d7ce73d1e6a18efa2f1" -dependencies = [ - "cmake", -] - -[[package]] -name = "zmq" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aad98a7a617d608cd9e1127147f630d24af07c7cd95ba1533246d96cbdd76c66" -dependencies = [ - "bitflags", - "libc", - "log", - "zmq-sys", -] - -[[package]] -name = "zmq-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d33a2c51dde24d5b451a2ed4b488266df221a5eaee2ee519933dc46b9a9b3648" -dependencies = [ - "libc", - "metadeps", - "zeromq-src", -] diff --git a/Cargo.toml b/Cargo.toml index 2cb202da..c8140978 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["bitcoin", "lightning", "lnp-bp", "layer-3", "cryptography"] categories = ["cryptography::cryptocurrencies"] readme = "README.md" edition = "2018" -exclude = [".github", "contrib", "client_side_validation", "strict_encoding", "invoice"] +exclude = [".github", "contrib", "client_side_validation", "strict_encoding"] [lib] name = "lnpbp" @@ -90,6 +90,6 @@ bulletproofs = ["client_side_validation/bulletproofs"] zip = ["inflate", "deflate"] [workspace] -members = [".", "strict_encoding", "strict_encoding/derive", "client_side_validation", "invoice"] -default-members = [".", "strict_encoding", "strict_encoding/derive", "client_side_validation", "invoice"] +members = [".", "strict_encoding", "strict_encoding/derive", "client_side_validation"] +default-members = [".", "strict_encoding", "strict_encoding/derive", "client_side_validation"] exclude = ["dep_test"] diff --git a/invoice/Cargo.toml b/invoice/Cargo.toml deleted file mode 100644 index 116df6f3..00000000 --- a/invoice/Cargo.toml +++ /dev/null @@ -1,68 +0,0 @@ -[package] -name = "lnpbp-invoice" -version = "0.1.0" -license = "MIT" -authors = ["Dr. Maxim Orlovsky "] -description = "LNP/BP universal invoices library implementing LNPBP-38 standard" -repository = "https://github.com/LNP-BP/rust-lnpbp" -homepage = "https://github.com/LNP-BP" -keywords = ["bitcoin", "lightning", "lnp-bp", "rgb", "invoice"] -categories = ["cryptography::cryptocurrencies"] -readme = "README.md" -edition = "2018" - -[[bin]] -name = "invoice" -path = "src/main.rs" -required-features = ["cli"] - -[lib] -name = "invoice" -path = "src/lib.rs" -crate-type = ["rlib", "staticlib"] - -[dependencies] -# Dependencies on other LNP/BP repositories -# ----------------------------------------- -amplify = { version = "3", features = ["stringly_conversions", "std"] } -amplify_derive = "2.4.3" -strict_encoding = { version = "1.0.6", features = ["miniscript"] } -strict_encoding_derive = { version = "1" } -lightning_encoding = "0.4.0-beta.1" -descriptor-wallet = { version = "0.4", features = ["keygen"] } -internet2 = "0.3.10" -lnpbp = "0.4" -lnp-core = "0.3.1" -rgb-core = { version = "0.4", optional = true } -# Dependencies on core rust-bitcoin ecosystem projects -# ---------------------------------------------------- -bitcoin = { version = "0.26", features = ["rand"] } -miniscript = { version = "5", features = ["compiler"] } -# Serialization -# ------------- -base64-compat = { version = "1", optional = true } # Used by cli only -base58 = { version = "0.1", optional = true } # Used by cli only -bech32 = { version = "0", optional = true } # Used by cli only -serde_crate = { package = "serde", version = "1", features = ["derive"], optional = true } -serde_with = { version = "1.5", features = ["hex"], optional = true } -serde_json = { version = "1", optional = true } # Used by cli only -serde_yaml = { version = "0.8", optional = true } # Used by cli only -toml = { version = "0.5", optional = true } # Used by cli only -clap = { version = "3.0.0-beta.2", optional = true } # Used by cli only -# Internal data representations -# ----------------------------- -url = "2.2" -chrono = "0.4.19" - -[target.'cfg(target_os="windows")'.dependencies] -openssl = { version = "0.10", features = ["vendored"] } - -[features] -default = [] -all = ["serde", "rgb"] -cli = ["clap", "base64-compat", "base58", "bech32", "serde", "serde_yaml", "serde_json", "toml"] -serde = ["serde_crate", "serde_with", "amplify/serde", "descriptor-wallet/serde", - "lnp-core/serde", "internet2/serde", "lnp-core/serde", - "bitcoin/use-serde", "miniscript/serde", - "chrono/serde", "url/serde"] -rgb = ["rgb-core"] diff --git a/invoice/README.md b/invoice/README.md deleted file mode 100644 index f60c65bc..00000000 --- a/invoice/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# LNP/BP Invoice Library - -Library providing functionality for doing universal invoices covering Bitcoin, -Lightning Network and RGB (on-chain and LN) according to LNPBP-38 standard. -Supports address-, UTXO-, channel-, miniscript-descriptor- and PSBT-based -invoices with such features as: -- Paying arbitrary amounts (donations etc) -- Recurrent payments -- Per-item prices with multiple item orders -- Expiration dates -- Currency exchange rate requirements -- Extended information about merchants, invoice details etc -- Optional merchant signatures - -Read more on this invoices in -[slides](https://github.com/LNP-BP/FAQ/blob/master/Presentation%20slides/Universal%20LNP-BP%20invoices.pdf) -or watch [YouTube recording](https://www.youtube.com/watch?v=R1QudCywRGk) of one -of LNP/BP Association development calls discussing universal invoices. diff --git a/invoice/src/base.rs b/invoice/src/base.rs deleted file mode 100644 index 8fad57ec..00000000 --- a/invoice/src/base.rs +++ /dev/null @@ -1,908 +0,0 @@ -// LNP/BP universal invoice library implementing LNPBP-38 standard -// Written in 2021 by -// Dr. Maxim Orlovsky -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the MIT License -// along with this software. -// If not, see . - -use chrono::NaiveDateTime; -#[cfg(feature = "serde")] -use serde_with::{As, DisplayFromStr}; -use std::cmp::Ordering; -use std::fmt::{self, Display, Formatter, Write}; -use std::io; -use std::str::FromStr; - -#[cfg(feature = "rgb")] -use amplify::Wrapper; -#[cfg(feature = "rgb")] -use bitcoin::hashes::sha256t; -use bitcoin::hashes::{sha256d, Hash}; -use bitcoin::secp256k1::{self, PublicKey, Signature}; -use bitcoin::Address; -use internet2::tlv; -use lnp::features::InitFeatures; -use lnp::payment::ShortChannelId; -use lnpbp::bech32::{self, Blob, FromBech32Str, ToBech32String}; -use lnpbp::chain::{AssetId, Chain}; -use lnpbp::client_side_validation::MerkleNode; -use lnpbp::seals::OutpointHash; -use miniscript::{descriptor::DescriptorPublicKey, Descriptor}; -use strict_encoding::{StrictDecode, StrictEncode}; -use wallet::{HashLock, Psbt}; - -// TODO: Derive `Eq` & `Hash` once Psbt will support them -/// NB: Invoice fields are non-public since each time we update them we must -/// clear signature -#[cfg_attr( - feature = "serde", - serde_as, - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -#[derive( - Getters, - Clone, - PartialEq, - Debug, - Display, - StrictEncode, - StrictDecode, - LightningEncode, - LightningDecode, -)] -#[display(Invoice::to_bech32_string)] -pub struct Invoice { - /// Version byte, always 0 for the initial version - version: u8, - - /// Amount in the specified asset - a price per single item, if `quantity` - /// options is set - #[cfg_attr(feature = "serde", serde(with = "As::"))] - amount: AmountExt, - - /// Main beneficiary. Separating the first beneficiary into a standalone - /// field allows to ensure that there is always at lease one beneficiary - /// at compile time - beneficiary: Beneficiary, - - /// List of beneficiary ordered in most desirable-first order, which follow - /// `beneficiary` value - #[tlv(type = 1)] - alt_beneficiaries: Vec, - - /// AssetId can also be used to define blockchain. If it's empty it implies - /// bitcoin mainnet - #[tlv(type = 2)] - #[cfg_attr( - feature = "serde", - serde(with = "As::>") - )] - asset: Option, - - /// Interval between recurrent payments - #[tlv(type = 3)] - recurrent: Recurrent, - - #[tlv(type = 4)] - #[cfg_attr( - feature = "serde", - serde(with = "As::>") - )] - expiry: Option, // Must be mapped to i64 - - #[tlv(type = 5)] - quantity: Option, - - /// If the price of the asset provided by fiat provider URL goes below this - /// limit the merchant will not accept the payment and it will become - /// expired - #[tlv(type = 6)] - currency_requirement: Option, - - #[tlv(type = 7)] - merchant: Option, - - #[tlv(type = 8)] - purpose: Option, - - #[tlv(type = 9)] - details: Option
, - - #[tlv(type = 0)] - #[cfg_attr( - feature = "serde", - serde(with = "As::>") - )] - signature: Option<(PublicKey, Signature)>, - - #[tlv(unknown)] - #[cfg_attr(feature = "serde", serde(skip))] - unknown: tlv::Map, - /* TODO: Add RGB feature vec optional field - * TODO: Add Bifrost server list as a TLV vec (empty if not provided) */ -} - -impl bech32::Strategy for Invoice { - const HRP: &'static str = "i"; - - type Strategy = bech32::strategies::CompressedStrictEncoding; -} - -impl FromStr for Invoice { - type Err = bech32::Error; - - fn from_str(s: &str) -> Result { - Invoice::from_bech32_str(s) - } -} - -impl Ord for Invoice { - fn cmp(&self, other: &Self) -> Ordering { - self.to_string().cmp(&other.to_string()) - } -} - -impl PartialOrd for Invoice { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl std::hash::Hash for Invoice { - fn hash(&self, state: &mut H) { - self.to_string().hash(state) - } -} - -impl Eq for Invoice {} - -impl Invoice { - pub fn new( - beneficiary: Beneficiary, - amount: Option, - asset: Option, - ) -> Invoice { - Invoice { - version: 0, - amount: amount - .map(|value| AmountExt::Normal(value)) - .unwrap_or(AmountExt::Any), - beneficiary, - alt_beneficiaries: vec![], - asset, - recurrent: Default::default(), - expiry: None, - quantity: None, - currency_requirement: None, - merchant: None, - purpose: None, - details: None, - signature: None, - unknown: Default::default(), - } - } - - pub fn with_descriptor( - descr: Descriptor, - amount: Option, - chain: &Chain, - ) -> Invoice { - Invoice::new( - Beneficiary::Descriptor(descr), - amount, - if chain == &Chain::Mainnet { - None - } else { - Some(chain.native_asset()) - }, - ) - } - - pub fn with_address(address: Address, amount: Option) -> Invoice { - let asset = if address.network != bitcoin::Network::Bitcoin { - Some(AssetId::native(&address.network.into())) - } else { - None - }; - Invoice::new(Beneficiary::Address(address), amount, asset) - } - - #[cfg(feature = "rgb")] - pub fn is_rgb(&self) -> bool { - self.rgb_asset().is_none() - } - - #[cfg(feature = "rgb")] - pub fn rgb_asset(&self) -> Option { - self.asset.and_then(|asset_id| { - if *&[ - Chain::Mainnet, - Chain::Signet, - Chain::LiquidV1, - Chain::Testnet3, - ] - .iter() - .map(Chain::native_asset) - .all(|id| id != asset_id) - { - Some(rgb::ContractId::from_inner(sha256t::Hash::from_inner( - asset_id.into_inner(), - ))) - } else { - None - } - }) - } - - pub fn classify_asset(&self, chain: Option) -> AssetClass { - match (self.asset, chain) { - (None, Some(Chain::Mainnet)) => AssetClass::Native, - (None, _) => AssetClass::InvalidNativeChain, - (Some(asset_id), Some(chain)) - if asset_id == chain.native_asset() => - { - AssetClass::Native - } - (Some(asset_id), _) - if *&[ - Chain::Mainnet, - Chain::Signet, - Chain::LiquidV1, - Chain::Testnet3, - ] - .iter() - .map(Chain::native_asset) - .find(|id| id == &asset_id) - .is_some() => - { - AssetClass::InvalidNativeChain - } - #[cfg(feature = "rgb")] - (Some(asset_id), _) => { - AssetClass::Rgb(rgb::ContractId::from_inner( - sha256t::Hash::from_inner(asset_id.into_inner()), - )) - } - #[cfg(not(feature = "rgb"))] - (Some(asset_id), _) => AssetClass::Other(asset_id), - } - } - - pub fn beneficiaries(&self) -> BeneficiariesIter { - BeneficiariesIter { - invoice: self, - index: 0, - } - } - - pub fn set_amount(&mut self, amount: AmountExt) -> bool { - if self.amount == amount { - return false; - } - self.amount = amount; - self.signature = None; - return true; - } - - pub fn set_recurrent(&mut self, recurrent: Recurrent) -> bool { - if self.recurrent == recurrent { - return false; - } - self.recurrent = recurrent; - self.signature = None; - return true; - } - - pub fn set_expiry(&mut self, expiry: NaiveDateTime) -> bool { - if self.expiry == Some(expiry) { - return false; - } - self.expiry = Some(expiry); - self.signature = None; - return true; - } - - pub fn set_no_expiry(&mut self) -> bool { - if self.expiry == None { - return false; - } - self.expiry = None; - self.signature = None; - return true; - } - - pub fn set_quantity(&mut self, quantity: Quantity) -> bool { - if self.quantity == Some(quantity) { - return false; - } - self.quantity = Some(quantity); - self.signature = None; - return true; - } - - pub fn remove_quantity(&mut self) -> bool { - if self.quantity == None { - return false; - } - self.quantity = None; - self.signature = None; - return true; - } - - pub fn set_currency_requirement( - &mut self, - currency_data: CurrencyData, - ) -> bool { - let currency_data = Some(currency_data); - if self.currency_requirement == currency_data { - return false; - } - self.currency_requirement = currency_data; - self.signature = None; - return true; - } - - pub fn remove_currency_requirement(&mut self) -> bool { - if self.currency_requirement == None { - return false; - } - self.currency_requirement = None; - self.signature = None; - return true; - } - - pub fn set_merchant(&mut self, merchant: String) -> bool { - let merchant = if merchant.is_empty() { - None - } else { - Some(merchant) - }; - if self.merchant == merchant { - return false; - } - self.merchant = merchant; - self.signature = None; - return true; - } - - pub fn remove_merchant(&mut self) -> bool { - if self.merchant == None { - return false; - } - self.merchant = None; - self.signature = None; - return true; - } - - pub fn set_purpose(&mut self, purpose: String) -> bool { - let purpose = if purpose.is_empty() { - None - } else { - Some(purpose) - }; - if self.purpose == purpose { - return false; - } - self.purpose = purpose; - self.signature = None; - return true; - } - - pub fn remove_purpose(&mut self) -> bool { - if self.purpose == None { - return false; - } - self.purpose = None; - self.signature = None; - return true; - } - - pub fn set_details(&mut self, details: Details) -> bool { - let details = Some(details); - if self.details == details { - return false; - } - self.details = details; - self.signature = None; - return true; - } - - pub fn remove_details(&mut self) -> bool { - if self.details == None { - return false; - } - self.details = None; - self.signature = None; - return true; - } - - pub fn signature_hash(&self) -> MerkleNode { - // TODO: Change signature encoding algorithm to a merkle-tree based - MerkleNode::hash( - &self.strict_serialize().expect( - "invoice data are inconsistent for strict serialization", - ), - ) - } - - pub fn set_signature(&mut self, pubkey: PublicKey, signature: Signature) { - self.signature = Some((pubkey, signature)) - } - - pub fn remove_signature(&mut self) { - self.signature = None - } -} - -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] -#[non_exhaustive] -pub enum AssetClass { - Native, - #[cfg(feature = "rgb")] - Rgb(rgb::ContractId), - #[cfg(not(feature = "rgb"))] - Other(AssetId), - InvalidNativeChain, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct BeneficiariesIter<'a> { - invoice: &'a Invoice, - index: usize, -} - -impl<'a> Iterator for BeneficiariesIter<'a> { - type Item = &'a Beneficiary; - - fn next(&mut self) -> Option { - self.index += 1; - if self.index == 1 { - Some(&self.invoice.beneficiary) - } else { - self.invoice.alt_beneficiaries.get(self.index - 2) - } - } -} - -#[derive( - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Debug, - Display, - From, - StrictEncode, - StrictDecode, -)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -#[non_exhaustive] -pub enum Recurrent { - #[display("non-recurrent")] - NonRecurrent, - - #[display("each {0} seconds")] - Seconds(u64), - - #[display("each {0} months")] - Months(u8), - - #[display("each {0} years")] - Years(u8), -} - -impl lightning_encoding::Strategy for Recurrent { - type Strategy = lightning_encoding::strategies::AsStrict; -} - -impl Default for Recurrent { - fn default() -> Self { - Recurrent::NonRecurrent - } -} - -// TODO: Derive `Eq` & `Hash` once Psbt will support them -#[cfg_attr( - feature = "serde", - serde_as, - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename = "lowercase", untagged) -)] -#[derive( - Clone, PartialEq, Debug, Display, From, StrictEncode, StrictDecode, -)] -#[display(inner)] -#[non_exhaustive] -pub enum Beneficiary { - /// Addresses are useful when you do not like to leak public key - /// information - #[from] - Address( - #[cfg_attr(feature = "serde", serde(with = "As::"))] - Address, - ), - - /// Used by protocols that work with existing UTXOs and can assign some - /// client-validated data to them (like in RGB). We always hide the real - /// UTXO behind the hashed version (using some salt) - #[from] - BlindUtxo( - #[cfg_attr(feature = "serde", serde(with = "As::"))] - OutpointHash, - ), - - /// Miniscript-based descriptors allowing custom derivation & key - /// generation - #[from] - Descriptor( - #[cfg_attr(feature = "serde", serde(with = "As::"))] - Descriptor, - ), - - /// Full transaction template in PSBT format - #[from] - // TODO: Fix display once PSBT implement `Display` - #[display("PSBT!")] - Psbt(Psbt), - - /// Lightning node receiving the payment. Not the same as lightning invoice - /// since many of the invoice data now will be part of [`Invoice`] here. - #[from] - Lightning(LnAddress), - - /// Fallback option for all future variants - Unknown( - #[cfg_attr(feature = "serde", serde(with = "As::"))] - Blob, - ), -} - -impl lightning_encoding::Strategy for Beneficiary { - type Strategy = lightning_encoding::strategies::AsStrict; -} - -#[derive( - Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Display, Error, -)] -#[display(doc_comments)] -/// Incorrect beneficiary format -pub struct BeneficiaryParseError; - -// TODO: Since we can't present full beneficiary data in a string form (because -// of the lightning part) we have to remove this implementation once -// serde_with will be working -impl FromStr for Beneficiary { - type Err = BeneficiaryParseError; - - fn from_str(s: &str) -> Result { - if let Ok(address) = Address::from_str(s) { - Ok(Beneficiary::Address(address)) - } else if let Ok(outpoint) = OutpointHash::from_str(s) { - Ok(Beneficiary::BlindUtxo(outpoint)) - } else if let Ok(descriptor) = - Descriptor::::from_str(s) - { - Ok(Beneficiary::Descriptor(descriptor)) - } else { - Err(BeneficiaryParseError) - } - } -} - -#[cfg_attr( - feature = "serde", - serde_as, - derive(Serialize, Deserialize), - serde(crate = "serde_crate") -)] -#[derive( - Clone, - Ord, - PartialOrd, - Eq, - PartialEq, - Hash, - Debug, - Display, - StrictEncode, - StrictDecode, - LightningEncode, - LightningDecode, -)] -#[display("{node_id}")] -pub struct LnAddress { - #[cfg_attr(feature = "serde", serde(with = "As::"))] - pub node_id: secp256k1::PublicKey, - pub features: InitFeatures, - #[cfg_attr(feature = "serde", serde(with = "As::"))] - pub lock: HashLock, /* When PTLC will be available the same field will - * be re-used for them + the - * use will be indicated with a - * feature flag */ - pub min_final_cltv_expiry: Option, - pub path_hints: Vec, -} - -/// Path hints for a lightning network payment, equal to the value of the `r` -/// key of the lightning BOLT-11 invoice -/// -#[cfg_attr( - feature = "serde", - serde_as, - derive(Serialize, Deserialize), - serde(crate = "serde_crate") -)] -#[derive( - Copy, - Clone, - Ord, - PartialOrd, - Eq, - PartialEq, - Hash, - Debug, - Display, - StrictEncode, - StrictDecode, - LightningEncode, - LightningDecode, -)] -#[display("{short_channel_id}@{node_id}")] -pub struct LnPathHint { - #[cfg_attr(feature = "serde", serde(with = "As::"))] - pub node_id: secp256k1::PublicKey, - #[cfg_attr(feature = "serde", serde(with = "As::"))] - pub short_channel_id: ShortChannelId, - pub fee_base_msat: u32, - pub fee_proportional_millionths: u32, - pub cltv_expiry_delta: u16, -} - -#[derive( - Copy, - Clone, - Ord, - PartialOrd, - Eq, - PartialEq, - Hash, - Debug, - Display, - From, - StrictEncode, - StrictDecode, -)] -pub enum AmountExt { - /// Payments for any amount is accepted: useful for charity/donations, etc - #[display("any")] - Any, - - #[from] - #[display(inner)] - Normal(u64), - - #[display("{0}.{1}")] - Milli(u64, u16), -} - -impl Default for AmountExt { - fn default() -> Self { - AmountExt::Any - } -} - -impl lightning_encoding::Strategy for AmountExt { - type Strategy = lightning_encoding::strategies::AsStrict; -} - -impl AmountExt { - pub fn atomic_value(&self) -> Option { - match self { - AmountExt::Any => None, - AmountExt::Normal(val) => Some(*val), - AmountExt::Milli(_, _) => None, - } - } -} - -#[derive( - Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Display, Error, From, -)] -#[display(doc_comments)] -#[from(std::num::ParseIntError)] -/// Incorrect beneficiary format -pub struct AmountParseError; - -impl FromStr for AmountExt { - type Err = AmountParseError; - - fn from_str(s: &str) -> Result { - if s.trim().to_lowercase() == "any" { - return Ok(AmountExt::Any); - } - let mut split = s.split("."); - Ok(match (split.next(), split.next()) { - (Some(amt), None) => AmountExt::Normal(amt.parse()?), - (Some(int), Some(frac)) => { - AmountExt::Milli(int.parse()?, frac.parse()?) - } - _ => Err(AmountParseError)?, - }) - } -} - -#[derive( - Clone, - Ord, - PartialOrd, - Eq, - PartialEq, - Hash, - Debug, - Display, - StrictEncode, - StrictDecode, - LightningEncode, - LightningDecode, -)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate") -)] -#[display("{source}#commitment")] -pub struct Details { - #[cfg_attr(feature = "serde", serde(with = "As::"))] - pub commitment: sha256d::Hash, - pub source: String, // Url -} - -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] -// TODO: Move to amplify library -pub struct Iso4217([u8; 3]); - -impl Display for Iso4217 { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.write_char(self.0[0].into())?; - f.write_char(self.0[1].into())?; - f.write_char(self.0[2].into()) - } -} - -#[derive( - Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error, -)] -#[display(doc_comments)] -pub enum Iso4217Error { - /// Wrong string length to parse ISO4217 data - WrongLen, -} - -impl FromStr for Iso4217 { - type Err = Iso4217Error; - - fn from_str(s: &str) -> Result { - if s.bytes().len() != 3 { - return Err(Iso4217Error::WrongLen); - } - - let mut inner = [0u8; 3]; - inner.copy_from_slice(&s.bytes().collect::>()[0..3]); - Ok(Iso4217(inner)) - } -} - -impl StrictEncode for Iso4217 { - fn strict_encode( - &self, - mut e: E, - ) -> Result { - e.write(&self.0)?; - Ok(3) - } -} - -impl StrictDecode for Iso4217 { - fn strict_decode( - mut d: D, - ) -> Result { - let mut me = Self([0u8; 3]); - d.read_exact(&mut me.0)?; - Ok(me) - } -} - -impl lightning_encoding::Strategy for Iso4217 { - type Strategy = lightning_encoding::strategies::AsStrict; -} - -#[cfg_attr( - feature = "serde", - serde_as, - derive(Serialize, Deserialize), - serde(crate = "serde_crate") -)] -#[derive( - Clone, - Ord, - PartialOrd, - Eq, - PartialEq, - Hash, - Debug, - Display, - StrictEncode, - StrictDecode, - LightningEncode, - LightningDecode, -)] -#[display("{coins}.{fractions} {iso4217}")] -pub struct CurrencyData { - #[cfg_attr(feature = "serde", serde(with = "As::"))] - pub iso4217: Iso4217, - pub coins: u32, - pub fractions: u8, - pub price_provider: String, // Url, -} - -#[derive( - Copy, - Clone, - Ord, - PartialOrd, - Eq, - PartialEq, - Hash, - Debug, - From, - StrictEncode, - StrictDecode, - LightningEncode, - LightningDecode, -)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate") -)] -pub struct Quantity { - pub min: u32, // We will default to zero - pub max: Option, - #[from] - pub default: u32, -} - -impl Default for Quantity { - fn default() -> Self { - Self { - min: 0, - max: None, - default: 1, - } - } -} - -impl Display for Quantity { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{} items", self.default)?; - match (self.min, self.max) { - (0, Some(max)) => write!(f, " (or any amount up to {})", max), - (0, None) => Ok(()), - (_, Some(max)) => write!(f, " (or from {} to {})", self.min, max), - (_, None) => write!(f, " (or any amount above {})", self.min), - } - } -} diff --git a/invoice/src/lib.rs b/invoice/src/lib.rs deleted file mode 100644 index 27411b7c..00000000 --- a/invoice/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -// LNP/BP universal invoice library implementing LNPBP-38 standard -// Written in 2021 by -// Dr. Maxim Orlovsky -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the MIT License -// along with this software. -// If not, see . - -#![recursion_limit = "256"] -// Coding conventions -#![deny( - non_upper_case_globals, - non_camel_case_types, - non_snake_case, - unused_mut, - unused_imports, - // dead_code, - //missing_docs -)] -// TODO: when we will be ready for the release #![deny(missing_docs)] - -#[macro_use] -extern crate amplify_derive; -#[macro_use] -extern crate lightning_encoding; - -#[cfg(feature = "serde")] -#[macro_use] -extern crate serde_with; -#[cfg(feature = "serde")] -extern crate serde_crate as serde; - -mod base; - -pub use base::*; diff --git a/invoice/src/main.rs b/invoice/src/main.rs deleted file mode 100644 index f6462b58..00000000 --- a/invoice/src/main.rs +++ /dev/null @@ -1,250 +0,0 @@ -// LNP/BP universal invoice library implementing LNPBP-38 standard -// Written in 2021 by -// Dr. Maxim Orlovsky -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to -// the public domain worldwide. This software is distributed without -// any warranty. -// -// You should have received a copy of the MIT License -// along with this software. -// If not, see . - -extern crate serde_crate as serde; - -use clap::{AppSettings, Clap}; -use serde::Serialize; -use std::fmt::{self, Debug, Display, Formatter}; -use std::io::{self, Read}; -use std::str::FromStr; - -use base58::{FromBase58, ToBase58}; -use bitcoin::hashes::hex::{self, FromHex, ToHex}; -use invoice::Invoice; -use strict_encoding::{StrictDecode, StrictEncode}; - -#[derive(Clap, Clone, Debug)] -#[clap( - name = "invoice", - bin_name = "invoice", - author, - version, - about = "Command-line tool for working with LNP/BP invoicing", - setting = AppSettings::ColoredHelp, -)] -pub struct Opts { - /// Command to execute - #[clap(subcommand)] - pub command: Command, -} - -#[derive(Clap, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[clap(setting = AppSettings::ColoredHelp)] -pub enum Command { - /// Converting between different representations of invoice data - Convert { - /// Invoice data; if none are given reads from STDIN - invoice: Option, - - /// Formatting of the input invoice data - #[clap(short, long, default_value = "bech32")] - input: Format, - - /// Formatting for the output invoice data - #[clap(short, long, default_value = "yaml")] - output: Format, - }, - - RgbConvert { - /// Asset id in any format - asset: Option, - - /// Formatting of the input invoice data - #[clap(short, long, default_value = "hex")] - input: Format, - - /// Formatting for the output invoice data - #[clap(short, long, default_value = "bech32")] - output: Format, - }, -} - -/// Formatting of the data -#[derive(Clap, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)] -pub enum Format { - /// Format according to the rust debug rules - Debug, - - /// Format using Bech32 representation - Bech32, - - /// Format using Base58 encoding - Base58, - - /// Format using Base64 encoding - Base64, - - /// Format as YAML - Yaml, - - /// Format as JSON - Json, - - /// Format according to the strict encoding rules - Hexadecimal, - - /// Format as a rust array (using hexadecimal byte values) - Rust, - - /// Produce binary (raw) output according to LNPBP-39 serialization rules - Raw, -} - -impl Display for Format { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - Format::Debug => f.write_str("debug"), - Format::Base58 => f.write_str("base58"), - Format::Base64 => f.write_str("base64"), - Format::Bech32 => f.write_str("bech32"), - Format::Yaml => f.write_str("yaml"), - Format::Json => f.write_str("json"), - Format::Hexadecimal => f.write_str("hex"), - Format::Rust => f.write_str("rust"), - Format::Raw => f.write_str("raw"), - } - } -} - -impl FromStr for Format { - type Err = String; - - fn from_str(s: &str) -> Result { - Ok(match s.trim().to_lowercase().as_str() { - "debug" => Format::Debug, - "base58" => Format::Base58, - "base64" => Format::Base64, - "bech32" => Format::Bech32, - "yaml" => Format::Yaml, - "json" => Format::Json, - "hex" => Format::Hexadecimal, - "raw" | "bin" => Format::Raw, - "rust" => Format::Rust, - other => Err(format!("Unknown format: {}", other))?, - }) - } -} - -fn input_read(data: Option, format: Format) -> Result -where - T: FromStr + StrictDecode + for<'de> serde::Deserialize<'de>, - ::Err: Display, -{ - let data = data - .map(|d| d.as_bytes().to_vec()) - .ok_or(String::default()) - .or_else(|_| -> Result, String> { - let mut buf = Vec::new(); - io::stdin() - .read_to_end(&mut buf) - .as_ref() - .map_err(io::Error::to_string)?; - Ok(buf) - })?; - let s = &String::from_utf8_lossy(&data); - Ok(match format { - Format::Bech32 => T::from_str(s).map_err(|err| err.to_string())?, - Format::Base58 => { - T::strict_deserialize(s.from_base58().map_err(|err| { - format!("Incorrect Base58 encoding: {:?}", err) - })?) - .map_err(|err| format!("Wrong invoice data: {}", err))? - } - Format::Base64 => T::strict_deserialize( - &base64::decode(&data) - .map_err(|err| format!("Incorrect Base64 encoding: {}", err))?, - ) - .map_err(|err| format!("Wrong invoice data: {}", err))?, - Format::Yaml => { - serde_yaml::from_str(s).map_err(|err| err.to_string())? - } - Format::Json => { - serde_json::from_str(s).map_err(|err| err.to_string())? - } - Format::Hexadecimal => T::strict_deserialize( - Vec::::from_hex(s) - .as_ref() - .map_err(hex::Error::to_string)?, - ) - .map_err(|err| format!("Wrong invoice data: {}", err))?, - Format::Raw => T::strict_deserialize(&data) - .map_err(|err| format!("Wrong invoice data: {}", err))?, - _ => Err(format!("Can't read data from {} format", format))?, - }) -} - -fn output_write( - mut f: impl io::Write, - data: T, - format: Format, -) -> Result<(), String> -where - T: Debug + Display + Serialize + StrictEncode, -{ - let strict = data.strict_serialize().map_err(|err| err.to_string())?; - match format { - Format::Debug => write!(f, "{:#?}", data), - Format::Bech32 => write!(f, "{}", data), - Format::Base58 => write!(f, "{}", strict.to_base58()), - Format::Base64 => write!(f, "{}", base64::encode(&strict)), - Format::Yaml => write!( - f, - "{}", - serde_yaml::to_string(&data) - .as_ref() - .map_err(serde_yaml::Error::to_string)? - ), - Format::Json => write!( - f, - "{}", - serde_json::to_string(&data) - .as_ref() - .map_err(serde_json::Error::to_string)? - ), - Format::Hexadecimal => write!(f, "{}", strict.to_hex()), - Format::Rust => write!(f, "{:#04X?}", strict), - Format::Raw => data - .strict_encode(f) - .map(|_| ()) - .map_err(|_| io::Error::from_raw_os_error(0)), - } - .as_ref() - .map_err(io::Error::to_string)?; - Ok(()) -} - -fn main() -> Result<(), String> { - let opts = Opts::parse(); - - match opts.command { - Command::Convert { - invoice, - input, - output, - } => { - let invoice: Invoice = input_read(invoice, input)?; - output_write(io::stdout(), invoice, output)?; - } - Command::RgbConvert { - asset, - input, - output, - } => { - let asset: rgb::ContractId = input_read(asset, input)?; - output_write(io::stdout(), asset, output)?; - } - } - - Ok(()) -}