diff --git a/Cargo.lock b/Cargo.lock index 4efae8448..705ceeea4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -165,7 +165,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.61", "time", ] @@ -232,7 +232,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -243,7 +243,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -605,7 +605,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -665,7 +665,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -714,7 +714,7 @@ dependencies = [ "log", "serde", "serde_json", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-stream", "tokio-util 0.7.11", "tracing", @@ -735,7 +735,7 @@ dependencies = [ "log", "serde", "serde_json", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-util 0.7.11", ] @@ -859,7 +859,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -870,7 +870,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -939,23 +939,23 @@ dependencies = [ [[package]] name = "dirs" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -966,7 +966,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -1210,7 +1210,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -1342,9 +1342,9 @@ dependencies = [ "serde_json", "sha256", "tempfile", - "thiserror", + "thiserror 1.0.61", "time", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-stream", "tonic 0.8.3", "tonic-build 0.8.4", @@ -1373,8 +1373,8 @@ dependencies = [ "pyo3", "runeauth", "serde_json", - "thiserror", - "tokio 1.37.0", + "thiserror 1.0.61", + "tokio 1.43.0", "tonic 0.8.3", ] @@ -1388,7 +1388,7 @@ dependencies = [ "hex", "rand 0.8.5", "runeauth", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -1417,8 +1417,8 @@ dependencies = [ "serde", "serde_json", "sled", - "thiserror", - "tokio 1.37.0", + "thiserror 1.0.61", + "tokio 1.43.0", "tokio-stream", "tokio-util 0.7.11", "tonic 0.8.3", @@ -1454,8 +1454,8 @@ dependencies = [ "futures", "gl-client", "hex", - "thiserror", - "tokio 1.37.0", + "thiserror 2.0.11", + "tokio 1.43.0", "vls-core", ] @@ -1508,7 +1508,7 @@ dependencies = [ "http", "indexmap 2.2.6", "slab", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-util 0.7.11", "tracing", ] @@ -1699,7 +1699,7 @@ dependencies = [ "itoa 1.0.11", "pin-project-lite 0.2.14", "socket2 0.5.7", - "tokio 1.37.0", + "tokio 1.43.0", "tower-service", "tracing", "want", @@ -1715,7 +1715,7 @@ dependencies = [ "http", "hyper 0.14.28", "rustls 0.21.12", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-rustls 0.24.1", ] @@ -1727,7 +1727,7 @@ checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ "hyper 0.14.28", "pin-project-lite 0.2.14", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-io-timeout", ] @@ -1955,9 +1955,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libm" @@ -2009,7 +2009,7 @@ dependencies = [ "futures-util", "notify", "pin-project-lite 0.2.14", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -2116,6 +2116,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + [[package]] name = "mio-named-pipes" version = "0.1.7" @@ -2447,7 +2458,7 @@ dependencies = [ "libc", "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2528,7 +2539,7 @@ dependencies = [ "sha-1", "sha2 0.9.9", "sha3", - "thiserror", + "thiserror 1.0.61", ] [[package]] @@ -2639,7 +2650,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -2737,9 +2748,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -3048,13 +3059,13 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 2.0.11", ] [[package]] @@ -3132,7 +3143,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "system-configuration", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-rustls 0.24.1", "tower-service", "url", @@ -3205,7 +3216,7 @@ dependencies = [ "hex", "indexmap 2.2.6", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.61", ] [[package]] @@ -3471,7 +3482,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -3522,7 +3533,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -3572,7 +3583,7 @@ dependencies = [ "bytes 1.6.0", "hex", "sha2 0.10.8", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -3623,7 +3634,7 @@ dependencies = [ "chrono", "num-bigint", "num-traits", - "thiserror", + "thiserror 1.0.61", ] [[package]] @@ -3725,9 +3736,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -3812,7 +3823,16 @@ version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.61", +] + +[[package]] +name = "thiserror" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", ] [[package]] @@ -3823,7 +3843,18 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", ] [[package]] @@ -3908,21 +3939,20 @@ dependencies = [ [[package]] name = "tokio" -version = "1.37.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes 1.6.0", "libc", - "mio 0.8.11", - "num_cpus", + "mio 1.0.3", "parking_lot 0.12.3", "pin-project-lite 0.2.14", "signal-hook-registry", "socket2 0.5.7", - "tokio-macros 2.2.0", - "windows-sys 0.48.0", + "tokio-macros 2.5.0", + "windows-sys 0.52.0", ] [[package]] @@ -3932,7 +3962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ "pin-project-lite 0.2.14", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -3948,13 +3978,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -3976,7 +4006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ "rustls 0.20.9", - "tokio 1.37.0", + "tokio 1.43.0", "webpki 0.22.4", ] @@ -3987,7 +4017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls 0.21.12", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -3998,7 +4028,7 @@ checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite 0.2.14", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -4025,7 +4055,7 @@ dependencies = [ "futures-core", "futures-sink", "pin-project-lite 0.2.14", - "tokio 1.37.0", + "tokio 1.43.0", ] [[package]] @@ -4082,7 +4112,7 @@ dependencies = [ "prost 0.11.9", "prost-derive 0.11.9", "rustls-pemfile", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-rustls 0.23.4", "tokio-stream", "tokio-util 0.7.11", @@ -4149,7 +4179,7 @@ dependencies = [ "pin-project-lite 0.2.14", "rand 0.8.5", "slab", - "tokio 1.37.0", + "tokio 1.43.0", "tokio-util 0.7.11", "tower-layer", "tower-service", @@ -4336,7 +4366,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] [[package]] @@ -4645,7 +4675,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "wasm-bindgen-shared", ] @@ -4679,7 +4709,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4790,7 +4820,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -4808,7 +4838,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -4828,18 +4867,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4850,9 +4889,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4862,9 +4901,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4874,15 +4913,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4892,9 +4931,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4904,9 +4943,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -4916,9 +4955,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -4928,9 +4967,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" @@ -4967,7 +5006,7 @@ dependencies = [ "ring 0.17.8", "signature", "spki", - "thiserror", + "thiserror 1.0.61", "zeroize", ] @@ -4986,7 +5025,7 @@ dependencies = [ "oid-registry", "ring 0.16.20", "rusticata-macros", - "thiserror", + "thiserror 1.0.61", "time", ] @@ -5016,5 +5055,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.96", ] diff --git a/gitlab/README.md b/gitlab/README.md index 3dea7a8ce..ac30d512c 100644 --- a/gitlab/README.md +++ b/gitlab/README.md @@ -1,5 +1,5 @@ ## Gitlab Pipelines -There are 5 Greenlight packaged binaries/libraries that are published - 2 Python packages and 3 Rust crates. +There are 5 Greenlight packaged binaries/libraries that are published - 1 Python packages and 4 Rust crates. The builds are triggered by certain tag formats. Make sure to include a patch as well since the Rust compiler requires that (applicable to `gl-client-py` as well). @@ -11,9 +11,9 @@ If a tagged release doesn't work, it can be retried by adding an `_N` suffix aft ### PyPI * gl-client-py - `glclientpy_YYYYMMDD-x.x.x` -* greenlight-cli - `glcli_YYYYMMDD-x.x.x` ### crates.io * gl-client - `glclient_YYYYMMDD-x.x.x` * gl-plugin - `glplugin_YYYYMMDD-x.x.x` * gl-signerproxy - `glsignerproxy_YYYYMMDD-x.x.x` +* gl-cli -`glcli_YYYYMMDD-x.x.x` diff --git a/gitlab/build-crates.yml b/gitlab/build-crates.yml index 29619c3fb..5db19fa0a 100644 --- a/gitlab/build-crates.yml +++ b/gitlab/build-crates.yml @@ -33,3 +33,10 @@ build_gl_signerproxy: - if: $CI_COMMIT_TAG =~ /glsignerproxy_\d{8}(_[1-9][0-9]?)?\-.*/ variables: PKG_NAME: gl-signerproxy + +build_gl_cli: + extends: .build_rust_prep + rules: + - if: $CI_COMMIT_TAG =~ /glcli_\d{8}(_[1-9][0-9]?)?\-.*/ + variables: + PKG_NAME: gl-cli diff --git a/gitlab/build-pypi.yml b/gitlab/build-pypi.yml index 4cf2f970d..a0e84d09d 100644 --- a/gitlab/build-pypi.yml +++ b/gitlab/build-pypi.yml @@ -17,23 +17,3 @@ build_gl_client_py: expire_in: 2 weeks paths: - "target/wheels/*" - -build_glcli: - extends: .build_setup - when: manual - rules: - - if: $CI_COMMIT_TAG =~ /glcli_\d{8}(_[1-9][0-9]?)?\-.*/ - before_script: - - export NEW_VER=$(echo ${CI_COMMIT_TAG} | cut -d'-' -f2) - - sed -i "s/^version = \".*\"/version = \"$NEW_VER\"/" tools/glcli/pyproject.toml - - . $HOME/.cargo/env # sh doesn't have the correct PATH - script: - - cd tools/glcli - - poetry config pypi-token.pypi ${PYPI_TOKEN} - - poetry build - - poetry publish - - ls -lh dist - artifacts: - expire_in: 2 weeks - paths: - - "tools/glcli/dist/*" diff --git a/libs/gl-cli/Cargo.toml b/libs/gl-cli/Cargo.toml index 8f7c46623..2dbbd5fa8 100644 --- a/libs/gl-cli/Cargo.toml +++ b/libs/gl-cli/Cargo.toml @@ -1,18 +1,27 @@ [package] name = "glcli" -authors = ["Peter Neuroth "] version = "0.1.0" edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +authors = ["Peter Neuroth "] +description = "A command-line interface for running a Greenlight signer and operating a Greenlight node" +homepage = "https://blockstream.github.io/greenlight/" +repository = "https://github.com/Blockstream/greenlight" +documentation = "https://blockstream.github.io/greenlight/" +keywords = ["lightning", "greenlight", "cli", "bitcoin", "blockchain"] +categories = ["command-line-utlis", "cryptography::cryptocurrencies"] +license = "MIT" +reademe = "README.md" [dependencies] -clap = { version = "4.5.4", features = ["derive"] } -dirs = "5.0.1" -env_logger = "0.11.3" +clap = { version = "4.5", features = ["derive"] } +dirs = "6.0" +env_logger = "0.11" futures = "0.3" -gl-client = { path = "../gl-client" } +gl-client = { version = "0.3", path = "../gl-client" } hex = "0.4" -thiserror = "1.0.59" -tokio = "1.37.0" +thiserror = "2.0.11" +tokio = "1.43.0" vls-core.workspace = true + +[badges] +maintenance = { status = "actively-developed" } diff --git a/libs/gl-cli/README.md b/libs/gl-cli/README.md new file mode 100644 index 000000000..ca7ac55fb --- /dev/null +++ b/libs/gl-cli/README.md @@ -0,0 +1,143 @@ +# glcli + +`glcli` is a command-line interface for running a __Greenlight signer__ and +operating a __Greenlight_node__. It is built on top of the `gl-client` library. + +## Features + +`glcli` is not yet feature-complete but already provides a basic set of +commands necessary for everyday node operations. Planned future enhancements +include additional commands and broader integration. + +* __Scheduler__: Interact with Greenlight's scheduler to provision and start nodes. +* __Signer__: Run and interact with a local signer. +* __Node__: Operate and control a lightning node hosted on Greenlight. + +## Installation + +Since `glcli` is not yet published on __crates.io__, you can install it locally +using +```bash +cargo install --path=. +``` +Run this command from the `glcli` directory. + +### Prerequisites + +Ensure __Rust__ is installed on your system. If it is not installed, you can set +it up using [Rustup]("https://rustup.rs/"): +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +### Build and Install Locally + +Navigate to the `glcli` directory and use __Cargo__ to install `glcli` into +your `CARGO_HOME` (which defaults to `$HOME/.cargo/`): +```bash +cargo install --path=. +``` +Ensure that `CARGO_HOME/bin` is in your `PATH`. + +## Usage + +After installation, run: +```bash +glcli --help +``` +This will display an overview of the available commands. + +By default, `glcli` stores application data in the system's default data +directory: +* __Linux__: `$XDG_DATA_HOME` or `$HOME/.local/share` +* __macOS__: `$HOME`/Library/Application Support + +To specify a custom data directory, use the `--data-dir` or `-d` option. For +example: +```bash +glcli -d "${HOME}/.greenlight_node_1" node getinfo +``` + +### Register a Node + +Before you can operate a Greenlight node you have to register one. Currently, +you need an _invite code_ or a +[developer certificate]("https://blockstream.github.io/greenlight/getting-started/certs/") +to register a new node. `glcli` currently supports registration via an +_invite code_ using the `--invite-code` option: +```bash +glcli scheduler register --invite-code= +``` + +### Run a Local Signer + +To operate your node, you need to attach a local signer to your Greenlight node. +The signer is responsible for handling cryptographic signing operations, +ensuring transaction security and validating requests before granting +signatures locally. + +Start a local signer and attach it to Greenlight by running: +```bash +glcli signer run +``` + +The signer now listens for incomming requests. + +### Operate a Greenlight Node + +_(Optional scheduling)_: When executing a `node` command, `glcli` will +automatically start the node by calling Greenlight's scheduler if necessary. +However, you can manually schedule your node in advance by running: +```bash +glcli scheduler schedule +``` + +Once provisioned, you can interact with your node using `node` subcommands. For +example to check the node's operational state: +```bash +glcli node getinfo +``` + +## Advanced Bitcoin Network Configuration + +Greenlight supports running nodes on the `bitcoin` and `signet` networks, +defaulting to `bitcoin`. To register a Greenlight node on `signet`, use the +`--network` option: +```bash +glcli --network="signet" scheduler register +``` +Include the `--network` option in all susequent commands for this node. For +example: +```bash +glcli --network="signet" signer run +``` +```bash +glcli --network="signet" node getinfo +``` + +_Please note that we __do not__ support `testnet` at the moment. Please open an +issue describing your use case if you need support for other networks._ + +## Development +### Build `glcli` +```bash +cargo build +``` +### Run Tests +```bash +cargo test +``` + +## Contributing +`glcli` is under active development and currently lacks many major commands from +[Core-Lightning]("https://github.com/ElementsProject/lightning") such as +`listinvoices`, `fundchannel`, `close` and `sendpay`. Contributions to +add these and other missing commands are welcome. If you need a command +that is not yet available, feel free to submit a pull request or open an issue +describing your use case. + +If you encounter any bugs, please report them via an issue or contribute a fix +through a pull request. + +## License +`glcli` is licensed under the __MIT License__ diff --git a/tools/glcli/.gitignore b/tools/glcli/.gitignore deleted file mode 100644 index 3443ff7c6..000000000 --- a/tools/glcli/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -__pycache__ -dist -build -.cache -src -poetry.lock -glapi.egg-info diff --git a/tools/glcli/Makefile b/tools/glcli/Makefile deleted file mode 100644 index 8ed81c1d0..000000000 --- a/tools/glcli/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -install: - (cd ../rust/gl-client-py; make install) - pip install . - -clean: - rm -rf build dist glcli.egg-info .mypy_cache src tmpenv .tmpenv .tmpenv2 - -test: - virtualenv .tmpenv --python=$(which python3) --download --always-copy --clear - .tmpenv/bin/python3 -m pip install -U pip - .tmpenv/bin/python3 -m pip install --extra-index-url=https://us-west2-python.pkg.dev/c-lightning/greenlight-pypi/simple/ gl-client-py - - GL_SCHEDULER_GRPC_URI=https://scheduler.testing.gl.blckstrm.com:443 .tmpenv/bin/python3 -c 'import glclient as gl; tls = gl.TlsConfig(); s = gl.Signer(b"0"*32, "regtest", tls); sched = gl.Scheduler(s.node_id(), "regtest"); print(sched.schedule())' - .tmpenv/bin/python3 -c 'import _libhsmd;print(_libhsmd.__file__)' - -sdist: - python setup.py sdist - -publish: sdist - twine upload --repository-url https://us-west2-python.pkg.dev/c-lightning/greenlight-pypi/ dist/glcli-*.tar.gz diff --git a/tools/glcli/README.md b/tools/glcli/README.md deleted file mode 100644 index e184334aa..000000000 --- a/tools/glcli/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# glcli: Greenlight Command Line Interface - -A simple tool to issue commands to a Greenlight node and interact with -the scheduler. - -## Help - -```bash -$glcli scheduler --help -``` - - -```bash -$ glcli --help -``` - -## Installing - -Installing the `glcli` utility can be done with the following command: - -```bash -pip install --extra-index-url=https://us-west2-python.pkg.dev/c-lightning/greenlight-pypi/simple/ glcli -``` - -In most cases we have prebuilt the binary extension for `gl-client-py` -(which internall depends on `libhsmd`, another binary extension). See -the [`gl-client-py` documentation][glpy-doc] for details on prebuilt -binaries and how to compile on platforms that don't have a prebuilt -version yet. - -[glpy-doc]: ../../libs/gl-client-py/ - - - diff --git a/tools/glcli/glcli/cli.py b/tools/glcli/glcli/cli.py deleted file mode 100644 index 733e04d37..000000000 --- a/tools/glcli/glcli/cli.py +++ /dev/null @@ -1,727 +0,0 @@ -from binascii import hexlify, unhexlify -from glcli import environment as env -from glclient import Scheduler, Credentials, scheduler_pb2 as schedpb -from glclient.pairing import NewDeviceClient, AttestationDeviceClient -from pyln.grpc import Amount, AmountOrAll, AmountOrAny -from google.protobuf.descriptor import FieldDescriptor -from pathlib import Path -from typing import Optional -import click -import json -import logging -import os -import glclient -import re -import secrets -import sys -import threading -import signal - - -logger = logging.getLogger("glcli") -logger.setLevel(logging.DEBUG) -handler = logging.StreamHandler(sys.stderr) -handler.setLevel(logging.DEBUG) -formatter = logging.Formatter("[%(asctime)s - %(levelname)s] %(message)s") -handler.setFormatter(formatter) -logger.addHandler(handler) - - -class Creds: - """Encapsulation of the fs convention followed by glcli.""" - - def __init__(self) -> "Creds": - """Initialize the credentials.""" - self.creds = Credentials() - creds_path = Path("credentials.gfs") - # legacy paths used by TlsConfig - cert_path = Path("device.crt") - key_path = Path("device-key.pem") - have_certs = cert_path.exists() and key_path.exists() - if creds_path.exists(): - self.creds = Credentials.from_path(str(creds_path)) - logger.info("Configuring client with device credentials") - elif have_certs: - logger.info("Configuring client with device credentials (legacy)") - device_cert = open(str(cert_path), "rb").read() - device_key = open(str(key_path), "rb").read() - rune = "" - if Path("rune").exists(): - rune = open("rune", "r").read() - self.creds = Credentials.from_parts(device_cert, device_key, rune) - else: - logger.info("Configuring client with NOBODY credentials.") - - -class Signer: - def __init__(self, creds: Creds, network='testnet'): - """Initialize the signer based on the cwd - """ - secrets_file = Path("hsm_secret") - if not secrets_file.exists(): - logger.info(f"No {secrets_file} file found, generating a new secret key") - secret = secrets.token_bytes(32) - with open( - os.open(secrets_file, os.O_CREAT | os.O_WRONLY, 0o600), "wb" - ) as f: - f.write(secret) - else: - logger.debug(f"Found existing {secrets_file} file, loading secret from it") - with open(secrets_file, "rb") as f: - secret = f.read(32) - - self.inner = glclient.Signer(secret, network, creds.creds) - - -class Context: - def load_metadata(self, creds): - """Load the metadata from the metadata.toml file if it exists. - - If it doesn't exist, create it by instantiating a signer - briefly, extract the information and then destroy the signer - again, unlocking the state directory for other signers. - - """ - path = Path("metadata.json") - if not path.exists(): - signer = Signer(creds) - node_id = signer.inner.node_id() - self.metadata = { - 'hex_node_id': signer.inner.node_id().hex(), - 'signer_version': signer.inner.version(), - } - del signer - json.dump(self.metadata, path.open(mode='w'), sort_keys=True, indent=2) - self.metadata['node_id'] = node_id - else: - self.metadata = json.load(path.open(mode='r')) - self.metadata['node_id'] = bytes.fromhex(self.metadata['hex_node_id']) - - def __init__(self, network='testnet', start_hsmd=False): - self.creds = Creds() - self.load_metadata(self.creds) - self.scheduler = Scheduler(network, creds=self.creds.creds) - self.node = None - self.scheduler_chan = None - self.node_id = self.metadata['node_id'] - - def get_node(self): - if self.node is None: - self.node = self.scheduler.node() - return self.node - - -class AmountType(click.ParamType): - name = 'amount' - - def convert(self, value, param, ctx): - if isinstance(value, Amount): - return value - - g = re.match(r'([0-9\.]+)(btc|msat|sat)?', value) - if g is None: - raise ValueError(f'Unable to parse {value} as an amount.') - - num, suffix = g.groups() - - unit = { - 'btc': 10**8 * 10**3, - 'sat': 1000, - 'msat': 1, - } - - return Amount(msat=int(num) * unit[suffix]) - - -class AmountOrAnyType(click.ParamType): - name = 'amount' - - def convert(self, value, param, ctx): - if isinstance(value, AmountOrAny): - return value - - if value.lower() == 'any': - return AmountOrAny(any=True) - - g = re.match(r'([0-9\.]+)(btc|msat|sat)?', value) - - if g is None: - raise ValueError(f'Unable to parse {value} as an amount.') - - num, suffix = g.groups() - - unit = { - 'btc': 10**8 * 10**3, - 'sat': 1000, - 'msat': 1, - } - - return AmountOrAny( - amount=Amount(msat=int(num) * unit[suffix]) - ) - - -class AmountOrAllType(click.ParamType): - name = 'amount' - - def convert(self, value, param, ctx): - if isinstance(value, AmountOrAll): - return value - - if value.lower() == 'all': - return AmountOrAll(all=True) - - g = re.match(r'([0-9\.]+)(btc|msat|sat)?', value) - - if g is None: - raise ValueError(f'Unable to parse {value} as an amount.') - - num, suffix = g.groups() - - unit = { - 'btc': 10**8 * 10**3, - 'sat': 1000, - 'msat': 1, - } - - return AmountOrAll( - amount=Amount(msat=int(num) * unit[suffix]) - ) - - -def pb2dict(p): - res = {} - defaults = True - for desc, val in p.ListFields(): - # If the parent of any field is contained in a oneof, then we - # all are. - defaults = defaults and desc.containing_oneof is None - - if desc.type == FieldDescriptor.TYPE_MESSAGE: - if desc.label == FieldDescriptor.LABEL_REPEATED: - val = [pb2dict(v) for v in val] - else: - val = pb2dict(val) - if isinstance(val, bytes): - val = val.hex() - res[desc.name] = val - - # Fill in the default variables so we don't end up with changing - # keys all the time. If we are in a oneof we don't show them since - # they are just redundant. - if defaults: - for desc in p.DESCRIPTOR.fields: - if desc.name in res: - continue - if desc.label == FieldDescriptor.LABEL_REPEATED: - res[desc.name] = [] - elif desc.type == FieldDescriptor.TYPE_MESSAGE: - res[desc.name] = {} - else: - res[desc.name] = desc.default_value - - return res - -def dict2jsondict(d): - """Hexlify all binary fields so they can be serialized with `json.dumps` - """ - if isinstance(d, list): - return [dict2jsondict(e) for e in d] - elif isinstance(d, dict): - return {k: dict2jsondict(v) for k, v in d.items()} - elif isinstance(d, (bytes, bytearray)): - return d.hex() - else: - return d - - -def pbprint(pb): - dta = pb2dict(pb) - dta = dict2jsondict(dta) - print(json.dumps(dta)) - - -@click.group() -@click.option('--testenv', is_flag=True) -@click.option('--hsmd/--no-hsmd', default=True) -@click.pass_context -def cli(ctx, testenv, hsmd): - - # Disable hsmd if we explicitly get told to run it in the - # foreground - nohsmd_subcmds = ['scheduler', 'hsmd'] - hsmd = hsmd and (ctx.invoked_subcommand not in nohsmd_subcmds) - - if testenv: - os.environ.update(env.test) - else: - os.environ.update(env.prod) - - if ctx.obj is None: - ctx.obj = Context(start_hsmd=hsmd) - - -@cli.group() -def scheduler(): - pass - - -@scheduler.command() -@click.option("--network", type=str, default="testnet") -@click.option("--invite", type=str, default=None) -@click.pass_context -def register(ctx, network, invite): - # Reinitialize the signer with the right network, so register will pick that up - signer = Signer(creds=ctx.obj.creds, network=network) - node_id = ctx.obj.node_id - hex_node_id = hexlify(node_id).decode("ASCII") - logger.debug(f"Registering new node with node_id={hex_node_id} for {network}") - # Reinitialize the Scheduler with the passed network for register. - scheduler = Scheduler(network=network, creds=ctx.obj.scheduler.creds) - res = scheduler.register(signer.inner, invite_code=invite) - - with open("credentials.gfs", "wb") as f: - f.write(res.creds) - - with open("device-key.pem", "w") as f: - f.write(res.device_key) - - with open("device.crt", "w") as f: - f.write(res.device_cert) - - with open("ca.pem", "wb") as f: - f.write(env.ca_pem) - - pbprint(res) - - -@scheduler.command() -@click.pass_context -def recover(ctx): - signer = Signer(Creds()) - node_id = ctx.obj.node_id - logger.debug(f"Recovering access to node_id={hexlify(node_id).decode('ASCII')}") - scheduler = ctx.obj.scheduler - - res = scheduler.recover(signer.inner) - - with open("credentials.gfs", "wb") as f: - f.write(res.creds) - - with open("device-key.pem", "w") as f: - f.write(res.device_key) - - with open("device.crt", "w") as f: - f.write(res.device_cert) - - with open("ca.pem", "wb") as f: - f.write(env.ca_pem) - - pbprint(res) - -@scheduler.command() -@click.pass_context -def upgradecreds(ctx): - signer = Signer(Creds()) - creds = ctx.obj.creds.creds.upgrade(ctx.obj.scheduler.inner, signer.inner.inner) - - with open("credentials.gfs", "wb") as f: - f.write(creds.to_bytes()) - - -@scheduler.command() -@click.pass_context -def ping(ctx): - node_id = ctx.obj.node_id - pbprint(ctx.obj.scheduler.get_node_info()) - - -@scheduler.command() -@click.pass_context -def schedule(ctx): - grpc_uri = os.environ.get("GL_SCHEDULER_GRPC_URI") - node_id = ctx.obj.node_id - logger.info(f"Scheduling {node_id.hex()} with scheduler {grpc_uri}") - scheduler = ctx.obj.scheduler - try: - res = scheduler.schedule() - pbprint(res) - except ValueError as e: - raise click.ClickException(message=e.args[0]) - - -@scheduler.command() -@click.argument("name", required=True) -@click.option("--description", type=str, default="", help="A description of the device purpose.") -@click.option("--restrictions", type=str, default="", help="A set of restrictions used to restrict the devices access.") -@click.pass_context -def pair_device(ctx, name, description, restrictions): - """Pair a signer-less device with a greenlight node. - - """ - p_client = NewDeviceClient() - session = p_client.pair_device(name, description, restrictions) - i_session = iter(session) - - qr_data = next(i_session) - click.echo(f"Share this with the attestation device: {qr_data}") - - res = next(i_session) - assert isinstance(res, schedpb.PairDeviceResponse) - click.echo(f"Pairing session {res.device_id} completed") - with open("credentials.gfs", "wb") as f: - f.write(res.creds) - - -@scheduler.command() -@click.argument("pairing_data", required=True) -@click.pass_context -def approve_pairing(ctx, pairing_data): - """Approve a pairing request from a signer-less device. - Fetches the pairing data from the servers and asks for user input to confirm the pairing request. - """ - device_id = pairing_data.split(':')[1] - # p_client = AttestationDeviceClient(Creds()) - p_client = AttestationDeviceClient(Creds().creds) - try: - pairing_data = p_client.get_pairing_data(device_id) - except Exception as e: - click.echo(f"Could not get pairing data: {e}") - sys.exit(1) - - click.echo(f"Found pairing request {device_id} with data: {pairing_data}") - - m_valid = p_client.verify_pairing_data(pairing_data) - if m_valid is not None: - click.echo(f"Pairing data is invalid {m_valid}") - sys.exit(1) - - m_attestation = f""" - The following device requests attestation: - id: {pairing_data.device_id} - name: {pairing_data.device_name} - description: {pairing_data.description} - restrictions: {pairing_data.restrictions} - """ - - click.echo(m_attestation) - if click.confirm(f"Do you want to grant the device access to your node with the given restrictions?", default=False): - click.echo("Attestating device") - try: - p_client.approve_pairing( - pairing_data.device_id, - pairing_data.device_name, - pairing_data.restrictions - ) - sys.exit(0) - except Exception as e: - click.echo(f"Could not approve device {e}") - sys.exit(1) - - click.echo("") - sys.exit(0) - - -@cli.command() -@click.pass_context -def hsmd(ctx): - """Run the hsmd against the scheduler.""" - signer = Signer(Creds()) - signer_handle = signer.inner.run_in_thread() - - def signal_handler(_signal, _frame): - signer_handle.shutdown() - sys.exit(0) - - signal.signal(signal.SIGINT, signal_handler) - - while True: - signal.pause() - - -@cli.command() -@click.pass_context -def getinfo(ctx) -> None: - node = ctx.obj.get_node() - res = node.get_info() - pbprint(res) - - -@cli.command() -@click.pass_context -def stop(ctx) -> None: - node = ctx.obj.get_node() - res = node.stop() - print("Node shut down") - - -@cli.command() -@click.argument("id", type=str) -@click.argument("host", required=False, type=str) -@click.argument("port", required=False, type=int) -@click.pass_context -def connect(ctx, id: str, host: Optional[str], port: Optional[int]): - node = ctx.obj.get_node() - res = node.connect_peer(node_id=id, host=host, port=port) - pbprint(res) - - -@cli.command() -#@click.argument("node_id", required=False) -@click.pass_context -def listpeers(ctx): - node = ctx.obj.get_node() - res = node.list_peers() - pbprint(res) - - -@cli.command() -@click.pass_context -def listclosedchannels(ctx): - node = ctx.obj.get_node() - res = node.list_closed_channels() - pbprint(res) - - -@cli.command() -@click.argument("string", type=str) -@click.pass_context -def decode(ctx, string: str): - node = ctx.obj.get_node() - res = node.decode(string) - pbprint(res) - - -@cli.command() -@click.argument("bolt11", type=str) -@click.argument("description", required=False, type=str) -@click.pass_context -def decodepay(ctx, bolt11: str, description: Optional[str] = None): - node = ctx.obj.get_node() - res = node.decodepay(bolt11=bolt11, description=description) - pbprint(res) - - -@cli.command() -@click.argument("node_id") -@click.pass_context -def disconnect(ctx, node_id): - node = ctx.obj.get_node() - res = node.disconnect_peer(node_id) - pbprint(res) - - -@cli.command() -@click.pass_context -def newaddr(ctx): - node = ctx.obj.get_node() - res = node.new_address() - pbprint(res) - - -@cli.command() -#@click.option("--minconf", required=False, type=int) -@click.pass_context -def listfunds(ctx): - node = ctx.obj.get_node() - res = node.list_funds() - pbprint(res) - - -@cli.command() -@click.argument("destination") -@click.argument("amount", type=AmountType()) -@click.option("--minconf", required=False, type=int) -@click.pass_context -def withdraw(ctx, destination, amount, minconf=1): - node = ctx.obj.get_node() - res = node.withdraw(destination, amount, minconf) - pbprint(res) - - -@cli.command() -@click.argument("nodeid") -@click.argument("amount", type=AmountOrAllType()) -@click.option("--minconf", required=False, type=int, default=1) -@click.pass_context -def fundchannel(ctx, nodeid, amount, minconf): - node = ctx.obj.get_node() - nodeid = bytes.fromhex(nodeid) - res = node.fund_channel( - id=nodeid, - amount=amount, - announce=False, - minconf=minconf, - ) - pbprint(res) - - -@cli.command() -@click.argument("peer_id") -@click.option("--timeout", required=False, type=int) -@click.option("--address", required=False, type=str) -@click.pass_context -def close(ctx, peer_id, timeout=None, address=None): - node = ctx.obj.get_node() - res = node.close_channel(peer_id, unilateraltimeout=timeout, destination=address) - pbprint(res) - - -@cli.command() -@click.argument("label") -@click.argument("amount", required=False, type=AmountOrAnyType()) -@click.option("--description", required=False, type=str) -@click.pass_context -def invoice(ctx, label, amount=None, description=None): - node = ctx.obj.get_node() - if amount is None: - amount = Amount(any=True) - - args = { - "label": label, - "amount_msat": amount, - } - args["description"] = description if description is not None else "" - - res = node.invoice(**args) - pbprint(res) - - -@cli.command() -@click.argument("invoice") -@click.pass_context -@click.option("--amount", required=False, type=AmountType()) -@click.option("--timeout", required=False, type=int) -def pay(ctx, invoice, amount=None, timeout=0): - node = ctx.obj.get_node() - res = node.pay(bolt11=invoice, amount_msat=amount, retry_for=timeout) - pbprint(res) - - -@cli.command() -@click.pass_context -def stream_incoming(ctx): - """Listen for incoming payments and print details to stdout. - """ - node = ctx.obj.get_node() - for e in node.stream_incoming(): - pbprint(e) - sys.stdout.flush() - - -@cli.command() -@click.argument('destination') -@click.argument('amount', type=AmountType()) -@click.option("--label", required=False) -@click.option("--routehints", required=False) -@click.option("--extratlvs", required=False) -@click.pass_context -def keysend(ctx, destination, amount, label, routehints, extratlvs): - """Send a spontaneous payment to the specified node. - """ - # Convert the advanced arguments. - if routehints is not None: - arr = json.loads(routehints) - routehints = [] - if not isinstance(arr, list): - raise click.UsageError("Routehints must be a JSON encoded list of lists of routehint hops") - for rharr in arr: - routehint = pb.Routehint(hops=[]) - if not isinstance(rharr, list): - raise click.UsageError("Routehints must be a JSON encoded list of lists of routehint hops") - for rh in rharr: - rh['node_id'] = unhexlify(rh['node_id']) - r = pb.RoutehintHop( - **rh - ) - routehint.hops.append(r) - routehints.append(routehint) - - if extratlvs is not None: - arr = json.loads(extratlvs) - extratlvs = [] - if not isinstance(extratlvs, list): - raise click.UsageError('--extratlvs must be a JSON encoded list of `{"type": 1234, "value": "DECAFBAD"}` entries') - for a in arr: - t = a['type'] - v = unhexlify(a['value']) - extratlvs.append(pb.TlvField( - type=t, - value=v, - )) - - print(extratlvs) - node = ctx.obj.get_node() - res = node.keysend( - destination=destination, - amount=amount, - label=label, - routehints=routehints, - extratlvs=extratlvs - ) - pbprint(res) - - -@cli.command() -@click.pass_context -def log(ctx): - node = ctx.obj.get_node() - - def tail(node): - for entry in node.stream_log(): - print(entry.line.strip()) - - t = threading.Thread(target=tail, args=(node, ), daemon=True) - t.start() - t.join() - - -@cli.command() -@click.pass_context -def listinvoices(ctx): - node = ctx.obj.get_node() - res = node.list_invoices() - pbprint(res) - - -@cli.command() -@click.pass_context -def listpays(ctx): - node = ctx.obj.get_node() - res = node.listpays() - pbprint(res) - - -@cli.command() -def version(): - import glclient - print(glclient.__version__) - - -@scheduler.command() -@click.pass_context -def export(ctx): - print(""" - You are about to export your node from greenlight. This will disable the node - on greenlight, create an encrypted backup and serve that backup back to you. - - This is intended for users that would like to offboard and run their node on - their own infrastructure. Due to the security model of Lightning Nodes, we - will not be able to reactivate the node on greenlight. Please configure and - test your infrastructure before exporting, to prevent prolonged downtime. - """) - answer = input("Do you want to continue (y/N)?") - if answer.lower() != "y": - print("Cancelling the export...") - return - - scheduler = ctx.obj.scheduler - exp = scheduler.export_node() - print(exp) - # TODO Download - # TODO Decrypt - # TODO Print about next steps - - -if __name__ == "__main__": - cli() diff --git a/tools/glcli/glcli/environment.py b/tools/glcli/glcli/environment.py deleted file mode 100644 index 38dda936e..000000000 --- a/tools/glcli/glcli/environment.py +++ /dev/null @@ -1,91 +0,0 @@ -import os - -ca_pem = b"""-----BEGIN CERTIFICATE----- -MIICYjCCAgigAwIBAgIUDEw2osNBr+H1o4WCvPSRIjNzUzQwCgYIKoZIzj0EAwIw -fjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh -biBGcmFuY2lzY28xFDASBgNVBAoTC0Jsb2Nrc3RyZWFtMR0wGwYDVQQLExRDZXJ0 -aWZpY2F0ZUF1dGhvcml0eTENMAsGA1UEAxMER0wgLzAeFw0yMTA0MjYxNzE0MDBa -Fw0zMTA0MjQxNzE0MDBaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y -bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQKEwtCbG9ja3N0cmVh -bTEdMBsGA1UECxMUQ2VydGlmaWNhdGVBdXRob3JpdHkxDTALBgNVBAMTBEdMIC8w -WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATp83k4SqQ5geGRpIpDuU20vrZz8qJ8 -eBDYbW3nIlC8UM/PzVBSNA/MqWlAamB3YGK+VlgsEMbeOUWEM4c9ztVlo2QwYjAO -BgNVHQ8BAf8EBAMCAaYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIG -A1UdEwEB/wQIMAYBAf8CAQMwHQYDVR0OBBYEFM6ha+o75cd25WbWGqXGR1WKTikj -MAoGCCqGSM49BAMCA0gAMEUCIGBkjyp1Nd/m/b3jEAUmxAisqCahuQUPuyQrIwo0 -ZF/9AiEAsZ8qZfkUZH2Ya7y6ccFTDps/ahsFWSrRao8ru3yhhrs= ------END CERTIFICATE-----""" - -users_nobody_crt = b"""-----BEGIN CERTIFICATE----- -MIICpzCCAk6gAwIBAgIUdSk1NrVicDLl62zNFJ6Re6Bc3wowCgYIKoZIzj0EAwIw -gYMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T -YW4gRnJhbmNpc2NvMRQwEgYDVQQKEwtCbG9ja3N0cmVhbTEdMBsGA1UECxMUQ2Vy -dGlmaWNhdGVBdXRob3JpdHkxEjAQBgNVBAMTCUdMIC91c2VyczAeFw0yMTA0MjYx -NzE0MDBaFw0zMTA0MjQxNzE0MDBaMIGKMQswCQYDVQQGEwJVUzETMBEGA1UECBMK -Q2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEUMBIGA1UEChMLQmxv -Y2tzdHJlYW0xHTAbBgNVBAsTFENlcnRpZmljYXRlQXV0aG9yaXR5MRkwFwYDVQQD -ExBHTCAvdXNlcnMvbm9ib2R5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsozl -E1LGXLxtfc8Ljf7fQh2YBoTqQiYHGDL44xLG9ey8YZfTYulYA6nl1GjhYFMJA3sM -mq5pdsmNaA7+gna8VaOBljCBkzAOBgNVHQ8BAf8EBAMCAaYwHQYDVR0lBBYwFAYI -KwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFK26BLJr -2nWbiI3/bRnCc9YFXgnvMB8GA1UdIwQYMBaAFE0O9xdTDG6TosQbXT6KDyYGwyWU -MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjOPQQDAgNHADBEAiBo3/V5vjAf -/y8PjUt1lEe2j4RiiJ2dcjMpj+05m2ZCSwIgHHCKetqUTLwWvukuGyXcDTxSqWSy -QyMXXrntwWHuvpA= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICijCCAjGgAwIBAgIUJ06syYB1TPRbSmTD4UCpT0PmA+UwCgYIKoZIzj0EAwIw -fjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh -biBGcmFuY2lzY28xFDASBgNVBAoTC0Jsb2Nrc3RyZWFtMR0wGwYDVQQLExRDZXJ0 -aWZpY2F0ZUF1dGhvcml0eTENMAsGA1UEAxMER0wgLzAeFw0yMTA0MjYxNzE0MDBa -Fw0zMTA0MjQxNzE0MDBaMIGDMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEUMBIGA1UEChMLQmxvY2tzdHJl -YW0xHTAbBgNVBAsTFENlcnRpZmljYXRlQXV0aG9yaXR5MRIwEAYDVQQDEwlHTCAv -dXNlcnMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWlNi+9P8ZdRfaP1VOOMb9 -e+VSugDxwvN41ZTdq5aQ1yTXHx2fcMyowoDaSCBg44rzPJ/TDOrIH2WWWCaHmHgT -o4GGMIGDMA4GA1UdDwEB/wQEAwIBpjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB -BQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBAzAdBgNVHQ4EFgQUTQ73F1MMbpOixBtd -PooPJgbDJZQwHwYDVR0jBBgwFoAUzqFr6jvlx3blZtYapcZHVYpOKSMwCgYIKoZI -zj0EAwIDRwAwRAIgJvgJ8ehKx0VenMyUT/MRXlmClARc1Np39/Fbp4GIbd8CIGhk -MKVcDA5iuQZ7xhZU1S8POh1L9uT35UkE7+xmGNjr ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIICYjCCAgigAwIBAgIUDEw2osNBr+H1o4WCvPSRIjNzUzQwCgYIKoZIzj0EAwIw -fjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh -biBGcmFuY2lzY28xFDASBgNVBAoTC0Jsb2Nrc3RyZWFtMR0wGwYDVQQLExRDZXJ0 -aWZpY2F0ZUF1dGhvcml0eTENMAsGA1UEAxMER0wgLzAeFw0yMTA0MjYxNzE0MDBa -Fw0zMTA0MjQxNzE0MDBaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y -bmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQKEwtCbG9ja3N0cmVh -bTEdMBsGA1UECxMUQ2VydGlmaWNhdGVBdXRob3JpdHkxDTALBgNVBAMTBEdMIC8w -WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATp83k4SqQ5geGRpIpDuU20vrZz8qJ8 -eBDYbW3nIlC8UM/PzVBSNA/MqWlAamB3YGK+VlgsEMbeOUWEM4c9ztVlo2QwYjAO -BgNVHQ8BAf8EBAMCAaYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIG -A1UdEwEB/wQIMAYBAf8CAQMwHQYDVR0OBBYEFM6ha+o75cd25WbWGqXGR1WKTikj -MAoGCCqGSM49BAMCA0gAMEUCIGBkjyp1Nd/m/b3jEAUmxAisqCahuQUPuyQrIwo0 -ZF/9AiEAsZ8qZfkUZH2Ya7y6ccFTDps/ahsFWSrRao8ru3yhhrs= ------END CERTIFICATE-----""" -users_nobody_key = b"""-----BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgmA2Srb58ZaDIW6sR -B+1E6X8UnxMDeJPsnB4LVgpJyfuhRANCAASyjOUTUsZcvG19zwuN/t9CHZgGhOpC -JgcYMvjjEsb17Lxhl9Ni6VgDqeXUaOFgUwkDewyarml2yY1oDv6CdrxV ------END PRIVATE KEY-----""" - -prod = { - # Used by glcli - "GL_GRPC_URI": "scheduler.gl.blckstrm.com:443", - - # Used by hagrid internally - "GL_SCHEDULER_GRPC_URI": "https://scheduler.gl.blckstrm.com:443", - - "GL_CERT_PATH": ".", -} - -test = { - # Used by glcli - "GL_GRPC_URI": "scheduler.testing.gl.blckstrm.com:443", - - # Used by hagrid internally - "GL_SCHEDULER_GRPC_URI": "https://scheduler.testing.gl.blckstrm.com:443", - - "GL_CERT_PATH": ".", -} diff --git a/tools/glcli/pyproject.toml b/tools/glcli/pyproject.toml deleted file mode 100644 index 1083b8651..000000000 --- a/tools/glcli/pyproject.toml +++ /dev/null @@ -1,36 +0,0 @@ -[tool.poetry] -name = "greenlight-cli" -version = "0.2.0" -description = "" -authors = ["Christian Decker "] -license = "MIT" - -packages = [ - { include = "glcli" }, -] - -[tool.poetry.dependencies] -python = "^3.8" -click = "^8" -grpcio = "^1" -protobuf = "^5" -gl-client = "0.2.0" - -[tool.poetry.group.dev.dependencies] -mypy-protobuf = "^3.5.0" -mypy = "^1.7.0" -typed-ast = "^1.5.5" -types-protobuf = "^4.24.0.4" -gl-client = { path = "../../libs/gl-client-py", develop = false} - -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry.scripts] -glcli = 'glcli.cli:cli' - -[tool.mypy] - -[[tool.mypy.overrides]] -module = 'glcli' diff --git a/tools/glcli/tests/__init__.py b/tools/glcli/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000