From c4cbcbe4d2971d2108cfe18be13145680ae79305 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Thu, 23 Apr 2026 00:17:36 +0200
Subject: [PATCH 01/56] tests: update python min to 3.10
---
tests/pyproject.toml | 8 +-
tests/uv.lock | 749 ++++++++++---------------------------------
2 files changed, 173 insertions(+), 584 deletions(-)
diff --git a/tests/pyproject.toml b/tests/pyproject.toml
index 22e8170..874fadb 100644
--- a/tests/pyproject.toml
+++ b/tests/pyproject.toml
@@ -1,7 +1,7 @@
[project]
name = "cln-nip47"
version = "0.1.0"
-requires-python = ">=3.9.2"
+requires-python = ">=3.10"
description = "python dependencies for running tests"
[dependency-groups]
@@ -11,7 +11,7 @@ dev = [
"pytest-xdist>=3.7,<4",
"pytest-timeout>=2.4,<3",
"nostr-sdk>=0.44",
- "pyln-testing>=25.2",
- "pyln-client>=25.2",
- "pyln-proto>=25.2",
+ "pyln-testing>=25.5",
+ "pyln-client>=25.5",
+ "pyln-proto>=25.5",
]
diff --git a/tests/uv.lock b/tests/uv.lock
index dcf72d3..6c3395a 100644
--- a/tests/uv.lock
+++ b/tests/uv.lock
@@ -1,10 +1,6 @@
version = 1
revision = 3
-requires-python = ">=3.9.2"
-resolution-markers = [
- "python_full_version >= '3.10'",
- "python_full_version < '3.10'",
-]
+requires-python = ">=3.10"
[[package]]
name = "asn1crypto"
@@ -126,19 +122,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a4/a0/fe5dbdfadcba2314551614d023db100e3aea7b09da2cdcbf1386f5c797a6/bitarray-3.8.1-cp314-cp314t-win32.whl", hash = "sha256:cf99e36c0f6ae5643ecef7ad7e1194aeb4a9798d9cff60b20ac041533fa6db0a", size = 144160, upload-time = "2026-04-02T16:28:12.702Z" },
{ url = "https://files.pythonhosted.org/packages/4e/0a/e95ed44f6d89e63ed666755fc0773223b10df0058d5de30d529f4cf35948/bitarray-3.8.1-cp314-cp314t-win_amd64.whl", hash = "sha256:9befda0dbd27ed95fba1c26be4bf98a49ba166b3c91beb5fc04364c130ce950c", size = 150852, upload-time = "2026-04-02T16:28:14.149Z" },
{ url = "https://files.pythonhosted.org/packages/0f/90/454b88b193743b4cd0fce0819a11b1c43b7f629cb2533f6ddc62cbb5e097/bitarray-3.8.1-cp314-cp314t-win_arm64.whl", hash = "sha256:4b7d7d10a1c82050efbb9a83d7a43974f70cf8f021afb86463b42e4ac4e5a46b", size = 147343, upload-time = "2026-04-02T16:28:15.632Z" },
- { url = "https://files.pythonhosted.org/packages/f7/f8/ea06b93a45cfe8ee5354872901cce708a13df9c7f39dfd2ef15f1ae95110/bitarray-3.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cac0145491619287ff893853bf3ca4d98d5ef94b617271184a5af68a06ac301a", size = 149077, upload-time = "2026-04-02T16:28:38.465Z" },
- { url = "https://files.pythonhosted.org/packages/bb/1b/b23c5dae859dfff47b29df58c55a6ab8321ef5ea62000624f5fdb11de166/bitarray-3.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fd68db1a0f5d9374a7b735414efe48d2b3ecbf0adea39299bb48030988f16149", size = 146168, upload-time = "2026-04-02T16:28:40.05Z" },
- { url = "https://files.pythonhosted.org/packages/3b/db/4634c969ec9302f13a410a051a25482beb1122729e92ac67267092b43023/bitarray-3.8.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9adacf6fdadeeb96e6c902aef08d02d2f45429fdbf0a75b80307e435156066f8", size = 322386, upload-time = "2026-04-02T16:28:41.715Z" },
- { url = "https://files.pythonhosted.org/packages/81/2e/750330e9896f95fb231f5ae915359bacddb936ff34604fa2a367743b38eb/bitarray-3.8.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d7d5f7f6f80388ce94849775da5f4082ab5e123e259972961970e190d60f5d2b", size = 350659, upload-time = "2026-04-02T16:28:43.39Z" },
- { url = "https://files.pythonhosted.org/packages/86/40/67181c6482d04c720e11947bd2d280d65f136383a2595aa599e738796757/bitarray-3.8.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3a5e594b4be2dbfe021cee8d6d7d96e9bb19dee7ed7be351f43bca7a0619b978", size = 361573, upload-time = "2026-04-02T16:28:45.503Z" },
- { url = "https://files.pythonhosted.org/packages/c4/38/e634dd0256ec0b1bd6c321e6ac207f19e540a9ca0efcabbfcbe21b97331a/bitarray-3.8.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:190a3482818d69faef176171c7cae10d55cb4dd0c686b5aced7f592b5e5591c1", size = 329626, upload-time = "2026-04-02T16:28:47.576Z" },
- { url = "https://files.pythonhosted.org/packages/82/22/a7cf6e9406c5e16cace3fdcbb1c8bc03fb7a538c682e2c1115d3af243503/bitarray-3.8.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4fb869faf4b484cb213199ced1e2732091559107637d429fc25d0a9731f5f630", size = 320007, upload-time = "2026-04-02T16:28:49.226Z" },
- { url = "https://files.pythonhosted.org/packages/d6/e4/22b843b4955eeceabfe564d069ff8569d6365e9d0d435a3bd10c344d50f9/bitarray-3.8.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:70f70ea138e69ec3159e4a38fef52443cb8eb81388aeb241b273265ea16387c5", size = 348717, upload-time = "2026-04-02T16:28:50.996Z" },
- { url = "https://files.pythonhosted.org/packages/ba/8f/a90f460c8034f2e39f577c016b3c01757c7d418b1184e837a15299ec92ff/bitarray-3.8.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0256d57e294414bfe4fec4f852fd1d9ae361228c71b082332bf81c8b8fc69f80", size = 345234, upload-time = "2026-04-02T16:28:52.695Z" },
- { url = "https://files.pythonhosted.org/packages/d2/ca/8b525f2cb1378d263b8c4f532d06243d34bdcce83a18125b4f51a31624b3/bitarray-3.8.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ef123b6aead12e0784f72970e8d94a96ac0d0aa4438c7ab9235e2f8669a0a5ae", size = 326386, upload-time = "2026-04-02T16:28:54.638Z" },
- { url = "https://files.pythonhosted.org/packages/54/c5/3f0e58127a23be13ac7041579a41ba3a31bbea1659ea26dd3251c942cb3c/bitarray-3.8.1-cp39-cp39-win32.whl", hash = "sha256:c263ed9922942353a954cfbcd5f81b7626c0e20dc7f3e53d4926e8bc560ab845", size = 143145, upload-time = "2026-04-02T16:28:56.431Z" },
- { url = "https://files.pythonhosted.org/packages/9f/2b/b8b125b65891563ddca90d4a53cf47d7128fda40a881825fe863d2e39da6/bitarray-3.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:7c133052737c7c75bfa49f5ba71918166fe988995b26a0d2f263a79bf8fed58a", size = 149888, upload-time = "2026-04-02T16:28:58.046Z" },
- { url = "https://files.pythonhosted.org/packages/b0/8a/132afaf9deb6802b51eb2c72f004348c440bbb082d9766788f32a8741604/bitarray-3.8.1-cp39-cp39-win_arm64.whl", hash = "sha256:20e412527ec1aac7e3a6542b32a9c34bb852c954676b05008f0e3d58c390a0ac", size = 146697, upload-time = "2026-04-02T16:28:59.797Z" },
]
[[package]]
@@ -165,11 +148,11 @@ wheels = [
[[package]]
name = "certifi"
-version = "2026.2.25"
+version = "2026.4.22"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" },
+ { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" },
]
[[package]]
@@ -177,8 +160,7 @@ name = "cffi"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pycparser", version = "2.23", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' and implementation_name != 'PyPy'" },
- { name = "pycparser", version = "3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' and implementation_name != 'PyPy'" },
+ { name = "pycparser", marker = "implementation_name != 'PyPy'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
wheels = [
@@ -253,18 +235,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
- { url = "https://files.pythonhosted.org/packages/c0/cc/08ed5a43f2996a16b462f64a7055c6e962803534924b9b2f1371d8c00b7b/cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf", size = 184288, upload-time = "2025-09-08T23:23:48.404Z" },
- { url = "https://files.pythonhosted.org/packages/3d/de/38d9726324e127f727b4ecc376bc85e505bfe61ef130eaf3f290c6847dd4/cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7", size = 180509, upload-time = "2025-09-08T23:23:49.73Z" },
- { url = "https://files.pythonhosted.org/packages/9b/13/c92e36358fbcc39cf0962e83223c9522154ee8630e1df7c0b3a39a8124e2/cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c", size = 208813, upload-time = "2025-09-08T23:23:51.263Z" },
- { url = "https://files.pythonhosted.org/packages/15/12/a7a79bd0df4c3bff744b2d7e52cc1b68d5e7e427b384252c42366dc1ecbc/cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165", size = 216498, upload-time = "2025-09-08T23:23:52.494Z" },
- { url = "https://files.pythonhosted.org/packages/a3/ad/5c51c1c7600bdd7ed9a24a203ec255dccdd0ebf4527f7b922a0bde2fb6ed/cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534", size = 203243, upload-time = "2025-09-08T23:23:53.836Z" },
- { url = "https://files.pythonhosted.org/packages/32/f2/81b63e288295928739d715d00952c8c6034cb6c6a516b17d37e0c8be5600/cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f", size = 203158, upload-time = "2025-09-08T23:23:55.169Z" },
- { url = "https://files.pythonhosted.org/packages/1f/74/cc4096ce66f5939042ae094e2e96f53426a979864aa1f96a621ad128be27/cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63", size = 216548, upload-time = "2025-09-08T23:23:56.506Z" },
- { url = "https://files.pythonhosted.org/packages/e8/be/f6424d1dc46b1091ffcc8964fa7c0ab0cd36839dd2761b49c90481a6ba1b/cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2", size = 218897, upload-time = "2025-09-08T23:23:57.825Z" },
- { url = "https://files.pythonhosted.org/packages/f7/e0/dda537c2309817edf60109e39265f24f24aa7f050767e22c98c53fe7f48b/cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65", size = 211249, upload-time = "2025-09-08T23:23:59.139Z" },
- { url = "https://files.pythonhosted.org/packages/2b/e7/7c769804eb75e4c4b35e658dba01de1640a351a9653c3d49ca89d16ccc91/cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322", size = 218041, upload-time = "2025-09-08T23:24:00.496Z" },
- { url = "https://files.pythonhosted.org/packages/aa/d9/6218d78f920dcd7507fc16a766b5ef8f3b913cc7aa938e7fc80b9978d089/cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a", size = 172138, upload-time = "2025-09-08T23:24:01.7Z" },
- { url = "https://files.pythonhosted.org/packages/54/8f/a1e836f82d8e32a97e6b29cc8f641779181ac7363734f12df27db803ebda/cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9", size = 182794, upload-time = "2025-09-08T23:24:02.943Z" },
]
[[package]]
@@ -369,22 +339,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" },
{ url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" },
{ url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" },
- { url = "https://files.pythonhosted.org/packages/01/1b/ef725f8eb19b5a261b30f78efa9252ef9d017985cb499102f6f49834cd12/charset_normalizer-3.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:177a0ba5f0211d488e295aaf82707237e331c24788d8d76c96c5a41594723217", size = 299121, upload-time = "2026-04-02T09:28:14.372Z" },
- { url = "https://files.pythonhosted.org/packages/a3/22/2f12878fbc680fbbb52386cd39a379801f62eaca74fc8b323381325f0f04/charset_normalizer-3.4.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e0d51f618228538a3e8f46bd246f87a6cd030565e015803691603f55e12afb5", size = 200612, upload-time = "2026-04-02T09:28:16.162Z" },
- { url = "https://files.pythonhosted.org/packages/bc/b6/10c84e789126ca97d4a7228863a30481e786980a8b8cfcbf4f30658ca63c/charset_normalizer-3.4.7-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:14265bfe1f09498b9d8ec91e9ec9fa52775edf90fcbde092b25f4a33d444fea9", size = 221041, upload-time = "2026-04-02T09:28:17.554Z" },
- { url = "https://files.pythonhosted.org/packages/21/7b/c414866a138400b2e81973d006da7f694cfeaf895ef07d2cba9a8743841a/charset_normalizer-3.4.7-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87fad7d9ba98c86bcb41b2dc8dbb326619be2562af1f8ff50776a39e55721c5a", size = 216323, upload-time = "2026-04-02T09:28:18.863Z" },
- { url = "https://files.pythonhosted.org/packages/2e/92/bdcf94997e06b223d826df3abed45a5ad6e17f609b7df9d25cd23b5bde30/charset_normalizer-3.4.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f22dec1690b584cea26fade98b2435c132c1b5f68e39f5a0b7627cd7ae31f1dc", size = 208419, upload-time = "2026-04-02T09:28:20.332Z" },
- { url = "https://files.pythonhosted.org/packages/1a/64/3f9142293c88b1b10e199649ed1330f070c2a68e305335a5819fa7f25fa7/charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_armv7l.whl", hash = "sha256:d61f00a0869d77422d9b2aba989e2d24afa6ffd552af442e0e58de4f35ea6d00", size = 195016, upload-time = "2026-04-02T09:28:21.657Z" },
- { url = "https://files.pythonhosted.org/packages/c1/d1/d8a6b7dd5c5636b76ce0d080bc57d8e56c7bbd6bc2ac941529a35e41d84a/charset_normalizer-3.4.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6370e8686f662e6a3941ee48ed4742317cafbe5707e36406e9df792cdb535776", size = 206115, upload-time = "2026-04-02T09:28:23.259Z" },
- { url = "https://files.pythonhosted.org/packages/dd/8c/60ebe912379627d023eb96995b40bc50308729f210f43d66109ca0a7bbd2/charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6c5863edfbe888d9eff9c8b8087354e27618d9da76425c119293f11712a6319", size = 204022, upload-time = "2026-04-02T09:28:24.779Z" },
- { url = "https://files.pythonhosted.org/packages/d5/2a/41816ceda78a551cbfdfbeab6f3891152b0e3f758ce6580c2c18c829f774/charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:ed065083d0898c9d5b4bbec7b026fd755ff7454e6e8b73a67f8c744b13986e24", size = 195914, upload-time = "2026-04-02T09:28:26.181Z" },
- { url = "https://files.pythonhosted.org/packages/8f/9b/7c7f4b7f11525fcbdfba752455314ac60646bae91cdd671d531c1f7a97c6/charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2cd4a60d0e2fb04537162c62bbbb4182f53541fe0ede35cdf270a1c1e723cc42", size = 222159, upload-time = "2026-04-02T09:28:27.504Z" },
- { url = "https://files.pythonhosted.org/packages/9f/57/301682e7469bdbfa2ce219a804f0668b2266ab8520570d85d3b3ef483ea3/charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:813c0e0132266c08eb87469a642cb30aaff57c5f426255419572aaeceeaa7bf4", size = 206154, upload-time = "2026-04-02T09:28:28.848Z" },
- { url = "https://files.pythonhosted.org/packages/20/ec/90339ff5cdc598b265748c1f231c7d7fbd9123a92cee10f757e0b1448de4/charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:07d9e39b01743c3717745f4c530a6349eadbfa043c7577eef86c502c15df2c67", size = 217423, upload-time = "2026-04-02T09:28:30.248Z" },
- { url = "https://files.pythonhosted.org/packages/2e/e7/a7a6147f8e3375676309cf584b25c72a3bab784ea4085b0011fa07b23aeb/charset_normalizer-3.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c0f081d69a6e58272819b70288d3221a6ee64b98df852631c80f293514d3b274", size = 210604, upload-time = "2026-04-02T09:28:31.736Z" },
- { url = "https://files.pythonhosted.org/packages/1a/62/d9340c7a79c393e57807d7fb6c57e82060687891f81b74d3201958b919c1/charset_normalizer-3.4.7-cp39-cp39-win32.whl", hash = "sha256:8751d2787c9131302398b11e6c8068053dcb55d5a8964e114b6e196cf16cb366", size = 144631, upload-time = "2026-04-02T09:28:33.158Z" },
- { url = "https://files.pythonhosted.org/packages/21/e7/92901117e2ddc8facfe8235a3ecd4eb482185b2ad5d5b6606b37c1afea06/charset_normalizer-3.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:12a6fff75f6bc66711b73a2f0addfc4c8c15a20e805146a02d147a318962c444", size = 154710, upload-time = "2026-04-02T09:28:34.557Z" },
- { url = "https://files.pythonhosted.org/packages/cc/4f/e1fb138201ad9a32499dd9a98aa4a5a5441fbf7f56b52b619a54b7ee8777/charset_normalizer-3.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:bb8cc7534f51d9a017b93e3e85b260924f909601c3df002bcdb58ddb4dc41a5c", size = 143716, upload-time = "2026-04-02T09:28:35.908Z" },
{ url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" },
]
@@ -394,8 +348,7 @@ version = "10.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jaraco-functools" },
- { name = "more-itertools", version = "10.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "more-itertools", version = "11.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "more-itertools" },
]
sdist = { url = "https://files.pythonhosted.org/packages/08/7c/95c154177b16077de0fec1b821b0d8b3df2b59c5c7b3575a9c1bf52a437e/cheroot-10.0.0.tar.gz", hash = "sha256:59c4a1877fef9969b3c3c080caaaf377e2780919437853fc0d32a9df40b311f0", size = 148461, upload-time = "2023-05-20T15:34:09.67Z" }
wheels = [
@@ -404,32 +357,14 @@ wheels = [
[[package]]
name = "click"
-version = "8.1.8"
+version = "8.3.3"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
dependencies = [
- { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
+ { name = "colorama", marker = "sys_platform == 'win32'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" },
-]
-
-[[package]]
-name = "click"
-version = "8.3.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
-dependencies = [
- { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" },
]
[[package]]
@@ -444,8 +379,7 @@ dev = [
{ name = "pyln-proto" },
{ name = "pyln-testing" },
{ name = "pytest" },
- { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "pytest-asyncio" },
{ name = "pytest-timeout" },
{ name = "pytest-xdist" },
]
@@ -455,9 +389,9 @@ dev = [
[package.metadata.requires-dev]
dev = [
{ name = "nostr-sdk", specifier = ">=0.44" },
- { name = "pyln-client", specifier = ">=25.2" },
- { name = "pyln-proto", specifier = ">=25.2" },
- { name = "pyln-testing", specifier = ">=25.2" },
+ { name = "pyln-client", specifier = ">=25.5" },
+ { name = "pyln-proto", specifier = ">=25.5" },
+ { name = "pyln-testing", specifier = ">=25.5" },
{ name = "pytest", specifier = ">=7.4,<9" },
{ name = "pytest-asyncio", specifier = ">=0.23.8,<2" },
{ name = "pytest-timeout", specifier = ">=2.4,<3" },
@@ -504,16 +438,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/07/cd/e9bd4ca7d931653a35c74194da04191a9aecc54b8f48a554cd538dc810e4/coincurve-20.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0530b9dd02fc6f6c2916716974b79bdab874227f560c422801ade290e3fc5013", size = 1209392, upload-time = "2024-06-02T18:15:08.663Z" },
{ url = "https://files.pythonhosted.org/packages/99/54/260053f14f74b99b645084231e1c76994134ded49407a3bba23a8ffc0ff6/coincurve-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:eacf9c0ce8739c84549a89c083b1f3526c8780b84517ee75d6b43d276e55f8a0", size = 1198932, upload-time = "2024-06-02T18:15:10.786Z" },
{ url = "https://files.pythonhosted.org/packages/b4/b5/c465e09345dd38b9415f5d47ae7683b3f461db02fcc03e699b6b5687ab2b/coincurve-20.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:52a67bfddbd6224dfa42085c88ad176559801b57d6a8bd30d92ee040de88b7b3", size = 1193324, upload-time = "2024-06-02T18:15:12.511Z" },
- { url = "https://files.pythonhosted.org/packages/96/af/bcb965cfa8248035303e22c73ff481cd65d41b5bc3115b95cc5ca49f67e6/coincurve-20.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4870047704cddaae7f0266a549c927407c2ba0ec92d689e3d2b511736812a905", size = 1255631, upload-time = "2024-06-02T18:15:35.257Z" },
- { url = "https://files.pythonhosted.org/packages/8c/44/ce5011566ad0969d199fa2cf9f413700505d1ec7a9cb2a6e707b22e5dc50/coincurve-20.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81ce41263517b0a9f43cd570c87720b3c13324929584fa28d2e4095969b6015d", size = 1255531, upload-time = "2024-06-02T18:15:36.699Z" },
- { url = "https://files.pythonhosted.org/packages/11/bf/9ebd8689991bbef2b3e67e87b394e54d77476de0eb2949199e08a1a11433/coincurve-20.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:572083ccce6c7b514d482f25f394368f4ae888f478bd0b067519d33160ea2fcc", size = 1191926, upload-time = "2024-06-02T18:15:38.147Z" },
- { url = "https://files.pythonhosted.org/packages/b9/5a/c24218c701096eaa65ad3f1f87f674d2339c81f898c392cdfcb8a51065ca/coincurve-20.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee5bc78a31a2f1370baf28aaff3949bc48f940a12b0359d1cd2c4115742874e6", size = 1194361, upload-time = "2024-06-02T18:15:39.712Z" },
- { url = "https://files.pythonhosted.org/packages/d2/af/ec0ae57975cb9f1c8b207058a94f86c9526f3e96df799f8833acdcfed250/coincurve-20.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2895d032e281c4e747947aae4bcfeef7c57eabfd9be22886c0ca4e1365c7c1f", size = 1204656, upload-time = "2024-06-02T18:15:41.534Z" },
- { url = "https://files.pythonhosted.org/packages/ce/cd/c40e9419e7a9ac35f754b120aa7bdeac929f544079ade5d31b5e1c496cf6/coincurve-20.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d3e2f21957ada0e1742edbde117bb41758fa8691b69c8d186c23e9e522ea71cd", size = 1215294, upload-time = "2024-06-02T18:15:42.887Z" },
- { url = "https://files.pythonhosted.org/packages/55/c2/1cedcf828b35ea89e2501cb64ccc441c3f17bce9c95b2537a2c136258d24/coincurve-20.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c2baa26b1aad1947ca07b3aa9e6a98940c5141c6bdd0f9b44d89e36da7282ffa", size = 1204502, upload-time = "2024-06-02T18:15:44.759Z" },
- { url = "https://files.pythonhosted.org/packages/49/ef/7a6b50d8a14bae6974482900b06281fee3f82228401ae01efbf8d87ef4e4/coincurve-20.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7eacc7944ddf9e2b7448ecbe84753841ab9874b8c332a4f5cc3b2f184db9f4a2", size = 1209295, upload-time = "2024-06-02T18:15:46.162Z" },
- { url = "https://files.pythonhosted.org/packages/26/c5/f010fe5377d775084e91a213f63417df4b77d833ae69bfbcf00aa7ae7020/coincurve-20.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:c293c095dc690178b822cadaaeb81de3cc0d28f8bdf8216ed23551dcce153a26", size = 1198937, upload-time = "2024-06-02T18:15:48.049Z" },
- { url = "https://files.pythonhosted.org/packages/9e/a8/491506c17c911b69b171aa6340e8b70ec4ee42f6f42f93cd53db33c5d1ac/coincurve-20.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:11a47083a0b7092d3eb50929f74ffd947c4a5e7035796b81310ea85289088c7a", size = 1193323, upload-time = "2024-06-02T18:15:49.598Z" },
]
[[package]]
@@ -527,62 +451,62 @@ wheels = [
[[package]]
name = "cryptography"
-version = "46.0.6"
+version = "46.0.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a4/ba/04b1bd4218cbc58dc90ce967106d51582371b898690f3ae0402876cc4f34/cryptography-46.0.6.tar.gz", hash = "sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759", size = 750542, upload-time = "2026-03-25T23:34:53.396Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/47/93/ac8f3d5ff04d54bc814e961a43ae5b0b146154c89c61b47bb07557679b18/cryptography-46.0.7.tar.gz", hash = "sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5", size = 750652, upload-time = "2026-04-08T01:57:54.692Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/47/23/9285e15e3bc57325b0a72e592921983a701efc1ee8f91c06c5f0235d86d9/cryptography-46.0.6-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8", size = 7176401, upload-time = "2026-03-25T23:33:22.096Z" },
- { url = "https://files.pythonhosted.org/packages/60/f8/e61f8f13950ab6195b31913b42d39f0f9afc7d93f76710f299b5ec286ae6/cryptography-46.0.6-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30", size = 4275275, upload-time = "2026-03-25T23:33:23.844Z" },
- { url = "https://files.pythonhosted.org/packages/19/69/732a736d12c2631e140be2348b4ad3d226302df63ef64d30dfdb8db7ad1c/cryptography-46.0.6-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a", size = 4425320, upload-time = "2026-03-25T23:33:25.703Z" },
- { url = "https://files.pythonhosted.org/packages/d4/12/123be7292674abf76b21ac1fc0e1af50661f0e5b8f0ec8285faac18eb99e/cryptography-46.0.6-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175", size = 4278082, upload-time = "2026-03-25T23:33:27.423Z" },
- { url = "https://files.pythonhosted.org/packages/5b/ba/d5e27f8d68c24951b0a484924a84c7cdaed7502bac9f18601cd357f8b1d2/cryptography-46.0.6-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463", size = 4926514, upload-time = "2026-03-25T23:33:29.206Z" },
- { url = "https://files.pythonhosted.org/packages/34/71/1ea5a7352ae516d5512d17babe7e1b87d9db5150b21f794b1377eac1edc0/cryptography-46.0.6-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97", size = 4457766, upload-time = "2026-03-25T23:33:30.834Z" },
- { url = "https://files.pythonhosted.org/packages/01/59/562be1e653accee4fdad92c7a2e88fced26b3fdfce144047519bbebc299e/cryptography-46.0.6-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c", size = 3986535, upload-time = "2026-03-25T23:33:33.02Z" },
- { url = "https://files.pythonhosted.org/packages/d6/8b/b1ebfeb788bf4624d36e45ed2662b8bd43a05ff62157093c1539c1288a18/cryptography-46.0.6-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507", size = 4277618, upload-time = "2026-03-25T23:33:34.567Z" },
- { url = "https://files.pythonhosted.org/packages/dd/52/a005f8eabdb28df57c20f84c44d397a755782d6ff6d455f05baa2785bd91/cryptography-46.0.6-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19", size = 4890802, upload-time = "2026-03-25T23:33:37.034Z" },
- { url = "https://files.pythonhosted.org/packages/ec/4d/8e7d7245c79c617d08724e2efa397737715ca0ec830ecb3c91e547302555/cryptography-46.0.6-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738", size = 4457425, upload-time = "2026-03-25T23:33:38.904Z" },
- { url = "https://files.pythonhosted.org/packages/1d/5c/f6c3596a1430cec6f949085f0e1a970638d76f81c3ea56d93d564d04c340/cryptography-46.0.6-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c", size = 4405530, upload-time = "2026-03-25T23:33:40.842Z" },
- { url = "https://files.pythonhosted.org/packages/7e/c9/9f9cea13ee2dbde070424e0c4f621c091a91ffcc504ffea5e74f0e1daeff/cryptography-46.0.6-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f", size = 4667896, upload-time = "2026-03-25T23:33:42.781Z" },
- { url = "https://files.pythonhosted.org/packages/ad/b5/1895bc0821226f129bc74d00eccfc6a5969e2028f8617c09790bf89c185e/cryptography-46.0.6-cp311-abi3-win32.whl", hash = "sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2", size = 3026348, upload-time = "2026-03-25T23:33:45.021Z" },
- { url = "https://files.pythonhosted.org/packages/c3/f8/c9bcbf0d3e6ad288b9d9aa0b1dee04b063d19e8c4f871855a03ab3a297ab/cryptography-46.0.6-cp311-abi3-win_amd64.whl", hash = "sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124", size = 3483896, upload-time = "2026-03-25T23:33:46.649Z" },
- { url = "https://files.pythonhosted.org/packages/01/41/3a578f7fd5c70611c0aacba52cd13cb364a5dee895a5c1d467208a9380b0/cryptography-46.0.6-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275", size = 7117147, upload-time = "2026-03-25T23:33:48.249Z" },
- { url = "https://files.pythonhosted.org/packages/fa/87/887f35a6fca9dde90cad08e0de0c89263a8e59b2d2ff904fd9fcd8025b6f/cryptography-46.0.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4", size = 4266221, upload-time = "2026-03-25T23:33:49.874Z" },
- { url = "https://files.pythonhosted.org/packages/aa/a8/0a90c4f0b0871e0e3d1ed126aed101328a8a57fd9fd17f00fb67e82a51ca/cryptography-46.0.6-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b", size = 4408952, upload-time = "2026-03-25T23:33:52.128Z" },
- { url = "https://files.pythonhosted.org/packages/16/0b/b239701eb946523e4e9f329336e4ff32b1247e109cbab32d1a7b61da8ed7/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707", size = 4270141, upload-time = "2026-03-25T23:33:54.11Z" },
- { url = "https://files.pythonhosted.org/packages/0f/a8/976acdd4f0f30df7b25605f4b9d3d89295351665c2091d18224f7ad5cdbf/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361", size = 4904178, upload-time = "2026-03-25T23:33:55.725Z" },
- { url = "https://files.pythonhosted.org/packages/b1/1b/bf0e01a88efd0e59679b69f42d4afd5bced8700bb5e80617b2d63a3741af/cryptography-46.0.6-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b", size = 4441812, upload-time = "2026-03-25T23:33:57.364Z" },
- { url = "https://files.pythonhosted.org/packages/bb/8b/11df86de2ea389c65aa1806f331cae145f2ed18011f30234cc10ca253de8/cryptography-46.0.6-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca", size = 3963923, upload-time = "2026-03-25T23:33:59.361Z" },
- { url = "https://files.pythonhosted.org/packages/91/e0/207fb177c3a9ef6a8108f234208c3e9e76a6aa8cf20d51932916bd43bda0/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013", size = 4269695, upload-time = "2026-03-25T23:34:00.909Z" },
- { url = "https://files.pythonhosted.org/packages/21/5e/19f3260ed1e95bced52ace7501fabcd266df67077eeb382b79c81729d2d3/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4", size = 4869785, upload-time = "2026-03-25T23:34:02.796Z" },
- { url = "https://files.pythonhosted.org/packages/10/38/cd7864d79aa1d92ef6f1a584281433419b955ad5a5ba8d1eb6c872165bcb/cryptography-46.0.6-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a", size = 4441404, upload-time = "2026-03-25T23:34:04.35Z" },
- { url = "https://files.pythonhosted.org/packages/09/0a/4fe7a8d25fed74419f91835cf5829ade6408fd1963c9eae9c4bce390ecbb/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d", size = 4397549, upload-time = "2026-03-25T23:34:06.342Z" },
- { url = "https://files.pythonhosted.org/packages/5f/a0/7d738944eac6513cd60a8da98b65951f4a3b279b93479a7e8926d9cd730b/cryptography-46.0.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736", size = 4651874, upload-time = "2026-03-25T23:34:07.916Z" },
- { url = "https://files.pythonhosted.org/packages/cb/f1/c2326781ca05208845efca38bf714f76939ae446cd492d7613808badedf1/cryptography-46.0.6-cp314-cp314t-win32.whl", hash = "sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed", size = 3001511, upload-time = "2026-03-25T23:34:09.892Z" },
- { url = "https://files.pythonhosted.org/packages/c9/57/fe4a23eb549ac9d903bd4698ffda13383808ef0876cc912bcb2838799ece/cryptography-46.0.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4", size = 3471692, upload-time = "2026-03-25T23:34:11.613Z" },
- { url = "https://files.pythonhosted.org/packages/c4/cc/f330e982852403da79008552de9906804568ae9230da8432f7496ce02b71/cryptography-46.0.6-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a", size = 7162776, upload-time = "2026-03-25T23:34:13.308Z" },
- { url = "https://files.pythonhosted.org/packages/49/b3/dc27efd8dcc4bff583b3f01d4a3943cd8b5821777a58b3a6a5f054d61b79/cryptography-46.0.6-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8", size = 4270529, upload-time = "2026-03-25T23:34:15.019Z" },
- { url = "https://files.pythonhosted.org/packages/e6/05/e8d0e6eb4f0d83365b3cb0e00eb3c484f7348db0266652ccd84632a3d58d/cryptography-46.0.6-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77", size = 4414827, upload-time = "2026-03-25T23:34:16.604Z" },
- { url = "https://files.pythonhosted.org/packages/2f/97/daba0f5d2dc6d855e2dcb70733c812558a7977a55dd4a6722756628c44d1/cryptography-46.0.6-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290", size = 4271265, upload-time = "2026-03-25T23:34:18.586Z" },
- { url = "https://files.pythonhosted.org/packages/89/06/fe1fce39a37ac452e58d04b43b0855261dac320a2ebf8f5260dd55b201a9/cryptography-46.0.6-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410", size = 4916800, upload-time = "2026-03-25T23:34:20.561Z" },
- { url = "https://files.pythonhosted.org/packages/ff/8a/b14f3101fe9c3592603339eb5d94046c3ce5f7fc76d6512a2d40efd9724e/cryptography-46.0.6-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d", size = 4448771, upload-time = "2026-03-25T23:34:22.406Z" },
- { url = "https://files.pythonhosted.org/packages/01/b3/0796998056a66d1973fd52ee89dc1bb3b6581960a91ad4ac705f182d398f/cryptography-46.0.6-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70", size = 3978333, upload-time = "2026-03-25T23:34:24.281Z" },
- { url = "https://files.pythonhosted.org/packages/c5/3d/db200af5a4ffd08918cd55c08399dc6c9c50b0bc72c00a3246e099d3a849/cryptography-46.0.6-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d", size = 4271069, upload-time = "2026-03-25T23:34:25.895Z" },
- { url = "https://files.pythonhosted.org/packages/d7/18/61acfd5b414309d74ee838be321c636fe71815436f53c9f0334bf19064fa/cryptography-46.0.6-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa", size = 4878358, upload-time = "2026-03-25T23:34:27.67Z" },
- { url = "https://files.pythonhosted.org/packages/8b/65/5bf43286d566f8171917cae23ac6add941654ccf085d739195a4eacf1674/cryptography-46.0.6-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58", size = 4448061, upload-time = "2026-03-25T23:34:29.375Z" },
- { url = "https://files.pythonhosted.org/packages/e0/25/7e49c0fa7205cf3597e525d156a6bce5b5c9de1fd7e8cb01120e459f205a/cryptography-46.0.6-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb", size = 4399103, upload-time = "2026-03-25T23:34:32.036Z" },
- { url = "https://files.pythonhosted.org/packages/44/46/466269e833f1c4718d6cd496ffe20c56c9c8d013486ff66b4f69c302a68d/cryptography-46.0.6-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72", size = 4659255, upload-time = "2026-03-25T23:34:33.679Z" },
- { url = "https://files.pythonhosted.org/packages/0a/09/ddc5f630cc32287d2c953fc5d32705e63ec73e37308e5120955316f53827/cryptography-46.0.6-cp38-abi3-win32.whl", hash = "sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c", size = 3010660, upload-time = "2026-03-25T23:34:35.418Z" },
- { url = "https://files.pythonhosted.org/packages/1b/82/ca4893968aeb2709aacfb57a30dec6fa2ab25b10fa9f064b8882ce33f599/cryptography-46.0.6-cp38-abi3-win_amd64.whl", hash = "sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f", size = 3471160, upload-time = "2026-03-25T23:34:37.191Z" },
- { url = "https://files.pythonhosted.org/packages/2e/84/7ccff00ced5bac74b775ce0beb7d1be4e8637536b522b5df9b73ada42da2/cryptography-46.0.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead", size = 3475444, upload-time = "2026-03-25T23:34:38.944Z" },
- { url = "https://files.pythonhosted.org/packages/bc/1f/4c926f50df7749f000f20eede0c896769509895e2648db5da0ed55db711d/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8", size = 4218227, upload-time = "2026-03-25T23:34:40.871Z" },
- { url = "https://files.pythonhosted.org/packages/c6/65/707be3ffbd5f786028665c3223e86e11c4cda86023adbc56bd72b1b6bab5/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0", size = 4381399, upload-time = "2026-03-25T23:34:42.609Z" },
- { url = "https://files.pythonhosted.org/packages/f3/6d/73557ed0ef7d73d04d9aba745d2c8e95218213687ee5e76b7d236a5030fc/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b", size = 4217595, upload-time = "2026-03-25T23:34:44.205Z" },
- { url = "https://files.pythonhosted.org/packages/9e/c5/e1594c4eec66a567c3ac4400008108a415808be2ce13dcb9a9045c92f1a0/cryptography-46.0.6-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a", size = 4380912, upload-time = "2026-03-25T23:34:46.328Z" },
- { url = "https://files.pythonhosted.org/packages/1a/89/843b53614b47f97fe1abc13f9a86efa5ec9e275292c457af1d4a60dc80e0/cryptography-46.0.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e", size = 3409955, upload-time = "2026-03-25T23:34:48.465Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/5d/4a8f770695d73be252331e60e526291e3df0c9b27556a90a6b47bccca4c2/cryptography-46.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4", size = 7179869, upload-time = "2026-04-08T01:56:17.157Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/45/6d80dc379b0bbc1f9d1e429f42e4cb9e1d319c7a8201beffd967c516ea01/cryptography-46.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325", size = 4275492, upload-time = "2026-04-08T01:56:19.36Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/9a/1765afe9f572e239c3469f2cb429f3ba7b31878c893b246b4b2994ffe2fe/cryptography-46.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308", size = 4426670, upload-time = "2026-04-08T01:56:21.415Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/3e/af9246aaf23cd4ee060699adab1e47ced3f5f7e7a8ffdd339f817b446462/cryptography-46.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77", size = 4280275, upload-time = "2026-04-08T01:56:23.539Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/54/6bbbfc5efe86f9d71041827b793c24811a017c6ac0fd12883e4caa86b8ed/cryptography-46.0.7-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1", size = 4928402, upload-time = "2026-04-08T01:56:25.624Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/cf/054b9d8220f81509939599c8bdbc0c408dbd2bdd41688616a20731371fe0/cryptography-46.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef", size = 4459985, upload-time = "2026-04-08T01:56:27.309Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/46/4e4e9c6040fb01c7467d47217d2f882daddeb8828f7df800cb806d8a2288/cryptography-46.0.7-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de", size = 3990652, upload-time = "2026-04-08T01:56:29.095Z" },
+ { url = "https://files.pythonhosted.org/packages/36/5f/313586c3be5a2fbe87e4c9a254207b860155a8e1f3cca99f9910008e7d08/cryptography-46.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83", size = 4279805, upload-time = "2026-04-08T01:56:30.928Z" },
+ { url = "https://files.pythonhosted.org/packages/69/33/60dfc4595f334a2082749673386a4d05e4f0cf4df8248e63b2c3437585f2/cryptography-46.0.7-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb", size = 4892883, upload-time = "2026-04-08T01:56:32.614Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/0b/333ddab4270c4f5b972f980adef4faa66951a4aaf646ca067af597f15563/cryptography-46.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b", size = 4459756, upload-time = "2026-04-08T01:56:34.306Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/14/633913398b43b75f1234834170947957c6b623d1701ffc7a9600da907e89/cryptography-46.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85", size = 4410244, upload-time = "2026-04-08T01:56:35.977Z" },
+ { url = "https://files.pythonhosted.org/packages/10/f2/19ceb3b3dc14009373432af0c13f46aa08e3ce334ec6eff13492e1812ccd/cryptography-46.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e", size = 4674868, upload-time = "2026-04-08T01:56:38.034Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/bb/a5c213c19ee94b15dfccc48f363738633a493812687f5567addbcbba9f6f/cryptography-46.0.7-cp311-abi3-win32.whl", hash = "sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457", size = 3026504, upload-time = "2026-04-08T01:56:39.666Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/02/7788f9fefa1d060ca68717c3901ae7fffa21ee087a90b7f23c7a603c32ae/cryptography-46.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b", size = 3488363, upload-time = "2026-04-08T01:56:41.893Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/56/15619b210e689c5403bb0540e4cb7dbf11a6bf42e483b7644e471a2812b3/cryptography-46.0.7-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842", size = 7119671, upload-time = "2026-04-08T01:56:44Z" },
+ { url = "https://files.pythonhosted.org/packages/74/66/e3ce040721b0b5599e175ba91ab08884c75928fbeb74597dd10ef13505d2/cryptography-46.0.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c", size = 4268551, upload-time = "2026-04-08T01:56:46.071Z" },
+ { url = "https://files.pythonhosted.org/packages/03/11/5e395f961d6868269835dee1bafec6a1ac176505a167f68b7d8818431068/cryptography-46.0.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902", size = 4408887, upload-time = "2026-04-08T01:56:47.718Z" },
+ { url = "https://files.pythonhosted.org/packages/40/53/8ed1cf4c3b9c8e611e7122fb56f1c32d09e1fff0f1d77e78d9ff7c82653e/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d", size = 4271354, upload-time = "2026-04-08T01:56:49.312Z" },
+ { url = "https://files.pythonhosted.org/packages/50/46/cf71e26025c2e767c5609162c866a78e8a2915bbcfa408b7ca495c6140c4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022", size = 4905845, upload-time = "2026-04-08T01:56:50.916Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/ea/01276740375bac6249d0a971ebdf6b4dc9ead0ee0a34ef3b5a88c1a9b0d4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce", size = 4444641, upload-time = "2026-04-08T01:56:52.882Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/4c/7d258f169ae71230f25d9f3d06caabcff8c3baf0978e2b7d65e0acac3827/cryptography-46.0.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f", size = 3967749, upload-time = "2026-04-08T01:56:54.597Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/2a/2ea0767cad19e71b3530e4cad9605d0b5e338b6a1e72c37c9c1ceb86c333/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99", size = 4270942, upload-time = "2026-04-08T01:56:56.416Z" },
+ { url = "https://files.pythonhosted.org/packages/41/3d/fe14df95a83319af25717677e956567a105bb6ab25641acaa093db79975d/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1", size = 4871079, upload-time = "2026-04-08T01:56:58.31Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/59/4a479e0f36f8f378d397f4eab4c850b4ffb79a2f0d58704b8fa0703ddc11/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2", size = 4443999, upload-time = "2026-04-08T01:57:00.508Z" },
+ { url = "https://files.pythonhosted.org/packages/28/17/b59a741645822ec6d04732b43c5d35e4ef58be7bfa84a81e5ae6f05a1d33/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e", size = 4399191, upload-time = "2026-04-08T01:57:02.654Z" },
+ { url = "https://files.pythonhosted.org/packages/59/6a/bb2e166d6d0e0955f1e9ff70f10ec4b2824c9cfcdb4da772c7dd69cc7d80/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee", size = 4655782, upload-time = "2026-04-08T01:57:04.592Z" },
+ { url = "https://files.pythonhosted.org/packages/95/b6/3da51d48415bcb63b00dc17c2eff3a651b7c4fed484308d0f19b30e8cb2c/cryptography-46.0.7-cp314-cp314t-win32.whl", hash = "sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298", size = 3002227, upload-time = "2026-04-08T01:57:06.91Z" },
+ { url = "https://files.pythonhosted.org/packages/32/a8/9f0e4ed57ec9cebe506e58db11ae472972ecb0c659e4d52bbaee80ca340a/cryptography-46.0.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb", size = 3475332, upload-time = "2026-04-08T01:57:08.807Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/7f/cd42fc3614386bc0c12f0cb3c4ae1fc2bbca5c9662dfed031514911d513d/cryptography-46.0.7-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4", size = 7165618, upload-time = "2026-04-08T01:57:10.645Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/d0/36a49f0262d2319139d2829f773f1b97ef8aef7f97e6e5bd21455e5a8fb5/cryptography-46.0.7-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7", size = 4270628, upload-time = "2026-04-08T01:57:12.885Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/6c/1a42450f464dda6ffbe578a911f773e54dd48c10f9895a23a7e88b3e7db5/cryptography-46.0.7-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832", size = 4415405, upload-time = "2026-04-08T01:57:14.923Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/92/4ed714dbe93a066dc1f4b4581a464d2d7dbec9046f7c8b7016f5286329e2/cryptography-46.0.7-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163", size = 4272715, upload-time = "2026-04-08T01:57:16.638Z" },
+ { url = "https://files.pythonhosted.org/packages/b7/e6/a26b84096eddd51494bba19111f8fffe976f6a09f132706f8f1bf03f51f7/cryptography-46.0.7-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2", size = 4918400, upload-time = "2026-04-08T01:57:19.021Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/08/ffd537b605568a148543ac3c2b239708ae0bd635064bab41359252ef88ed/cryptography-46.0.7-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067", size = 4450634, upload-time = "2026-04-08T01:57:21.185Z" },
+ { url = "https://files.pythonhosted.org/packages/16/01/0cd51dd86ab5b9befe0d031e276510491976c3a80e9f6e31810cce46c4ad/cryptography-46.0.7-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0", size = 3985233, upload-time = "2026-04-08T01:57:22.862Z" },
+ { url = "https://files.pythonhosted.org/packages/92/49/819d6ed3a7d9349c2939f81b500a738cb733ab62fbecdbc1e38e83d45e12/cryptography-46.0.7-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba", size = 4271955, upload-time = "2026-04-08T01:57:24.814Z" },
+ { url = "https://files.pythonhosted.org/packages/80/07/ad9b3c56ebb95ed2473d46df0847357e01583f4c52a85754d1a55e29e4d0/cryptography-46.0.7-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006", size = 4879888, upload-time = "2026-04-08T01:57:26.88Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/c7/201d3d58f30c4c2bdbe9b03844c291feb77c20511cc3586daf7edc12a47b/cryptography-46.0.7-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0", size = 4449961, upload-time = "2026-04-08T01:57:29.068Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/ef/649750cbf96f3033c3c976e112265c33906f8e462291a33d77f90356548c/cryptography-46.0.7-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85", size = 4401696, upload-time = "2026-04-08T01:57:31.029Z" },
+ { url = "https://files.pythonhosted.org/packages/41/52/a8908dcb1a389a459a29008c29966c1d552588d4ae6d43f3a1a4512e0ebe/cryptography-46.0.7-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e", size = 4664256, upload-time = "2026-04-08T01:57:33.144Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/fa/f0ab06238e899cc3fb332623f337a7364f36f4bb3f2534c2bb95a35b132c/cryptography-46.0.7-cp38-abi3-win32.whl", hash = "sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246", size = 3013001, upload-time = "2026-04-08T01:57:34.933Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/f1/00ce3bde3ca542d1acd8f8cfa38e446840945aa6363f9b74746394b14127/cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3", size = 3472985, upload-time = "2026-04-08T01:57:36.714Z" },
+ { url = "https://files.pythonhosted.org/packages/63/0c/dca8abb64e7ca4f6b2978769f6fea5ad06686a190cec381f0a796fdcaaba/cryptography-46.0.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fc9ab8856ae6cf7c9358430e49b368f3108f050031442eaeb6b9d87e4dcf4e4f", size = 3476879, upload-time = "2026-04-08T01:57:38.664Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/ea/075aac6a84b7c271578d81a2f9968acb6e273002408729f2ddff517fed4a/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d3b99c535a9de0adced13d159c5a9cf65c325601aa30f4be08afd680643e9c15", size = 4219700, upload-time = "2026-04-08T01:57:40.625Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/7b/1c55db7242b5e5612b29fc7a630e91ee7a6e3c8e7bf5406d22e206875fbd/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d02c738dacda7dc2a74d1b2b3177042009d5cab7c7079db74afc19e56ca1b455", size = 4385982, upload-time = "2026-04-08T01:57:42.725Z" },
+ { url = "https://files.pythonhosted.org/packages/cb/da/9870eec4b69c63ef5925bf7d8342b7e13bc2ee3d47791461c4e49ca212f4/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:04959522f938493042d595a736e7dbdff6eb6cc2339c11465b3ff89343b65f65", size = 4219115, upload-time = "2026-04-08T01:57:44.939Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/72/05aa5832b82dd341969e9a734d1812a6aadb088d9eb6f0430fc337cc5a8f/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:3986ac1dee6def53797289999eabe84798ad7817f3e97779b5061a95b0ee4968", size = 4385479, upload-time = "2026-04-08T01:57:46.86Z" },
+ { url = "https://files.pythonhosted.org/packages/20/2a/1b016902351a523aa2bd446b50a5bc1175d7a7d1cf90fe2ef904f9b84ebc/cryptography-46.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:258514877e15963bd43b558917bc9f54cf7cf866c38aa576ebf47a77ddbc43a4", size = 3412829, upload-time = "2026-04-08T01:57:48.874Z" },
]
[[package]]
@@ -621,9 +545,7 @@ version = "3.1.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "blinker" },
- { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "click", version = "8.3.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "importlib-metadata", marker = "python_full_version < '3.10'" },
+ { name = "click" },
{ name = "itsdangerous" },
{ name = "jinja2" },
{ name = "markupsafe" },
@@ -636,44 +558,17 @@ wheels = [
[[package]]
name = "idna"
-version = "3.11"
+version = "3.13"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
-]
-
-[[package]]
-name = "importlib-metadata"
-version = "8.7.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "zipp", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/fa/5e/f8e9a1d23b9c20a551a8a02ea3637b4642e22c2626e3a13a9a29cdea99eb/importlib_metadata-8.7.1-py3-none-any.whl", hash = "sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151", size = 27865, upload-time = "2025-12-21T10:00:18.329Z" },
-]
-
-[[package]]
-name = "iniconfig"
-version = "2.1.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" },
]
[[package]]
name = "iniconfig"
version = "2.3.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
@@ -693,8 +588,7 @@ name = "jaraco-functools"
version = "4.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "more-itertools", version = "10.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "more-itertools", version = "11.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "more-itertools" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0f/27/056e0638a86749374d6f57d0b0db39f29509cce9313cf91bdc0ac4d91084/jaraco_functools-4.4.0.tar.gz", hash = "sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb", size = 19943, upload-time = "2025-12-21T09:29:43.6Z" }
wheels = [
@@ -713,36 +607,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
]
-[[package]]
-name = "jsonschema"
-version = "4.25.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "attrs", marker = "python_full_version < '3.10'" },
- { name = "jsonschema-specifications", marker = "python_full_version < '3.10'" },
- { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "rpds-py", version = "0.27.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" },
-]
-
[[package]]
name = "jsonschema"
version = "4.26.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
dependencies = [
- { name = "attrs", marker = "python_full_version >= '3.10'" },
- { name = "jsonschema-specifications", marker = "python_full_version >= '3.10'" },
- { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "attrs" },
+ { name = "jsonschema-specifications" },
+ { name = "referencing" },
+ { name = "rpds-py" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" }
wheels = [
@@ -754,8 +627,7 @@ name = "jsonschema-specifications"
version = "2025.9.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "referencing" },
]
sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" }
wheels = [
@@ -845,41 +717,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" },
{ url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" },
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
- { url = "https://files.pythonhosted.org/packages/56/23/0d8c13a44bde9154821586520840643467aee574d8ce79a17da539ee7fed/markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26", size = 11623, upload-time = "2025-09-27T18:37:29.296Z" },
- { url = "https://files.pythonhosted.org/packages/fd/23/07a2cb9a8045d5f3f0890a8c3bc0859d7a47bfd9a560b563899bec7b72ed/markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc", size = 12049, upload-time = "2025-09-27T18:37:30.234Z" },
- { url = "https://files.pythonhosted.org/packages/bc/e4/6be85eb81503f8e11b61c0b6369b6e077dcf0a74adbd9ebf6b349937b4e9/markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c", size = 21923, upload-time = "2025-09-27T18:37:31.177Z" },
- { url = "https://files.pythonhosted.org/packages/6f/bc/4dc914ead3fe6ddaef035341fee0fc956949bbd27335b611829292b89ee2/markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42", size = 20543, upload-time = "2025-09-27T18:37:32.168Z" },
- { url = "https://files.pythonhosted.org/packages/89/6e/5fe81fbcfba4aef4093d5f856e5c774ec2057946052d18d168219b7bd9f9/markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b", size = 20585, upload-time = "2025-09-27T18:37:33.166Z" },
- { url = "https://files.pythonhosted.org/packages/f6/f6/e0e5a3d3ae9c4020f696cd055f940ef86b64fe88de26f3a0308b9d3d048c/markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758", size = 21387, upload-time = "2025-09-27T18:37:34.185Z" },
- { url = "https://files.pythonhosted.org/packages/c8/25/651753ef4dea08ea790f4fbb65146a9a44a014986996ca40102e237aa49a/markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2", size = 20133, upload-time = "2025-09-27T18:37:35.138Z" },
- { url = "https://files.pythonhosted.org/packages/dc/0a/c3cf2b4fef5f0426e8a6d7fce3cb966a17817c568ce59d76b92a233fdbec/markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d", size = 20588, upload-time = "2025-09-27T18:37:36.096Z" },
- { url = "https://files.pythonhosted.org/packages/cd/1b/a7782984844bd519ad4ffdbebbba2671ec5d0ebbeac34736c15fb86399e8/markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7", size = 14566, upload-time = "2025-09-27T18:37:37.09Z" },
- { url = "https://files.pythonhosted.org/packages/18/1f/8d9c20e1c9440e215a44be5ab64359e207fcb4f675543f1cf9a2a7f648d0/markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e", size = 15053, upload-time = "2025-09-27T18:37:38.054Z" },
- { url = "https://files.pythonhosted.org/packages/4e/d3/fe08482b5cd995033556d45041a4f4e76e7f0521112a9c9991d40d39825f/markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8", size = 13928, upload-time = "2025-09-27T18:37:39.037Z" },
+]
+
+[[package]]
+name = "mnemonic"
+version = "0.21"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/ff/77/e6232ed59fbd7b90208bb8d4f89ed5aabcf30a524bc2fb8f0dafbe8e7df9/mnemonic-0.21.tar.gz", hash = "sha256:1fe496356820984f45559b1540c80ff10de448368929b9c60a2b55744cc88acf", size = 152462, upload-time = "2024-01-05T10:46:14.895Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/57/48/5abb16ce7f9d97b728e6b97c704ceaa614362e0847651f379ed0511942a0/mnemonic-0.21-py3-none-any.whl", hash = "sha256:72dc9de16ec5ef47287237b9b6943da11647a03fe7cf1f139fc3d7c4a7439288", size = 92701, upload-time = "2024-01-05T10:46:12.703Z" },
]
[[package]]
name = "more-itertools"
-version = "10.8.0"
+version = "11.0.2"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ea/5d/38b681d3fce7a266dd9ab73c66959406d565b3e85f21d5e66e1181d93721/more_itertools-10.8.0.tar.gz", hash = "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd", size = 137431, upload-time = "2025-09-02T15:23:11.018Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/f7/139d22fef48ac78127d18e01d80cf1be40236ae489769d17f35c3d425293/more_itertools-11.0.2.tar.gz", hash = "sha256:392a9e1e362cbc106a2457d37cabf9b36e5e12efd4ebff1654630e76597df804", size = 144659, upload-time = "2026-04-09T15:01:33.297Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl", hash = "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b", size = 69667, upload-time = "2025-09-02T15:23:09.635Z" },
-]
-
-[[package]]
-name = "more-itertools"
-version = "11.0.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/24/24/e0acc4bf54cba50c1d432c70a72a3df96db4a321b2c4c68432a60759044f/more_itertools-11.0.1.tar.gz", hash = "sha256:fefaf25b7ab08f0b45fa9f1892cae93b9fc0089ef034d39213bce15f1cc9e199", size = 144739, upload-time = "2026-04-02T16:17:45.061Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d8/f4/5e52c7319b8087acef603ed6e50dc325c02eaa999355414830468611f13c/more_itertools-11.0.1-py3-none-any.whl", hash = "sha256:eaf287826069452a8f61026c597eae2428b2d1ba2859083abbf240b46842ce6d", size = 72182, upload-time = "2026-04-02T16:17:43.724Z" },
+ { url = "https://files.pythonhosted.org/packages/cb/98/6af411189d9413534c3eb691182bff1f5c6d44ed2f93f2edfe52a1bbceb8/more_itertools-11.0.2-py3-none-any.whl", hash = "sha256:6e35b35f818b01f691643c6c611bc0902f2e92b46c18fffa77ae1e7c46e912e4", size = 71939, upload-time = "2026-04-09T15:01:32.21Z" },
]
[[package]]
@@ -904,11 +759,11 @@ wheels = [
[[package]]
name = "packaging"
-version = "26.0"
+version = "26.1"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" },
]
[[package]]
@@ -950,97 +805,71 @@ wheels = [
[[package]]
name = "psycopg2-binary"
-version = "2.9.11"
+version = "2.9.12"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ac/6c/8767aaa597ba424643dc87348c6f1754dd9f48e80fdc1b9f7ca5c3a7c213/psycopg2-binary-2.9.11.tar.gz", hash = "sha256:b6aed9e096bf63f9e75edf2581aa9a7e7186d97ab5c177aa6c87797cd591236c", size = 379620, upload-time = "2025-10-10T11:14:48.041Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/2a/60/a3624f79acea344c16fbef3a94d28b89a8042ddfb8f3e4ca83f538671409/psycopg2_binary-2.9.12.tar.gz", hash = "sha256:5ac9444edc768c02a6b6a591f070b8aae28ff3a99be57560ac996001580f294c", size = 379686, upload-time = "2026-04-21T09:40:34.304Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6a/f2/8e377d29c2ecf99f6062d35ea606b036e8800720eccfec5fe3dd672c2b24/psycopg2_binary-2.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d6fe6b47d0b42ce1c9f1fa3e35bb365011ca22e39db37074458f27921dca40f2", size = 3756506, upload-time = "2025-10-10T11:10:30.144Z" },
- { url = "https://files.pythonhosted.org/packages/24/cc/dc143ea88e4ec9d386106cac05023b69668bd0be20794c613446eaefafe5/psycopg2_binary-2.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c0e4262e089516603a09474ee13eabf09cb65c332277e39af68f6233911087", size = 3863943, upload-time = "2025-10-10T11:10:34.586Z" },
- { url = "https://files.pythonhosted.org/packages/8c/df/16848771155e7c419c60afeb24950b8aaa3ab09c0a091ec3ccca26a574d0/psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c47676e5b485393f069b4d7a811267d3168ce46f988fa602658b8bb901e9e64d", size = 4410873, upload-time = "2025-10-10T11:10:38.951Z" },
- { url = "https://files.pythonhosted.org/packages/43/79/5ef5f32621abd5a541b89b04231fe959a9b327c874a1d41156041c75494b/psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a28d8c01a7b27a1e3265b11250ba7557e5f72b5ee9e5f3a2fa8d2949c29bf5d2", size = 4468016, upload-time = "2025-10-10T11:10:43.319Z" },
- { url = "https://files.pythonhosted.org/packages/f0/9b/d7542d0f7ad78f57385971f426704776d7b310f5219ed58da5d605b1892e/psycopg2_binary-2.9.11-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f3f2732cf504a1aa9e9609d02f79bea1067d99edf844ab92c247bbca143303b", size = 4164996, upload-time = "2025-10-10T11:10:46.705Z" },
- { url = "https://files.pythonhosted.org/packages/14/ed/e409388b537fa7414330687936917c522f6a77a13474e4238219fcfd9a84/psycopg2_binary-2.9.11-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:865f9945ed1b3950d968ec4690ce68c55019d79e4497366d36e090327ce7db14", size = 3981881, upload-time = "2025-10-30T02:54:57.182Z" },
- { url = "https://files.pythonhosted.org/packages/bf/30/50e330e63bb05efc6fa7c1447df3e08954894025ca3dcb396ecc6739bc26/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91537a8df2bde69b1c1db01d6d944c831ca793952e4f57892600e96cee95f2cd", size = 3650857, upload-time = "2025-10-10T11:10:50.112Z" },
- { url = "https://files.pythonhosted.org/packages/f0/e0/4026e4c12bb49dd028756c5b0bc4c572319f2d8f1c9008e0dad8cc9addd7/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4dca1f356a67ecb68c81a7bc7809f1569ad9e152ce7fd02c2f2036862ca9f66b", size = 3296063, upload-time = "2025-10-10T11:10:54.089Z" },
- { url = "https://files.pythonhosted.org/packages/2c/34/eb172be293c886fef5299fe5c3fcf180a05478be89856067881007934a7c/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0da4de5c1ac69d94ed4364b6cbe7190c1a70d325f112ba783d83f8440285f152", size = 3043464, upload-time = "2025-10-30T02:55:02.483Z" },
- { url = "https://files.pythonhosted.org/packages/18/1c/532c5d2cb11986372f14b798a95f2eaafe5779334f6a80589a68b5fcf769/psycopg2_binary-2.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37d8412565a7267f7d79e29ab66876e55cb5e8e7b3bbf94f8206f6795f8f7e7e", size = 3345378, upload-time = "2025-10-10T11:11:01.039Z" },
- { url = "https://files.pythonhosted.org/packages/70/e7/de420e1cf16f838e1fa17b1120e83afff374c7c0130d088dba6286fcf8ea/psycopg2_binary-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:c665f01ec8ab273a61c62beeb8cce3014c214429ced8a308ca1fc410ecac3a39", size = 2713904, upload-time = "2025-10-10T11:11:04.81Z" },
- { url = "https://files.pythonhosted.org/packages/c7/ae/8d8266f6dd183ab4d48b95b9674034e1b482a3f8619b33a0d86438694577/psycopg2_binary-2.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0e8480afd62362d0a6a27dd09e4ca2def6fa50ed3a4e7c09165266106b2ffa10", size = 3756452, upload-time = "2025-10-10T11:11:11.583Z" },
- { url = "https://files.pythonhosted.org/packages/4b/34/aa03d327739c1be70e09d01182619aca8ebab5970cd0cfa50dd8b9cec2ac/psycopg2_binary-2.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:763c93ef1df3da6d1a90f86ea7f3f806dc06b21c198fa87c3c25504abec9404a", size = 3863957, upload-time = "2025-10-10T11:11:16.932Z" },
- { url = "https://files.pythonhosted.org/packages/48/89/3fdb5902bdab8868bbedc1c6e6023a4e08112ceac5db97fc2012060e0c9a/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e164359396576a3cc701ba8af4751ae68a07235d7a380c631184a611220d9a4", size = 4410955, upload-time = "2025-10-10T11:11:21.21Z" },
- { url = "https://files.pythonhosted.org/packages/ce/24/e18339c407a13c72b336e0d9013fbbbde77b6fd13e853979019a1269519c/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d57c9c387660b8893093459738b6abddbb30a7eab058b77b0d0d1c7d521ddfd7", size = 4468007, upload-time = "2025-10-10T11:11:24.831Z" },
- { url = "https://files.pythonhosted.org/packages/91/7e/b8441e831a0f16c159b5381698f9f7f7ed54b77d57bc9c5f99144cc78232/psycopg2_binary-2.9.11-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2c226ef95eb2250974bf6fa7a842082b31f68385c4f3268370e3f3870e7859ee", size = 4165012, upload-time = "2025-10-10T11:11:29.51Z" },
- { url = "https://files.pythonhosted.org/packages/0d/61/4aa89eeb6d751f05178a13da95516c036e27468c5d4d2509bb1e15341c81/psycopg2_binary-2.9.11-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a311f1edc9967723d3511ea7d2708e2c3592e3405677bf53d5c7246753591fbb", size = 3981881, upload-time = "2025-10-30T02:55:07.332Z" },
- { url = "https://files.pythonhosted.org/packages/76/a1/2f5841cae4c635a9459fe7aca8ed771336e9383b6429e05c01267b0774cf/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ebb415404821b6d1c47353ebe9c8645967a5235e6d88f914147e7fd411419e6f", size = 3650985, upload-time = "2025-10-10T11:11:34.975Z" },
- { url = "https://files.pythonhosted.org/packages/84/74/4defcac9d002bca5709951b975173c8c2fa968e1a95dc713f61b3a8d3b6a/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f07c9c4a5093258a03b28fab9b4f151aa376989e7f35f855088234e656ee6a94", size = 3296039, upload-time = "2025-10-10T11:11:40.432Z" },
- { url = "https://files.pythonhosted.org/packages/6d/c2/782a3c64403d8ce35b5c50e1b684412cf94f171dc18111be8c976abd2de1/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:00ce1830d971f43b667abe4a56e42c1e2d594b32da4802e44a73bacacb25535f", size = 3043477, upload-time = "2025-10-30T02:55:11.182Z" },
- { url = "https://files.pythonhosted.org/packages/c8/31/36a1d8e702aa35c38fc117c2b8be3f182613faa25d794b8aeaab948d4c03/psycopg2_binary-2.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cffe9d7697ae7456649617e8bb8d7a45afb71cd13f7ab22af3e5c61f04840908", size = 3345842, upload-time = "2025-10-10T11:11:45.366Z" },
- { url = "https://files.pythonhosted.org/packages/6e/b4/a5375cda5b54cb95ee9b836930fea30ae5a8f14aa97da7821722323d979b/psycopg2_binary-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:304fd7b7f97eef30e91b8f7e720b3db75fee010b520e434ea35ed1ff22501d03", size = 2713894, upload-time = "2025-10-10T11:11:48.775Z" },
- { url = "https://files.pythonhosted.org/packages/d8/91/f870a02f51be4a65987b45a7de4c2e1897dd0d01051e2b559a38fa634e3e/psycopg2_binary-2.9.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:be9b840ac0525a283a96b556616f5b4820e0526addb8dcf6525a0fa162730be4", size = 3756603, upload-time = "2025-10-10T11:11:52.213Z" },
- { url = "https://files.pythonhosted.org/packages/27/fa/cae40e06849b6c9a95eb5c04d419942f00d9eaac8d81626107461e268821/psycopg2_binary-2.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f090b7ddd13ca842ebfe301cd587a76a4cf0913b1e429eb92c1be5dbeb1a19bc", size = 3864509, upload-time = "2025-10-10T11:11:56.452Z" },
- { url = "https://files.pythonhosted.org/packages/2d/75/364847b879eb630b3ac8293798e380e441a957c53657995053c5ec39a316/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ab8905b5dcb05bf3fb22e0cf90e10f469563486ffb6a96569e51f897c750a76a", size = 4411159, upload-time = "2025-10-10T11:12:00.49Z" },
- { url = "https://files.pythonhosted.org/packages/6f/a0/567f7ea38b6e1c62aafd58375665a547c00c608a471620c0edc364733e13/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf940cd7e7fec19181fdbc29d76911741153d51cab52e5c21165f3262125685e", size = 4468234, upload-time = "2025-10-10T11:12:04.892Z" },
- { url = "https://files.pythonhosted.org/packages/30/da/4e42788fb811bbbfd7b7f045570c062f49e350e1d1f3df056c3fb5763353/psycopg2_binary-2.9.11-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa0f693d3c68ae925966f0b14b8edda71696608039f4ed61b1fe9ffa468d16db", size = 4166236, upload-time = "2025-10-10T11:12:11.674Z" },
- { url = "https://files.pythonhosted.org/packages/3c/94/c1777c355bc560992af848d98216148be5f1be001af06e06fc49cbded578/psycopg2_binary-2.9.11-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a1cf393f1cdaf6a9b57c0a719a1068ba1069f022a59b8b1fe44b006745b59757", size = 3983083, upload-time = "2025-10-30T02:55:15.73Z" },
- { url = "https://files.pythonhosted.org/packages/bd/42/c9a21edf0e3daa7825ed04a4a8588686c6c14904344344a039556d78aa58/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef7a6beb4beaa62f88592ccc65df20328029d721db309cb3250b0aae0fa146c3", size = 3652281, upload-time = "2025-10-10T11:12:17.713Z" },
- { url = "https://files.pythonhosted.org/packages/12/22/dedfbcfa97917982301496b6b5e5e6c5531d1f35dd2b488b08d1ebc52482/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:31b32c457a6025e74d233957cc9736742ac5a6cb196c6b68499f6bb51390bd6a", size = 3298010, upload-time = "2025-10-10T11:12:22.671Z" },
- { url = "https://files.pythonhosted.org/packages/66/ea/d3390e6696276078bd01b2ece417deac954dfdd552d2edc3d03204416c0c/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:edcb3aeb11cb4bf13a2af3c53a15b3d612edeb6409047ea0b5d6a21a9d744b34", size = 3044641, upload-time = "2025-10-30T02:55:19.929Z" },
- { url = "https://files.pythonhosted.org/packages/12/9a/0402ded6cbd321da0c0ba7d34dc12b29b14f5764c2fc10750daa38e825fc/psycopg2_binary-2.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b6d93d7c0b61a1dd6197d208ab613eb7dcfdcca0a49c42ceb082257991de9d", size = 3347940, upload-time = "2025-10-10T11:12:26.529Z" },
- { url = "https://files.pythonhosted.org/packages/b1/d2/99b55e85832ccde77b211738ff3925a5d73ad183c0b37bcbbe5a8ff04978/psycopg2_binary-2.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:b33fabeb1fde21180479b2d4667e994de7bbf0eec22832ba5d9b5e4cf65b6c6d", size = 2714147, upload-time = "2025-10-10T11:12:29.535Z" },
- { url = "https://files.pythonhosted.org/packages/ff/a8/a2709681b3ac11b0b1786def10006b8995125ba268c9a54bea6f5ae8bd3e/psycopg2_binary-2.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b8fb3db325435d34235b044b199e56cdf9ff41223a4b9752e8576465170bb38c", size = 3756572, upload-time = "2025-10-10T11:12:32.873Z" },
- { url = "https://files.pythonhosted.org/packages/62/e1/c2b38d256d0dafd32713e9f31982a5b028f4a3651f446be70785f484f472/psycopg2_binary-2.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:366df99e710a2acd90efed3764bb1e28df6c675d33a7fb40df9b7281694432ee", size = 3864529, upload-time = "2025-10-10T11:12:36.791Z" },
- { url = "https://files.pythonhosted.org/packages/11/32/b2ffe8f3853c181e88f0a157c5fb4e383102238d73c52ac6d93a5c8bffe6/psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c55b385daa2f92cb64b12ec4536c66954ac53654c7f15a203578da4e78105c0", size = 4411242, upload-time = "2025-10-10T11:12:42.388Z" },
- { url = "https://files.pythonhosted.org/packages/10/04/6ca7477e6160ae258dc96f67c371157776564679aefd247b66f4661501a2/psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c0377174bf1dd416993d16edc15357f6eb17ac998244cca19bc67cdc0e2e5766", size = 4468258, upload-time = "2025-10-10T11:12:48.654Z" },
- { url = "https://files.pythonhosted.org/packages/3c/7e/6a1a38f86412df101435809f225d57c1a021307dd0689f7a5e7fe83588b1/psycopg2_binary-2.9.11-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c6ff3335ce08c75afaed19e08699e8aacf95d4a260b495a4a8545244fe2ceb3", size = 4166295, upload-time = "2025-10-10T11:12:52.525Z" },
- { url = "https://files.pythonhosted.org/packages/f2/7d/c07374c501b45f3579a9eb761cbf2604ddef3d96ad48679112c2c5aa9c25/psycopg2_binary-2.9.11-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84011ba3109e06ac412f95399b704d3d6950e386b7994475b231cf61eec2fc1f", size = 3983133, upload-time = "2025-10-30T02:55:24.329Z" },
- { url = "https://files.pythonhosted.org/packages/82/56/993b7104cb8345ad7d4516538ccf8f0d0ac640b1ebd8c754a7b024e76878/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba34475ceb08cccbdd98f6b46916917ae6eeb92b5ae111df10b544c3a4621dc4", size = 3652383, upload-time = "2025-10-10T11:12:56.387Z" },
- { url = "https://files.pythonhosted.org/packages/2d/ac/eaeb6029362fd8d454a27374d84c6866c82c33bfc24587b4face5a8e43ef/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b31e90fdd0f968c2de3b26ab014314fe814225b6c324f770952f7d38abf17e3c", size = 3298168, upload-time = "2025-10-10T11:13:00.403Z" },
- { url = "https://files.pythonhosted.org/packages/2b/39/50c3facc66bded9ada5cbc0de867499a703dc6bca6be03070b4e3b65da6c/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:d526864e0f67f74937a8fce859bd56c979f5e2ec57ca7c627f5f1071ef7fee60", size = 3044712, upload-time = "2025-10-30T02:55:27.975Z" },
- { url = "https://files.pythonhosted.org/packages/9c/8e/b7de019a1f562f72ada81081a12823d3c1590bedc48d7d2559410a2763fe/psycopg2_binary-2.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04195548662fa544626c8ea0f06561eb6203f1984ba5b4562764fbeb4c3d14b1", size = 3347549, upload-time = "2025-10-10T11:13:03.971Z" },
- { url = "https://files.pythonhosted.org/packages/80/2d/1bb683f64737bbb1f86c82b7359db1eb2be4e2c0c13b947f80efefa7d3e5/psycopg2_binary-2.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:efff12b432179443f54e230fdf60de1f6cc726b6c832db8701227d089310e8aa", size = 2714215, upload-time = "2025-10-10T11:13:07.14Z" },
- { url = "https://files.pythonhosted.org/packages/64/12/93ef0098590cf51d9732b4f139533732565704f45bdc1ffa741b7c95fb54/psycopg2_binary-2.9.11-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:92e3b669236327083a2e33ccfa0d320dd01b9803b3e14dd986a4fc54aa00f4e1", size = 3756567, upload-time = "2025-10-10T11:13:11.885Z" },
- { url = "https://files.pythonhosted.org/packages/7c/a9/9d55c614a891288f15ca4b5209b09f0f01e3124056924e17b81b9fa054cc/psycopg2_binary-2.9.11-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e0deeb03da539fa3577fcb0b3f2554a97f7e5477c246098dbb18091a4a01c16f", size = 3864755, upload-time = "2025-10-10T11:13:17.727Z" },
- { url = "https://files.pythonhosted.org/packages/13/1e/98874ce72fd29cbde93209977b196a2edae03f8490d1bd8158e7f1daf3a0/psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b52a3f9bb540a3e4ec0f6ba6d31339727b2950c9772850d6545b7eae0b9d7c5", size = 4411646, upload-time = "2025-10-10T11:13:24.432Z" },
- { url = "https://files.pythonhosted.org/packages/5a/bd/a335ce6645334fb8d758cc358810defca14a1d19ffbc8a10bd38a2328565/psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:db4fd476874ccfdbb630a54426964959e58da4c61c9feba73e6094d51303d7d8", size = 4468701, upload-time = "2025-10-10T11:13:29.266Z" },
- { url = "https://files.pythonhosted.org/packages/44/d6/c8b4f53f34e295e45709b7568bf9b9407a612ea30387d35eb9fa84f269b4/psycopg2_binary-2.9.11-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:47f212c1d3be608a12937cc131bd85502954398aaa1320cb4c14421a0ffccf4c", size = 4166293, upload-time = "2025-10-10T11:13:33.336Z" },
- { url = "https://files.pythonhosted.org/packages/4b/e0/f8cc36eadd1b716ab36bb290618a3292e009867e5c97ce4aba908cb99644/psycopg2_binary-2.9.11-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e35b7abae2b0adab776add56111df1735ccc71406e56203515e228a8dc07089f", size = 3983184, upload-time = "2025-10-30T02:55:32.483Z" },
- { url = "https://files.pythonhosted.org/packages/53/3e/2a8fe18a4e61cfb3417da67b6318e12691772c0696d79434184a511906dc/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fcf21be3ce5f5659daefd2b3b3b6e4727b028221ddc94e6c1523425579664747", size = 3652650, upload-time = "2025-10-10T11:13:38.181Z" },
- { url = "https://files.pythonhosted.org/packages/76/36/03801461b31b29fe58d228c24388f999fe814dfc302856e0d17f97d7c54d/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:9bd81e64e8de111237737b29d68039b9c813bdf520156af36d26819c9a979e5f", size = 3298663, upload-time = "2025-10-10T11:13:44.878Z" },
- { url = "https://files.pythonhosted.org/packages/97/77/21b0ea2e1a73aa5fa9222b2a6b8ba325c43c3a8d54272839c991f2345656/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:32770a4d666fbdafab017086655bcddab791d7cb260a16679cc5a7338b64343b", size = 3044737, upload-time = "2025-10-30T02:55:35.69Z" },
- { url = "https://files.pythonhosted.org/packages/67/69/f36abe5f118c1dca6d3726ceae164b9356985805480731ac6712a63f24f0/psycopg2_binary-2.9.11-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3cb3a676873d7506825221045bd70e0427c905b9c8ee8d6acd70cfcbd6e576d", size = 3347643, upload-time = "2025-10-10T11:13:53.499Z" },
- { url = "https://files.pythonhosted.org/packages/e1/36/9c0c326fe3a4227953dfb29f5d0c8ae3b8eb8c1cd2967aa569f50cb3c61f/psycopg2_binary-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:4012c9c954dfaccd28f94e84ab9f94e12df76b4afb22331b1f0d3154893a6316", size = 2803913, upload-time = "2025-10-10T11:13:57.058Z" },
- { url = "https://files.pythonhosted.org/packages/b2/41/cb36a61146b3afed03e980477f6dd29c0263f15e4b4844660501a774dc0b/psycopg2_binary-2.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20e7fb94e20b03dcc783f76c0865f9da39559dcc0c28dd1a3fce0d01902a6b9c", size = 3756418, upload-time = "2025-10-10T11:14:00.728Z" },
- { url = "https://files.pythonhosted.org/packages/f4/e3/8623be505c8921727277f22753092835b559543b078e83378bb74712dbc8/psycopg2_binary-2.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bdab48575b6f870f465b397c38f1b415520e9879fdf10a53ee4f49dcbdf8a21", size = 3863981, upload-time = "2025-10-10T11:14:05.215Z" },
- { url = "https://files.pythonhosted.org/packages/bc/86/ec3682dc3550c65eff80384f603a6a55b798e1b86ccef262d454d19f96eb/psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9d3a9edcfbe77a3ed4bc72836d466dfce4174beb79eda79ea155cc77237ed9e8", size = 4410882, upload-time = "2025-10-10T11:14:09.552Z" },
- { url = "https://files.pythonhosted.org/packages/41/af/540ee7d56fb33408c57240d55904c95e4a30952c096f5e1542769cadc787/psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:44fc5c2b8fa871ce7f0023f619f1349a0aa03a0857f2c96fbc01c657dcbbdb49", size = 4468062, upload-time = "2025-10-10T11:14:15.225Z" },
- { url = "https://files.pythonhosted.org/packages/b4/d5/b95d47b2e67b2adfaba517c803a99a1ac41e84c8201d0f3b29d77b56e357/psycopg2_binary-2.9.11-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9c55460033867b4622cda1b6872edf445809535144152e5d14941ef591980edf", size = 4165036, upload-time = "2025-10-10T11:14:21.209Z" },
- { url = "https://files.pythonhosted.org/packages/af/f9/99e39882b70d9b0cfdcbad33bea2e5823843c3a7839c1aaf89fc1337c05c/psycopg2_binary-2.9.11-cp39-cp39-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2d11098a83cca92deaeaed3d58cfd150d49b3b06ee0d0852be466bf87596899e", size = 3981901, upload-time = "2025-10-30T02:55:39.325Z" },
- { url = "https://files.pythonhosted.org/packages/de/c3/8d2c97f1dfddedf5a06c6ad2eda83fba48555a7bc525c3150aedc6f2bedc/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:691c807d94aecfbc76a14e1408847d59ff5b5906a04a23e12a89007672b9e819", size = 3650995, upload-time = "2025-10-10T11:14:27.733Z" },
- { url = "https://files.pythonhosted.org/packages/9c/89/afdf59b44b84ebb28111652485fab608429389f4051d22bc5a7bb43d5208/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b81627b691f29c4c30a8f322546ad039c40c328373b11dff7490a3e1b517855", size = 3296106, upload-time = "2025-10-10T11:14:33.312Z" },
- { url = "https://files.pythonhosted.org/packages/94/21/851c9ecf0e9a699907d1c455dbbde7ef9b11dba28e7b7b132c7bb28391f2/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:b637d6d941209e8d96a072d7977238eea128046effbf37d1d8b2c0764750017d", size = 3043491, upload-time = "2025-10-30T02:55:42.228Z" },
- { url = "https://files.pythonhosted.org/packages/9c/de/50f6eced439e7a131b268276c4b68cf8800fd55d8cef7b37109c44bf957a/psycopg2_binary-2.9.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:41360b01c140c2a03d346cec3280cf8a71aa07d94f3b1509fa0161c366af66b4", size = 3345816, upload-time = "2025-10-10T11:14:38.648Z" },
- { url = "https://files.pythonhosted.org/packages/45/3b/e0506f199dc8a90ff3b462f261f45d15c0703bb8c59f0da1add5f0c11a30/psycopg2_binary-2.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:875039274f8a2361e5207857899706da840768e2a775bf8c65e82f60b197df02", size = 2714968, upload-time = "2025-10-10T11:14:43.24Z" },
-]
-
-[[package]]
-name = "pycparser"
-version = "2.23"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" },
+ { url = "https://files.pythonhosted.org/packages/78/80/49bacf9e51617d8309f6f0123e29edc793f6f5f6700c7d1f1b20782fbb37/psycopg2_binary-2.9.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b818ceff717f98851a64bffd4c5eb5b3059ae280276dcecc52ac658dcf006a4", size = 3712314, upload-time = "2026-04-20T23:33:31.363Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/f2/98eeac7d60c43df9338287834edf9b3e69be68a2db78a57b1b81d705e735/psycopg2_binary-2.9.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fa0d7caca8635c56e373055094eeda3208d901d55dd0ff5abc1d4e47f82b56", size = 3822389, upload-time = "2026-04-20T23:33:34.178Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/7c/30575e75f14d5351a56a1971bb43fe7f8bf7edf1b654fb1bec65c42a8812/psycopg2_binary-2.9.12-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:864c261b3690e1207d14bbfe0a61e27567981b80c47a778561e49f676f7ce433", size = 4578448, upload-time = "2026-04-20T23:33:37.073Z" },
+ { url = "https://files.pythonhosted.org/packages/65/9b/4df366d89f28c527dc39d0b6c98a5ca74e30d37ac097b73f3352147568ae/psycopg2_binary-2.9.12-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c5ee5213445dd45312459029b8c4c0a695461eb517b753d2582315bd07995f5e", size = 4273705, upload-time = "2026-04-20T23:33:39.291Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/8a/c566803818eb03161ba869b6ba612bf7ad56816d98b9e5121e0a22ad6b0b/psycopg2_binary-2.9.12-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6f9cae1f848779b5b01f417e762c40d026ea93eb0648249a604728cda991dde3", size = 5893784, upload-time = "2026-04-20T23:33:41.658Z" },
+ { url = "https://files.pythonhosted.org/packages/63/fe/0dfa5797e0b229e0567bc378695224caf14d547f73b05be0c80549089772/psycopg2_binary-2.9.12-cp310-cp310-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:63a3ebbd543d3d1eda088ac99164e8c5bac15293ee91f20281fd17d050aee1c4", size = 4109306, upload-time = "2026-04-20T23:33:43.953Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/89/28063adf17a4ba501eedd9890feab0c649ee4d8bd0a97df0ff1e9584feab/psycopg2_binary-2.9.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d6fcbba8c9fed08a73b8ac61ea79e4821e45b1e92bb466230c5e746bbf3d5256", size = 3654400, upload-time = "2026-04-20T23:33:46.115Z" },
+ { url = "https://files.pythonhosted.org/packages/84/94/5a01de0aa4ead0b8d8d1aa4ec18cec0bd36d03fa714eaa5bb8a0b1b50020/psycopg2_binary-2.9.12-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:36512911ebb2b60a0c3e44d0bb5048c1980aced91235d133b7874f3d1d93487c", size = 3299215, upload-time = "2026-04-20T23:33:48.202Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/85/723bb085a61c6ac2dc0a0043f375f2fe7365363e27b073bad56ca5bda979/psycopg2_binary-2.9.12-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:8ffdb59fe88f99589e34354a130217aa1fd2d615612402d6edc8b3dbc7a44463", size = 3047724, upload-time = "2026-04-20T23:33:50.74Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/67/4d8b1e0d2fc4166677380eac0edf9cdff91013aca2546e8ef7bc04b56158/psycopg2_binary-2.9.12-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a46fe069b65255df410f856d842bc235f90e22ffdf532dda625fd4213d3fd9b1", size = 3349183, upload-time = "2026-04-20T23:33:59.635Z" },
+ { url = "https://files.pythonhosted.org/packages/73/99/21af7a5498637ea4dc91a17c281a53bc1d632fbafe00f6689fbfb32a9fed/psycopg2_binary-2.9.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab29414b25dcb698bf26bf213e3348abdcd07bbd5de032a5bec15bd75b298b03", size = 2757036, upload-time = "2026-04-20T23:34:01.606Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/19/d4ce60954f3bb9d8e3bc5e5c4d1f2487de2d3851bf2391d54954c9df12a6/psycopg2_binary-2.9.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5c8ce6c61bd1b1f6b9c24ee32211599f6166af2c55abb19456090a21fd16554b", size = 3712338, upload-time = "2026-04-20T23:34:03.961Z" },
+ { url = "https://files.pythonhosted.org/packages/53/71/c85409ee0d78890f0660eff262e815e7dd2bb741a17611d82e9e8cd9dc5e/psycopg2_binary-2.9.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4a9eaa6e7f4ff91bec10aa3fb296878e75187bced5cc4bafe17dc40915e1326", size = 3822407, upload-time = "2026-04-20T23:34:05.977Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/ed/60486c2c7f0d4d1ede2bfb1ed27e2498477ce646bc7f6b2759906303117e/psycopg2_binary-2.9.12-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c6528cefc8e50fcc6f4a107e27a672058b36cc5736d665476aeb413ba88dbb06", size = 4578425, upload-time = "2026-04-20T23:34:08.246Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/b9/656cb03fad9f4f49f2145c334b1126ee75189929ca4e6187d485a2d59951/psycopg2_binary-2.9.12-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e4e184b1fb6072bf05388aa41c697e1b2d01b3473f107e7ec44f186a32cfd0b8", size = 4273709, upload-time = "2026-04-20T23:34:10.974Z" },
+ { url = "https://files.pythonhosted.org/packages/99/66/08cf0da0e25cc6fb142c89be45fc8418792858f0c4cbff5e24530ff02cd6/psycopg2_binary-2.9.12-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4766ab678563054d3f1d064a4db19cc4b5f9e3a8d9018592a8285cf200c248f3", size = 5893779, upload-time = "2026-04-20T23:34:13.905Z" },
+ { url = "https://files.pythonhosted.org/packages/17/d7/eecd9ce8e146d3721115d82d3836efdbb712187e4590325df549989d18f4/psycopg2_binary-2.9.12-cp311-cp311-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5a0253224780c978746cb9be55a946bcdaf40fe3519c0f622924cdabdafe2c39", size = 4109308, upload-time = "2026-04-20T23:34:16.761Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/2e/b1dc289b362cc8d45697b57eefbd673186f49a4ea0906928988e3affcc98/psycopg2_binary-2.9.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0dc9228d47c46bda253d2ecd6bb93b56a9f2d7ad33b684a1fa3622bf74ffe30c", size = 3654405, upload-time = "2026-04-20T23:34:19.303Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/e4/4c4aea6473214dbdbd0fbba11aa4691e76dc01722c55724c5951719865ff/psycopg2_binary-2.9.12-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f921f3cd87035ef7df233383011d7a53ea1d346224752c1385f1edfd790ceb6a", size = 3299187, upload-time = "2026-04-20T23:34:21.206Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/5d/b03b99986446a4f57b170ed9a2579fb7ff9783ca0fa5226b19db99737fee/psycopg2_binary-2.9.12-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3d999bd982a723113c1a45b55a7a6a90d64d0ed2278020ed625c490ff7bef96c", size = 3047716, upload-time = "2026-04-20T23:34:23.077Z" },
+ { url = "https://files.pythonhosted.org/packages/14/86/382ee4afbd1d97500c9d2862b20c2fdeddf4b7335e984df3fb4309f64108/psycopg2_binary-2.9.12-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29d4d134bd0ab46ffb04e94aa3c5fa3ef582e9026609165e2f758ff76fc3a3be", size = 3349237, upload-time = "2026-04-20T23:34:25.211Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/16/9a57c75ba1eda7165c017342f526810d5f5a12647dde749c99ae9a7141d7/psycopg2_binary-2.9.12-cp311-cp311-win_amd64.whl", hash = "sha256:cb4a1dacdd48077150dc762a9e5ddbf32c256d66cb46f80839391aa458774936", size = 2757036, upload-time = "2026-04-20T23:34:27.77Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/9f/ef4ef3c8e15083df90ca35265cfd1a081a2f0cc07bb229c6314c6af817f4/psycopg2_binary-2.9.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5cdc05117180c5fa9c40eea8ea559ce64d73824c39d928b7da9fb5f6a9392433", size = 3712459, upload-time = "2026-04-20T23:34:30.549Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/01/3dd14e46ba48c1e1a6ec58ee599fa1b5efa00c246d5046cd903d0eeb1af1/psycopg2_binary-2.9.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3227a3bc228c10d21011a99245edca923e4e8bf461857e869a507d9a41fe9f6", size = 3822936, upload-time = "2026-04-20T23:34:32.77Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/f7/0640e4901119d8a9f7a1784b927f494e2198e213ceb593753d1f2c8b1b30/psycopg2_binary-2.9.12-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:995ce929eede89db6254b50827e2b7fd61e50d11f0b116b29fffe4a2e53c4580", size = 4578676, upload-time = "2026-04-20T23:34:35.18Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/55/44df3965b5f297c50cc0b1b594a31c67d6127a9d133045b8a66611b14dfb/psycopg2_binary-2.9.12-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9fe06d93e72f1c048e731a2e3e7854a5bfaa58fc736068df90b352cefe66f03f", size = 4274917, upload-time = "2026-04-20T23:34:37.982Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/4b/74535248b1eac0c9336862e8617c765ac94dac76f9e25d7c4a79588c8907/psycopg2_binary-2.9.12-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40e7b28b63aaf737cb3a1edc3a9bbc9a9f4ad3dcb7152e8c1130e4050eddcb7d", size = 5894843, upload-time = "2026-04-20T23:34:40.856Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/ba/f1bf8d2ae71868ad800b661099086ee52bc0f8d9f05be1acd8ebb06757cc/psycopg2_binary-2.9.12-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:89d19a9f7899e8eb0656a2b3a08e0da04c720a06db6e0033eab5928aabe60fa9", size = 4110556, upload-time = "2026-04-20T23:34:44.016Z" },
+ { url = "https://files.pythonhosted.org/packages/45/46/c15706c338403b7c420bcc0c2905aad116cc064545686d8bf85f1999ea00/psycopg2_binary-2.9.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:612b965daee295ae2da8f8218ce1d274645dc76ef3f1abf6a0a94fd57eff876d", size = 3655714, upload-time = "2026-04-20T23:34:46.233Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/7c/a2d5dc09b64a4564db242a0fe418fde7d33f6f8259dd2c5b9d7def00fb5a/psycopg2_binary-2.9.12-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b9a339b79d37c1b45f3235265f07cdeb0cb5ad7acd2ac7720a5920989c17c24e", size = 3301154, upload-time = "2026-04-20T23:34:49.528Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/e8/cc8c9a4ce71461f9ec548d38cadc41dc184b34c73e6455450775a9334ccd/psycopg2_binary-2.9.12-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:3471336e1acfd9c7fe507b8bad5af9317b6a89294f9eb37bd9a030bb7bebcdc6", size = 3048882, upload-time = "2026-04-20T23:34:51.86Z" },
+ { url = "https://files.pythonhosted.org/packages/19/6a/31e2296bc0787c5ab75d3d118e40b239db8151b5192b90b77c72bc9256e9/psycopg2_binary-2.9.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7af18183109e23502c8b2ae7f6926c0882766f35b5175a4cd737ad825e4d7a1b", size = 3351298, upload-time = "2026-04-20T23:34:54.124Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/a8/75f4e3e11203b590150abed2cf7794b9c9c9f7eceddae955191138b44dde/psycopg2_binary-2.9.12-cp312-cp312-win_amd64.whl", hash = "sha256:398fcd4db988c7d7d3713e2b8e18939776fd3fb447052daae4f24fa39daede4c", size = 2757230, upload-time = "2026-04-20T23:34:56.242Z" },
+ { url = "https://files.pythonhosted.org/packages/91/bb/4608c96f970f6e0c56572e87027ef4404f709382a3503e9934526d7ba051/psycopg2_binary-2.9.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7c729a73c7b1b84de3582f73cdd27d905121dc2c531f3d9a3c32a3011033b965", size = 3712419, upload-time = "2026-04-20T23:34:58.754Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/af/48f76af9d50d61cf390f8cd657b503168b089e2e9298e48465d029fcc713/psycopg2_binary-2.9.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4413d0caef93c5cf50b96863df4c2efe8c269bf2267df353225595e7e15e8df7", size = 3822990, upload-time = "2026-04-20T23:35:00.821Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/df/aba0f99397cd811d32e06fc0cc781f1f3ce98bc0e729cb423925085d781a/psycopg2_binary-2.9.12-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4dfcf8e45ebb0c663be34a3442f65e17311f3367089cd4e5e3a3e8e62c978777", size = 4578696, upload-time = "2026-04-20T23:35:03.409Z" },
+ { url = "https://files.pythonhosted.org/packages/95/9c/eaa74021ac4e4d5c2f83d82fc6615a63f4fe6c94dc4e94c3990427053f67/psycopg2_binary-2.9.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c41321a14dd74aceb6a9a643b9253a334521babfa763fa873e33d89cfa122fb5", size = 4274982, upload-time = "2026-04-20T23:35:05.583Z" },
+ { url = "https://files.pythonhosted.org/packages/35/ed/c25deff98bd26187ba48b3b250a3ffc3037c46c5b89362534a15d200e0db/psycopg2_binary-2.9.12-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83946ba43979ebfdc99a3cd0ee775c89f221df026984ba19d46133d8d75d3cd9", size = 5894867, upload-time = "2026-04-20T23:35:07.902Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/81/8d0e21ca77373c6c9589e5c4528f6e8f0c08c62cafc76fb0bddb7a2cee22/psycopg2_binary-2.9.12-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:411e85815652d13560fbe731878daa5d92378c4995a22302071890ec3397d019", size = 4110578, upload-time = "2026-04-20T23:35:10.149Z" },
+ { url = "https://files.pythonhosted.org/packages/00/fc/f481e2435bd8f742d0123309174aae4165160ad3ef17c1b99c3622c241d2/psycopg2_binary-2.9.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c8ad4c08e00f7679559eaed7aff1edfffc60c086b976f93972f686384a95e2c", size = 3655816, upload-time = "2026-04-20T23:35:12.56Z" },
+ { url = "https://files.pythonhosted.org/packages/53/79/b9f46466bdbe9f239c96cde8be33c1aace4842f06013b47b730dc9759187/psycopg2_binary-2.9.12-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:00814e40fa23c2b37ef0a1e3c749d89982c73a9cb5046137f0752a22d432e82f", size = 3301307, upload-time = "2026-04-20T23:35:15.029Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/19/7dc003b32fe35024df89b658104f7c8538a8b2dcbde7a4e746ce929742e7/psycopg2_binary-2.9.12-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:98062447aebc20ed20add1f547a364fd0ef8933640d5372ff1873f8deb9b61be", size = 3048968, upload-time = "2026-04-20T23:35:16.757Z" },
+ { url = "https://files.pythonhosted.org/packages/91/58/2dbd7db5c604d45f4950d988506aae672a14126ec22998ced5021cbb76bb/psycopg2_binary-2.9.12-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:66a7685d7e548f10fb4ce32fb01a7b7f4aa702134de92a292c7bd9e0d3dbd290", size = 3351369, upload-time = "2026-04-20T23:35:18.933Z" },
+ { url = "https://files.pythonhosted.org/packages/42/ee/dee8dcaad07f735824de3d6563bc67119fa6c28257b17977a8d624f02fab/psycopg2_binary-2.9.12-cp313-cp313-win_amd64.whl", hash = "sha256:b6937f5fe4e180aeee87de907a2fa982ded6f7f15d7218f78a083e4e1d68f2a0", size = 2757347, upload-time = "2026-04-20T23:35:21.283Z" },
+ { url = "https://files.pythonhosted.org/packages/13/1b/708c0dca874acfad6d65314271859899a79007686f3a1f74e82a2ed4b645/psycopg2_binary-2.9.12-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6f3b3de8a74ef8db215f22edffb19e32dc6fa41340456de7ec99efdc8a7b3ec2", size = 3712428, upload-time = "2026-04-20T23:35:23.453Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/39/ddbea9d4b4de6aca9431b6ed253f530f8a02d3b8f9bcfd0dbfe2b3de6fe4/psycopg2_binary-2.9.12-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1006fb62f0f0bc5ce256a832356c6262e91be43f5e4eb15b5eaf38079464caf2", size = 3823184, upload-time = "2026-04-20T23:35:25.92Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/a0/bc2fef74b106fa345567122a0659e6d94512ed7dc0131ec44c9e5aba3725/psycopg2_binary-2.9.12-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:840066105706cd2eb29b9a1c2329620056582a4bf3e8169dec5c447042d0869f", size = 4579157, upload-time = "2026-04-20T23:35:28.542Z" },
+ { url = "https://files.pythonhosted.org/packages/57/d7/d4e3b2005d3de607ca4fbb0e8742e248056e52184a6b94ebda3c1c2c329b/psycopg2_binary-2.9.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:863f5d12241ebe1c76a72a04c2113b6dc905f90b9cef0e9be0efd994affd9354", size = 4274970, upload-time = "2026-04-20T23:35:30.418Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/42/c9853f8db3967fe08bcde11f53d53b85d351750cae726ce001cb68afa9c1/psycopg2_binary-2.9.12-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a99eaab34a9010f1a086b126de467466620a750634d114d20455f3a824aae033", size = 5895175, upload-time = "2026-04-20T23:35:33.584Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/fd/b82b5601a97630308bef079f545ffec481bbbc795c2ba5ec416a01d03f60/psycopg2_binary-2.9.12-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ffdd7dc5463ccd61845ac37b7012d0f35a1548df9febe14f8dd549be4a0bc81e", size = 4110658, upload-time = "2026-04-20T23:35:35.638Z" },
+ { url = "https://files.pythonhosted.org/packages/62/8c/32ca69b0389ef25dd22937bf9e8fbe2ce27aea20b05ded48c4ce4cb42475/psycopg2_binary-2.9.12-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:54a0dfecab1b48731f934e06139dfe11e24219fb6d0ceb32177cf0375f14c7b5", size = 3656251, upload-time = "2026-04-20T23:35:37.854Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/29/96992a2b59e3b9d730fcf9612d0a387305025dc867a9fc490a9e496e074e/psycopg2_binary-2.9.12-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:96937c9c5d891f772430f418a7a8b4691a90c3e6b93cf72b5bd7cad8cbca32a5", size = 3301810, upload-time = "2026-04-20T23:35:39.927Z" },
+ { url = "https://files.pythonhosted.org/packages/56/ad/44b06659949b243ae10112cd3b20a197f9bf3e81d5651379b9eb889bfaad/psycopg2_binary-2.9.12-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:77b348775efd4cdab410ec6609d81ccecd1139c90265fa583a7255c8064bc03d", size = 3048977, upload-time = "2026-04-20T23:35:41.806Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/f2/10a1bcebadb6aa55e280e1f58975c36a7b560ea525184c7aa4064c466633/psycopg2_binary-2.9.12-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:527e6342b3e44c2f0544f6b8e927d60de7f163f5723b8f1dfa7d2a84298738cd", size = 3351466, upload-time = "2026-04-20T23:35:43.993Z" },
+ { url = "https://files.pythonhosted.org/packages/20/be/b732c8418ffa5bcfda002890f5dc4c869fc17db66ff11f53b17cfe44afc0/psycopg2_binary-2.9.12-cp314-cp314-win_amd64.whl", hash = "sha256:f12ae41fcafadb39b2785e64a40f9db05d6de2ac114077457e0e7c597f3af980", size = 2848762, upload-time = "2026-04-20T23:35:46.421Z" },
]
[[package]]
name = "pycparser"
version = "3.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
@@ -1066,20 +895,20 @@ wheels = [
[[package]]
name = "pyln-client"
-version = "25.12.1"
+version = "26.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyln-bolt7" },
{ name = "pyln-proto" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/75/b1/28c46889cf1822f89a5d23644aa08806cedd17c2553afee2d72c4e101c62/pyln_client-25.12.1.tar.gz", hash = "sha256:4e92d18ce79879b891355d4a9bb79117466e98e12b83c1b5f321fc3e77039d5b", size = 92116, upload-time = "2026-01-15T00:04:15.621Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/8a/14/0faf6b8b04f368629897a010357d3b8d21c8a800b972b433a358caebe32b/pyln_client-26.4.tar.gz", hash = "sha256:e696076fcf1329ee22198097b8139a096f653cbbfc6a03e471455ca6f5d68a46", size = 92160, upload-time = "2026-04-20T04:58:12.666Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/41/51/fb302f67a8e62eaa49d869b489cad61dac66fda9a3fd737ac56422b1b920/pyln_client-25.12.1-py3-none-any.whl", hash = "sha256:cb8c42bf4b432a3a2ec0b1ee94b96f5ad91fee1ddd0289930d55c988ab801293", size = 37633, upload-time = "2026-01-15T00:04:14.386Z" },
+ { url = "https://files.pythonhosted.org/packages/60/41/f67df5064b4b9d258fb30e96e1d3ca8f0395c7c0098b24091dde6238fb8e/pyln_client-26.4-py3-none-any.whl", hash = "sha256:d5470e1ecccc1b6e46e39658c1019c62868c5aed4a0203635052803ddedcce2e", size = 37655, upload-time = "2026-04-20T04:58:11.429Z" },
]
[[package]]
name = "pyln-proto"
-version = "25.12.1"
+version = "26.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "base58" },
@@ -1088,32 +917,31 @@ dependencies = [
{ name = "cryptography" },
{ name = "pysocks" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/5b/b7/0be4a1b81e99eb9d4ad6b048ee7cdb2ae0b50fdad4e9f2e61b2e3f51efe3/pyln_proto-25.12.1.tar.gz", hash = "sha256:7167f361a6bdc9c225749c572fcc23f28f9734dee367252f7fbad13df200984b", size = 44860, upload-time = "2026-01-15T00:04:16.541Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/0d/35/5d30332fcaa8d77be87290c5534d45c48822310611ae6ea6d3e48c242ded/pyln_proto-26.4.tar.gz", hash = "sha256:dde9e243c7bf6fbcf7904e0dbd18c4f05dc17e668b074bfab090a7376e3de6cf", size = 44861, upload-time = "2026-04-20T04:58:09.361Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ac/ab/f11c2f4d7a74c79f3a89f37e051461e5e93049263eb6dd9f98944aee90a0/pyln_proto-25.12.1-py3-none-any.whl", hash = "sha256:84990233ae7ba6a39e4ec9c44fc978efbf74dcfb82953f32921c242807c85764", size = 31834, upload-time = "2026-01-15T00:04:14.893Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/c9/8a34960e1e9550f87697d1f05208d9cc916c14419f18f2d6013801079fc1/pyln_proto-26.4-py3-none-any.whl", hash = "sha256:97772d285aa0d0c8a1545577aeef8821e08d59676f63ae760d270e1b3015bc9d", size = 31811, upload-time = "2026-04-20T04:58:08.369Z" },
]
[[package]]
name = "pyln-testing"
-version = "25.12.1"
+version = "26.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cheroot" },
{ name = "ephemeral-port-reserve" },
{ name = "flask" },
- { name = "jsonschema", version = "4.25.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "jsonschema", version = "4.26.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "jsonschema" },
+ { name = "mnemonic" },
{ name = "psutil" },
{ name = "psycopg2-binary" },
{ name = "pyln-client" },
{ name = "pytest" },
{ name = "python-bitcoinlib" },
- { name = "requests", version = "2.32.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "requests", version = "2.33.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "requests" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/ab/d4/5ce2c805b6ab3297a00bfd8f759b1a511a91514832ab1238e24725f8db51/pyln_testing-25.12.1.tar.gz", hash = "sha256:1835e3450997c6266926487d190d14b367bcec23e4e6f04a70101b3c95c67443", size = 51333, upload-time = "2026-01-15T00:04:12.781Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/17/7e/275f0416e30faa3093ad31703f3d8702dc06569164a185813b23672ba6d9/pyln_testing-26.4.tar.gz", hash = "sha256:cca1f4fec65f12bfda809674ea7c231285a96ef0b8bc2c69ef4919f1b465d2ae", size = 52609, upload-time = "2026-04-20T04:58:07.746Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/eb/83/276aa759def88a9ef79f639ee691aadf1cdbadfc4a0526cb536f68df4939/pyln_testing-25.12.1-py3-none-any.whl", hash = "sha256:2e2c7dfae4d03069f854237070a2567a31b68f625864950515bbb2d0a3d82f41", size = 53080, upload-time = "2026-01-15T00:04:11.882Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/c4/3cb55bf86a2499510a24b310897903efafce847869eb1ec1c7b67b7fcfa4/pyln_testing-26.4-py3-none-any.whl", hash = "sha256:ccb7641bbbb1b6b650f1b8238aacf04d7ebeea944ebd2855a901e25d18846804", size = 54365, upload-time = "2026-04-20T04:58:06.793Z" },
]
[[package]]
@@ -1132,8 +960,7 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
- { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "iniconfig" },
{ name = "packaging" },
{ name = "pluggy" },
{ name = "pygments" },
@@ -1144,34 +971,14 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
]
-[[package]]
-name = "pytest-asyncio"
-version = "1.2.0"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "backports-asyncio-runner", marker = "python_full_version < '3.10'" },
- { name = "pytest", marker = "python_full_version < '3.10'" },
- { name = "typing-extensions", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" },
-]
-
[[package]]
name = "pytest-asyncio"
version = "1.3.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
dependencies = [
- { name = "backports-asyncio-runner", marker = "python_full_version == '3.10.*'" },
- { name = "pytest", marker = "python_full_version >= '3.10'" },
- { name = "typing-extensions", marker = "python_full_version >= '3.10' and python_full_version < '3.13'" },
+ { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" },
+ { name = "pytest" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" }
wheels = [
@@ -1212,248 +1019,39 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/75/46/b388d0885cf799f5bc66ca9995c83e5b7e17cb737f812a7c2591aa789ea6/python_bitcoinlib-0.12.2-py3-none-any.whl", hash = "sha256:2f29a9f475f21c12169b3a6cc8820f34f11362d7ff1200a5703dce3e4e903a44", size = 106954, upload-time = "2023-06-03T18:37:08.524Z" },
]
-[[package]]
-name = "referencing"
-version = "0.36.2"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "attrs", marker = "python_full_version < '3.10'" },
- { name = "rpds-py", version = "0.27.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
- { name = "typing-extensions", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
-]
-
[[package]]
name = "referencing"
version = "0.37.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
dependencies = [
- { name = "attrs", marker = "python_full_version >= '3.10'" },
- { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
- { name = "typing-extensions", marker = "python_full_version >= '3.10' and python_full_version < '3.13'" },
+ { name = "attrs" },
+ { name = "rpds-py" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" },
]
-[[package]]
-name = "requests"
-version = "2.32.5"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-dependencies = [
- { name = "certifi", marker = "python_full_version < '3.10'" },
- { name = "charset-normalizer", marker = "python_full_version < '3.10'" },
- { name = "idna", marker = "python_full_version < '3.10'" },
- { name = "urllib3", marker = "python_full_version < '3.10'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" },
-]
-
[[package]]
name = "requests"
version = "2.33.1"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
dependencies = [
- { name = "certifi", marker = "python_full_version >= '3.10'" },
- { name = "charset-normalizer", marker = "python_full_version >= '3.10'" },
- { name = "idna", marker = "python_full_version >= '3.10'" },
- { name = "urllib3", marker = "python_full_version >= '3.10'" },
+ { name = "certifi" },
+ { name = "charset-normalizer" },
+ { name = "idna" },
+ { name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" },
]
-[[package]]
-name = "rpds-py"
-version = "0.27.1"
-source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version < '3.10'",
-]
-sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a5/ed/3aef893e2dd30e77e35d20d4ddb45ca459db59cead748cad9796ad479411/rpds_py-0.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:68afeec26d42ab3b47e541b272166a0b4400313946871cba3ed3a4fc0cab1cef", size = 371606, upload-time = "2025-08-27T12:12:25.189Z" },
- { url = "https://files.pythonhosted.org/packages/6d/82/9818b443e5d3eb4c83c3994561387f116aae9833b35c484474769c4a8faf/rpds_py-0.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74e5b2f7bb6fa38b1b10546d27acbacf2a022a8b5543efb06cfebc72a59c85be", size = 353452, upload-time = "2025-08-27T12:12:27.433Z" },
- { url = "https://files.pythonhosted.org/packages/99/c7/d2a110ffaaa397fc6793a83c7bd3545d9ab22658b7cdff05a24a4535cc45/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9024de74731df54546fab0bfbcdb49fae19159ecaecfc8f37c18d2c7e2c0bd61", size = 381519, upload-time = "2025-08-27T12:12:28.719Z" },
- { url = "https://files.pythonhosted.org/packages/5a/bc/e89581d1f9d1be7d0247eaef602566869fdc0d084008ba139e27e775366c/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31d3ebadefcd73b73928ed0b2fd696f7fefda8629229f81929ac9c1854d0cffb", size = 394424, upload-time = "2025-08-27T12:12:30.207Z" },
- { url = "https://files.pythonhosted.org/packages/ac/2e/36a6861f797530e74bb6ed53495f8741f1ef95939eed01d761e73d559067/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2e7f8f169d775dd9092a1743768d771f1d1300453ddfe6325ae3ab5332b4657", size = 523467, upload-time = "2025-08-27T12:12:31.808Z" },
- { url = "https://files.pythonhosted.org/packages/c4/59/c1bc2be32564fa499f988f0a5c6505c2f4746ef96e58e4d7de5cf923d77e/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d905d16f77eb6ab2e324e09bfa277b4c8e5e6b8a78a3e7ff8f3cdf773b4c013", size = 402660, upload-time = "2025-08-27T12:12:33.444Z" },
- { url = "https://files.pythonhosted.org/packages/0a/ec/ef8bf895f0628dd0a59e54d81caed6891663cb9c54a0f4bb7da918cb88cf/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50c946f048209e6362e22576baea09193809f87687a95a8db24e5fbdb307b93a", size = 384062, upload-time = "2025-08-27T12:12:34.857Z" },
- { url = "https://files.pythonhosted.org/packages/69/f7/f47ff154be8d9a5e691c083a920bba89cef88d5247c241c10b9898f595a1/rpds_py-0.27.1-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:3deab27804d65cd8289eb814c2c0e807c4b9d9916c9225e363cb0cf875eb67c1", size = 401289, upload-time = "2025-08-27T12:12:36.085Z" },
- { url = "https://files.pythonhosted.org/packages/3b/d9/ca410363efd0615814ae579f6829cafb39225cd63e5ea5ed1404cb345293/rpds_py-0.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b61097f7488de4be8244c89915da8ed212832ccf1e7c7753a25a394bf9b1f10", size = 417718, upload-time = "2025-08-27T12:12:37.401Z" },
- { url = "https://files.pythonhosted.org/packages/e3/a0/8cb5c2ff38340f221cc067cc093d1270e10658ba4e8d263df923daa18e86/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a3f29aba6e2d7d90528d3c792555a93497fe6538aa65eb675b44505be747808", size = 558333, upload-time = "2025-08-27T12:12:38.672Z" },
- { url = "https://files.pythonhosted.org/packages/6f/8c/1b0de79177c5d5103843774ce12b84caa7164dfc6cd66378768d37db11bf/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd6cd0485b7d347304067153a6dc1d73f7d4fd995a396ef32a24d24b8ac63ac8", size = 589127, upload-time = "2025-08-27T12:12:41.48Z" },
- { url = "https://files.pythonhosted.org/packages/c8/5e/26abb098d5e01266b0f3a2488d299d19ccc26849735d9d2b95c39397e945/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f4461bf931108c9fa226ffb0e257c1b18dc2d44cd72b125bec50ee0ab1248a9", size = 554899, upload-time = "2025-08-27T12:12:42.925Z" },
- { url = "https://files.pythonhosted.org/packages/de/41/905cc90ced13550db017f8f20c6d8e8470066c5738ba480d7ba63e3d136b/rpds_py-0.27.1-cp310-cp310-win32.whl", hash = "sha256:ee5422d7fb21f6a00c1901bf6559c49fee13a5159d0288320737bbf6585bd3e4", size = 217450, upload-time = "2025-08-27T12:12:44.813Z" },
- { url = "https://files.pythonhosted.org/packages/75/3d/6bef47b0e253616ccdf67c283e25f2d16e18ccddd38f92af81d5a3420206/rpds_py-0.27.1-cp310-cp310-win_amd64.whl", hash = "sha256:3e039aabf6d5f83c745d5f9a0a381d031e9ed871967c0a5c38d201aca41f3ba1", size = 228447, upload-time = "2025-08-27T12:12:46.204Z" },
- { url = "https://files.pythonhosted.org/packages/b5/c1/7907329fbef97cbd49db6f7303893bd1dd5a4a3eae415839ffdfb0762cae/rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881", size = 371063, upload-time = "2025-08-27T12:12:47.856Z" },
- { url = "https://files.pythonhosted.org/packages/11/94/2aab4bc86228bcf7c48760990273653a4900de89c7537ffe1b0d6097ed39/rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5", size = 353210, upload-time = "2025-08-27T12:12:49.187Z" },
- { url = "https://files.pythonhosted.org/packages/3a/57/f5eb3ecf434342f4f1a46009530e93fd201a0b5b83379034ebdb1d7c1a58/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e", size = 381636, upload-time = "2025-08-27T12:12:50.492Z" },
- { url = "https://files.pythonhosted.org/packages/ae/f4/ef95c5945e2ceb5119571b184dd5a1cc4b8541bbdf67461998cfeac9cb1e/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c", size = 394341, upload-time = "2025-08-27T12:12:52.024Z" },
- { url = "https://files.pythonhosted.org/packages/5a/7e/4bd610754bf492d398b61725eb9598ddd5eb86b07d7d9483dbcd810e20bc/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195", size = 523428, upload-time = "2025-08-27T12:12:53.779Z" },
- { url = "https://files.pythonhosted.org/packages/9f/e5/059b9f65a8c9149361a8b75094864ab83b94718344db511fd6117936ed2a/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52", size = 402923, upload-time = "2025-08-27T12:12:55.15Z" },
- { url = "https://files.pythonhosted.org/packages/f5/48/64cabb7daced2968dd08e8a1b7988bf358d7bd5bcd5dc89a652f4668543c/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed", size = 384094, upload-time = "2025-08-27T12:12:57.194Z" },
- { url = "https://files.pythonhosted.org/packages/ae/e1/dc9094d6ff566bff87add8a510c89b9e158ad2ecd97ee26e677da29a9e1b/rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a", size = 401093, upload-time = "2025-08-27T12:12:58.985Z" },
- { url = "https://files.pythonhosted.org/packages/37/8e/ac8577e3ecdd5593e283d46907d7011618994e1d7ab992711ae0f78b9937/rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde", size = 417969, upload-time = "2025-08-27T12:13:00.367Z" },
- { url = "https://files.pythonhosted.org/packages/66/6d/87507430a8f74a93556fe55c6485ba9c259949a853ce407b1e23fea5ba31/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21", size = 558302, upload-time = "2025-08-27T12:13:01.737Z" },
- { url = "https://files.pythonhosted.org/packages/3a/bb/1db4781ce1dda3eecc735e3152659a27b90a02ca62bfeea17aee45cc0fbc/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9", size = 589259, upload-time = "2025-08-27T12:13:03.127Z" },
- { url = "https://files.pythonhosted.org/packages/7b/0e/ae1c8943d11a814d01b482e1f8da903f88047a962dff9bbdadf3bd6e6fd1/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948", size = 554983, upload-time = "2025-08-27T12:13:04.516Z" },
- { url = "https://files.pythonhosted.org/packages/b2/d5/0b2a55415931db4f112bdab072443ff76131b5ac4f4dc98d10d2d357eb03/rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39", size = 217154, upload-time = "2025-08-27T12:13:06.278Z" },
- { url = "https://files.pythonhosted.org/packages/24/75/3b7ffe0d50dc86a6a964af0d1cc3a4a2cdf437cb7b099a4747bbb96d1819/rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15", size = 228627, upload-time = "2025-08-27T12:13:07.625Z" },
- { url = "https://files.pythonhosted.org/packages/8d/3f/4fd04c32abc02c710f09a72a30c9a55ea3cc154ef8099078fd50a0596f8e/rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746", size = 220998, upload-time = "2025-08-27T12:13:08.972Z" },
- { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" },
- { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" },
- { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" },
- { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" },
- { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" },
- { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" },
- { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" },
- { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" },
- { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" },
- { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" },
- { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" },
- { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" },
- { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" },
- { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" },
- { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" },
- { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" },
- { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" },
- { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" },
- { url = "https://files.pythonhosted.org/packages/fd/e8/1e430fe311e4799e02e2d1af7c765f024e95e17d651612425b226705f910/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf", size = 398395, upload-time = "2025-08-27T12:13:36.132Z" },
- { url = "https://files.pythonhosted.org/packages/82/95/9dc227d441ff2670651c27a739acb2535ccaf8b351a88d78c088965e5996/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2", size = 524334, upload-time = "2025-08-27T12:13:37.562Z" },
- { url = "https://files.pythonhosted.org/packages/87/01/a670c232f401d9ad461d9a332aa4080cd3cb1d1df18213dbd0d2a6a7ab51/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0", size = 407691, upload-time = "2025-08-27T12:13:38.94Z" },
- { url = "https://files.pythonhosted.org/packages/03/36/0a14aebbaa26fe7fab4780c76f2239e76cc95a0090bdb25e31d95c492fcd/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418", size = 386868, upload-time = "2025-08-27T12:13:40.192Z" },
- { url = "https://files.pythonhosted.org/packages/3b/03/8c897fb8b5347ff6c1cc31239b9611c5bf79d78c984430887a353e1409a1/rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d", size = 405469, upload-time = "2025-08-27T12:13:41.496Z" },
- { url = "https://files.pythonhosted.org/packages/da/07/88c60edc2df74850d496d78a1fdcdc7b54360a7f610a4d50008309d41b94/rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274", size = 422125, upload-time = "2025-08-27T12:13:42.802Z" },
- { url = "https://files.pythonhosted.org/packages/6b/86/5f4c707603e41b05f191a749984f390dabcbc467cf833769b47bf14ba04f/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd", size = 562341, upload-time = "2025-08-27T12:13:44.472Z" },
- { url = "https://files.pythonhosted.org/packages/b2/92/3c0cb2492094e3cd9baf9e49bbb7befeceb584ea0c1a8b5939dca4da12e5/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2", size = 592511, upload-time = "2025-08-27T12:13:45.898Z" },
- { url = "https://files.pythonhosted.org/packages/10/bb/82e64fbb0047c46a168faa28d0d45a7851cd0582f850b966811d30f67ad8/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002", size = 557736, upload-time = "2025-08-27T12:13:47.408Z" },
- { url = "https://files.pythonhosted.org/packages/00/95/3c863973d409210da7fb41958172c6b7dbe7fc34e04d3cc1f10bb85e979f/rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3", size = 221462, upload-time = "2025-08-27T12:13:48.742Z" },
- { url = "https://files.pythonhosted.org/packages/ce/2c/5867b14a81dc217b56d95a9f2a40fdbc56a1ab0181b80132beeecbd4b2d6/rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83", size = 232034, upload-time = "2025-08-27T12:13:50.11Z" },
- { url = "https://files.pythonhosted.org/packages/c7/78/3958f3f018c01923823f1e47f1cc338e398814b92d83cd278364446fac66/rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d", size = 222392, upload-time = "2025-08-27T12:13:52.587Z" },
- { url = "https://files.pythonhosted.org/packages/01/76/1cdf1f91aed5c3a7bf2eba1f1c4e4d6f57832d73003919a20118870ea659/rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228", size = 358355, upload-time = "2025-08-27T12:13:54.012Z" },
- { url = "https://files.pythonhosted.org/packages/c3/6f/bf142541229374287604caf3bb2a4ae17f0a580798fd72d3b009b532db4e/rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92", size = 342138, upload-time = "2025-08-27T12:13:55.791Z" },
- { url = "https://files.pythonhosted.org/packages/1a/77/355b1c041d6be40886c44ff5e798b4e2769e497b790f0f7fd1e78d17e9a8/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2", size = 380247, upload-time = "2025-08-27T12:13:57.683Z" },
- { url = "https://files.pythonhosted.org/packages/d6/a4/d9cef5c3946ea271ce2243c51481971cd6e34f21925af2783dd17b26e815/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723", size = 390699, upload-time = "2025-08-27T12:13:59.137Z" },
- { url = "https://files.pythonhosted.org/packages/3a/06/005106a7b8c6c1a7e91b73169e49870f4af5256119d34a361ae5240a0c1d/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802", size = 521852, upload-time = "2025-08-27T12:14:00.583Z" },
- { url = "https://files.pythonhosted.org/packages/e5/3e/50fb1dac0948e17a02eb05c24510a8fe12d5ce8561c6b7b7d1339ab7ab9c/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f", size = 402582, upload-time = "2025-08-27T12:14:02.034Z" },
- { url = "https://files.pythonhosted.org/packages/cb/b0/f4e224090dc5b0ec15f31a02d746ab24101dd430847c4d99123798661bfc/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2", size = 384126, upload-time = "2025-08-27T12:14:03.437Z" },
- { url = "https://files.pythonhosted.org/packages/54/77/ac339d5f82b6afff1df8f0fe0d2145cc827992cb5f8eeb90fc9f31ef7a63/rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21", size = 399486, upload-time = "2025-08-27T12:14:05.443Z" },
- { url = "https://files.pythonhosted.org/packages/d6/29/3e1c255eee6ac358c056a57d6d6869baa00a62fa32eea5ee0632039c50a3/rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef", size = 414832, upload-time = "2025-08-27T12:14:06.902Z" },
- { url = "https://files.pythonhosted.org/packages/3f/db/6d498b844342deb3fa1d030598db93937a9964fcf5cb4da4feb5f17be34b/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081", size = 557249, upload-time = "2025-08-27T12:14:08.37Z" },
- { url = "https://files.pythonhosted.org/packages/60/f3/690dd38e2310b6f68858a331399b4d6dbb9132c3e8ef8b4333b96caf403d/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd", size = 587356, upload-time = "2025-08-27T12:14:10.034Z" },
- { url = "https://files.pythonhosted.org/packages/86/e3/84507781cccd0145f35b1dc32c72675200c5ce8d5b30f813e49424ef68fc/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7", size = 555300, upload-time = "2025-08-27T12:14:11.783Z" },
- { url = "https://files.pythonhosted.org/packages/e5/ee/375469849e6b429b3516206b4580a79e9ef3eb12920ddbd4492b56eaacbe/rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688", size = 216714, upload-time = "2025-08-27T12:14:13.629Z" },
- { url = "https://files.pythonhosted.org/packages/21/87/3fc94e47c9bd0742660e84706c311a860dcae4374cf4a03c477e23ce605a/rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797", size = 228943, upload-time = "2025-08-27T12:14:14.937Z" },
- { url = "https://files.pythonhosted.org/packages/70/36/b6e6066520a07cf029d385de869729a895917b411e777ab1cde878100a1d/rpds_py-0.27.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:acb9aafccaae278f449d9c713b64a9e68662e7799dbd5859e2c6b3c67b56d334", size = 362472, upload-time = "2025-08-27T12:14:16.333Z" },
- { url = "https://files.pythonhosted.org/packages/af/07/b4646032e0dcec0df9c73a3bd52f63bc6c5f9cda992f06bd0e73fe3fbebd/rpds_py-0.27.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b7fb801aa7f845ddf601c49630deeeccde7ce10065561d92729bfe81bd21fb33", size = 345676, upload-time = "2025-08-27T12:14:17.764Z" },
- { url = "https://files.pythonhosted.org/packages/b0/16/2f1003ee5d0af4bcb13c0cf894957984c32a6751ed7206db2aee7379a55e/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0dd05afb46597b9a2e11c351e5e4283c741237e7f617ffb3252780cca9336a", size = 385313, upload-time = "2025-08-27T12:14:19.829Z" },
- { url = "https://files.pythonhosted.org/packages/05/cd/7eb6dd7b232e7f2654d03fa07f1414d7dfc980e82ba71e40a7c46fd95484/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b6dfb0e058adb12d8b1d1b25f686e94ffa65d9995a5157afe99743bf7369d62b", size = 399080, upload-time = "2025-08-27T12:14:21.531Z" },
- { url = "https://files.pythonhosted.org/packages/20/51/5829afd5000ec1cb60f304711f02572d619040aa3ec033d8226817d1e571/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed090ccd235f6fa8bb5861684567f0a83e04f52dfc2e5c05f2e4b1309fcf85e7", size = 523868, upload-time = "2025-08-27T12:14:23.485Z" },
- { url = "https://files.pythonhosted.org/packages/05/2c/30eebca20d5db95720ab4d2faec1b5e4c1025c473f703738c371241476a2/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf876e79763eecf3e7356f157540d6a093cef395b65514f17a356f62af6cc136", size = 408750, upload-time = "2025-08-27T12:14:24.924Z" },
- { url = "https://files.pythonhosted.org/packages/90/1a/cdb5083f043597c4d4276eae4e4c70c55ab5accec078da8611f24575a367/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12ed005216a51b1d6e2b02a7bd31885fe317e45897de81d86dcce7d74618ffff", size = 387688, upload-time = "2025-08-27T12:14:27.537Z" },
- { url = "https://files.pythonhosted.org/packages/7c/92/cf786a15320e173f945d205ab31585cc43969743bb1a48b6888f7a2b0a2d/rpds_py-0.27.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:ee4308f409a40e50593c7e3bb8cbe0b4d4c66d1674a316324f0c2f5383b486f9", size = 407225, upload-time = "2025-08-27T12:14:28.981Z" },
- { url = "https://files.pythonhosted.org/packages/33/5c/85ee16df5b65063ef26017bef33096557a4c83fbe56218ac7cd8c235f16d/rpds_py-0.27.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b08d152555acf1f455154d498ca855618c1378ec810646fcd7c76416ac6dc60", size = 423361, upload-time = "2025-08-27T12:14:30.469Z" },
- { url = "https://files.pythonhosted.org/packages/4b/8e/1c2741307fcabd1a334ecf008e92c4f47bb6f848712cf15c923becfe82bb/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dce51c828941973a5684d458214d3a36fcd28da3e1875d659388f4f9f12cc33e", size = 562493, upload-time = "2025-08-27T12:14:31.987Z" },
- { url = "https://files.pythonhosted.org/packages/04/03/5159321baae9b2222442a70c1f988cbbd66b9be0675dd3936461269be360/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c1476d6f29eb81aa4151c9a31219b03f1f798dc43d8af1250a870735516a1212", size = 592623, upload-time = "2025-08-27T12:14:33.543Z" },
- { url = "https://files.pythonhosted.org/packages/ff/39/c09fd1ad28b85bc1d4554a8710233c9f4cefd03d7717a1b8fbfd171d1167/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ce0cac322b0d69b63c9cdb895ee1b65805ec9ffad37639f291dd79467bee675", size = 558800, upload-time = "2025-08-27T12:14:35.436Z" },
- { url = "https://files.pythonhosted.org/packages/c5/d6/99228e6bbcf4baa764b18258f519a9035131d91b538d4e0e294313462a98/rpds_py-0.27.1-cp314-cp314-win32.whl", hash = "sha256:dfbfac137d2a3d0725758cd141f878bf4329ba25e34979797c89474a89a8a3a3", size = 221943, upload-time = "2025-08-27T12:14:36.898Z" },
- { url = "https://files.pythonhosted.org/packages/be/07/c802bc6b8e95be83b79bdf23d1aa61d68324cb1006e245d6c58e959e314d/rpds_py-0.27.1-cp314-cp314-win_amd64.whl", hash = "sha256:a6e57b0abfe7cc513450fcf529eb486b6e4d3f8aee83e92eb5f1ef848218d456", size = 233739, upload-time = "2025-08-27T12:14:38.386Z" },
- { url = "https://files.pythonhosted.org/packages/c8/89/3e1b1c16d4c2d547c5717377a8df99aee8099ff050f87c45cb4d5fa70891/rpds_py-0.27.1-cp314-cp314-win_arm64.whl", hash = "sha256:faf8d146f3d476abfee026c4ae3bdd9ca14236ae4e4c310cbd1cf75ba33d24a3", size = 223120, upload-time = "2025-08-27T12:14:39.82Z" },
- { url = "https://files.pythonhosted.org/packages/62/7e/dc7931dc2fa4a6e46b2a4fa744a9fe5c548efd70e0ba74f40b39fa4a8c10/rpds_py-0.27.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:ba81d2b56b6d4911ce735aad0a1d4495e808b8ee4dc58715998741a26874e7c2", size = 358944, upload-time = "2025-08-27T12:14:41.199Z" },
- { url = "https://files.pythonhosted.org/packages/e6/22/4af76ac4e9f336bfb1a5f240d18a33c6b2fcaadb7472ac7680576512b49a/rpds_py-0.27.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:84f7d509870098de0e864cad0102711c1e24e9b1a50ee713b65928adb22269e4", size = 342283, upload-time = "2025-08-27T12:14:42.699Z" },
- { url = "https://files.pythonhosted.org/packages/1c/15/2a7c619b3c2272ea9feb9ade67a45c40b3eeb500d503ad4c28c395dc51b4/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e960fc78fecd1100539f14132425e1d5fe44ecb9239f8f27f079962021523e", size = 380320, upload-time = "2025-08-27T12:14:44.157Z" },
- { url = "https://files.pythonhosted.org/packages/a2/7d/4c6d243ba4a3057e994bb5bedd01b5c963c12fe38dde707a52acdb3849e7/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62f85b665cedab1a503747617393573995dac4600ff51869d69ad2f39eb5e817", size = 391760, upload-time = "2025-08-27T12:14:45.845Z" },
- { url = "https://files.pythonhosted.org/packages/b4/71/b19401a909b83bcd67f90221330bc1ef11bc486fe4e04c24388d28a618ae/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fed467af29776f6556250c9ed85ea5a4dd121ab56a5f8b206e3e7a4c551e48ec", size = 522476, upload-time = "2025-08-27T12:14:47.364Z" },
- { url = "https://files.pythonhosted.org/packages/e4/44/1a3b9715c0455d2e2f0f6df5ee6d6f5afdc423d0773a8a682ed2b43c566c/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2729615f9d430af0ae6b36cf042cb55c0936408d543fb691e1a9e36648fd35a", size = 403418, upload-time = "2025-08-27T12:14:49.991Z" },
- { url = "https://files.pythonhosted.org/packages/1c/4b/fb6c4f14984eb56673bc868a66536f53417ddb13ed44b391998100a06a96/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b207d881a9aef7ba753d69c123a35d96ca7cb808056998f6b9e8747321f03b8", size = 384771, upload-time = "2025-08-27T12:14:52.159Z" },
- { url = "https://files.pythonhosted.org/packages/c0/56/d5265d2d28b7420d7b4d4d85cad8ef891760f5135102e60d5c970b976e41/rpds_py-0.27.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:639fd5efec029f99b79ae47e5d7e00ad8a773da899b6309f6786ecaf22948c48", size = 400022, upload-time = "2025-08-27T12:14:53.859Z" },
- { url = "https://files.pythonhosted.org/packages/8f/e9/9f5fc70164a569bdd6ed9046486c3568d6926e3a49bdefeeccfb18655875/rpds_py-0.27.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fecc80cb2a90e28af8a9b366edacf33d7a91cbfe4c2c4544ea1246e949cfebeb", size = 416787, upload-time = "2025-08-27T12:14:55.673Z" },
- { url = "https://files.pythonhosted.org/packages/d4/64/56dd03430ba491db943a81dcdef115a985aac5f44f565cd39a00c766d45c/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42a89282d711711d0a62d6f57d81aa43a1368686c45bc1c46b7f079d55692734", size = 557538, upload-time = "2025-08-27T12:14:57.245Z" },
- { url = "https://files.pythonhosted.org/packages/3f/36/92cc885a3129993b1d963a2a42ecf64e6a8e129d2c7cc980dbeba84e55fb/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:cf9931f14223de59551ab9d38ed18d92f14f055a5f78c1d8ad6493f735021bbb", size = 588512, upload-time = "2025-08-27T12:14:58.728Z" },
- { url = "https://files.pythonhosted.org/packages/dd/10/6b283707780a81919f71625351182b4f98932ac89a09023cb61865136244/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0", size = 555813, upload-time = "2025-08-27T12:15:00.334Z" },
- { url = "https://files.pythonhosted.org/packages/04/2e/30b5ea18c01379da6272a92825dd7e53dc9d15c88a19e97932d35d430ef7/rpds_py-0.27.1-cp314-cp314t-win32.whl", hash = "sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a", size = 217385, upload-time = "2025-08-27T12:15:01.937Z" },
- { url = "https://files.pythonhosted.org/packages/32/7d/97119da51cb1dd3f2f3c0805f155a3aa4a95fa44fe7d78ae15e69edf4f34/rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772", size = 230097, upload-time = "2025-08-27T12:15:03.961Z" },
- { url = "https://files.pythonhosted.org/packages/7f/6c/252e83e1ce7583c81f26d1d884b2074d40a13977e1b6c9c50bbf9a7f1f5a/rpds_py-0.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c918c65ec2e42c2a78d19f18c553d77319119bf43aa9e2edf7fb78d624355527", size = 372140, upload-time = "2025-08-27T12:15:05.441Z" },
- { url = "https://files.pythonhosted.org/packages/9d/71/949c195d927c5aeb0d0629d329a20de43a64c423a6aa53836290609ef7ec/rpds_py-0.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1fea2b1a922c47c51fd07d656324531adc787e415c8b116530a1d29c0516c62d", size = 354086, upload-time = "2025-08-27T12:15:07.404Z" },
- { url = "https://files.pythonhosted.org/packages/9f/02/e43e332ad8ce4f6c4342d151a471a7f2900ed1d76901da62eb3762663a71/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbf94c58e8e0cd6b6f38d8de67acae41b3a515c26169366ab58bdca4a6883bb8", size = 382117, upload-time = "2025-08-27T12:15:09.275Z" },
- { url = "https://files.pythonhosted.org/packages/d0/05/b0fdeb5b577197ad72812bbdfb72f9a08fa1e64539cc3940b1b781cd3596/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2a8fed130ce946d5c585eddc7c8eeef0051f58ac80a8ee43bd17835c144c2cc", size = 394520, upload-time = "2025-08-27T12:15:10.727Z" },
- { url = "https://files.pythonhosted.org/packages/67/1f/4cfef98b2349a7585181e99294fa2a13f0af06902048a5d70f431a66d0b9/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:037a2361db72ee98d829bc2c5b7cc55598ae0a5e0ec1823a56ea99374cfd73c1", size = 522657, upload-time = "2025-08-27T12:15:12.613Z" },
- { url = "https://files.pythonhosted.org/packages/44/55/ccf37ddc4c6dce7437b335088b5ca18da864b334890e2fe9aa6ddc3f79a9/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5281ed1cc1d49882f9997981c88df1a22e140ab41df19071222f7e5fc4e72125", size = 402967, upload-time = "2025-08-27T12:15:14.113Z" },
- { url = "https://files.pythonhosted.org/packages/74/e5/5903f92e41e293b07707d5bf00ef39a0eb2af7190aff4beaf581a6591510/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fd50659a069c15eef8aa3d64bbef0d69fd27bb4a50c9ab4f17f83a16cbf8905", size = 384372, upload-time = "2025-08-27T12:15:15.842Z" },
- { url = "https://files.pythonhosted.org/packages/8f/e3/fbb409e18aeefc01e49f5922ac63d2d914328430e295c12183ce56ebf76b/rpds_py-0.27.1-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:c4b676c4ae3921649a15d28ed10025548e9b561ded473aa413af749503c6737e", size = 401264, upload-time = "2025-08-27T12:15:17.388Z" },
- { url = "https://files.pythonhosted.org/packages/55/79/529ad07794e05cb0f38e2f965fc5bb20853d523976719400acecc447ec9d/rpds_py-0.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:079bc583a26db831a985c5257797b2b5d3affb0386e7ff886256762f82113b5e", size = 418691, upload-time = "2025-08-27T12:15:19.144Z" },
- { url = "https://files.pythonhosted.org/packages/33/39/6554a7fd6d9906fda2521c6d52f5d723dca123529fb719a5b5e074c15e01/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4e44099bd522cba71a2c6b97f68e19f40e7d85399de899d66cdb67b32d7cb786", size = 558989, upload-time = "2025-08-27T12:15:21.087Z" },
- { url = "https://files.pythonhosted.org/packages/19/b2/76fa15173b6f9f445e5ef15120871b945fb8dd9044b6b8c7abe87e938416/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e202e6d4188e53c6661af813b46c37ca2c45e497fc558bacc1a7630ec2695aec", size = 589835, upload-time = "2025-08-27T12:15:22.696Z" },
- { url = "https://files.pythonhosted.org/packages/ee/9e/5560a4b39bab780405bed8a88ee85b30178061d189558a86003548dea045/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f41f814b8eaa48768d1bb551591f6ba45f87ac76899453e8ccd41dba1289b04b", size = 555227, upload-time = "2025-08-27T12:15:24.278Z" },
- { url = "https://files.pythonhosted.org/packages/52/d7/cd9c36215111aa65724c132bf709c6f35175973e90b32115dedc4ced09cb/rpds_py-0.27.1-cp39-cp39-win32.whl", hash = "sha256:9e71f5a087ead99563c11fdaceee83ee982fd39cf67601f4fd66cb386336ee52", size = 217899, upload-time = "2025-08-27T12:15:25.926Z" },
- { url = "https://files.pythonhosted.org/packages/5b/e0/d75ab7b4dd8ba777f6b365adbdfc7614bbfe7c5f05703031dfa4b61c3d6c/rpds_py-0.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:71108900c9c3c8590697244b9519017a400d9ba26a36c48381b3f64743a44aab", size = 228725, upload-time = "2025-08-27T12:15:27.398Z" },
- { url = "https://files.pythonhosted.org/packages/d5/63/b7cc415c345625d5e62f694ea356c58fb964861409008118f1245f8c3347/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7ba22cb9693df986033b91ae1d7a979bc399237d45fccf875b76f62bb9e52ddf", size = 371360, upload-time = "2025-08-27T12:15:29.218Z" },
- { url = "https://files.pythonhosted.org/packages/e5/8c/12e1b24b560cf378b8ffbdb9dc73abd529e1adcfcf82727dfd29c4a7b88d/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b640501be9288c77738b5492b3fd3abc4ba95c50c2e41273c8a1459f08298d3", size = 353933, upload-time = "2025-08-27T12:15:30.837Z" },
- { url = "https://files.pythonhosted.org/packages/9b/85/1bb2210c1f7a1b99e91fea486b9f0f894aa5da3a5ec7097cbad7dec6d40f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb08b65b93e0c6dd70aac7f7890a9c0938d5ec71d5cb32d45cf844fb8ae47636", size = 382962, upload-time = "2025-08-27T12:15:32.348Z" },
- { url = "https://files.pythonhosted.org/packages/cc/c9/a839b9f219cf80ed65f27a7f5ddbb2809c1b85c966020ae2dff490e0b18e/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7ff07d696a7a38152ebdb8212ca9e5baab56656749f3d6004b34ab726b550b8", size = 394412, upload-time = "2025-08-27T12:15:33.839Z" },
- { url = "https://files.pythonhosted.org/packages/02/2d/b1d7f928b0b1f4fc2e0133e8051d199b01d7384875adc63b6ddadf3de7e5/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb7c72262deae25366e3b6c0c0ba46007967aea15d1eea746e44ddba8ec58dcc", size = 523972, upload-time = "2025-08-27T12:15:35.377Z" },
- { url = "https://files.pythonhosted.org/packages/a9/af/2cbf56edd2d07716df1aec8a726b3159deb47cb5c27e1e42b71d705a7c2f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b002cab05d6339716b03a4a3a2ce26737f6231d7b523f339fa061d53368c9d8", size = 403273, upload-time = "2025-08-27T12:15:37.051Z" },
- { url = "https://files.pythonhosted.org/packages/c0/93/425e32200158d44ff01da5d9612c3b6711fe69f606f06e3895511f17473b/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23f6b69d1c26c4704fec01311963a41d7de3ee0570a84ebde4d544e5a1859ffc", size = 385278, upload-time = "2025-08-27T12:15:38.571Z" },
- { url = "https://files.pythonhosted.org/packages/eb/1a/1a04a915ecd0551bfa9e77b7672d1937b4b72a0fc204a17deef76001cfb2/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:530064db9146b247351f2a0250b8f00b289accea4596a033e94be2389977de71", size = 402084, upload-time = "2025-08-27T12:15:40.529Z" },
- { url = "https://files.pythonhosted.org/packages/51/f7/66585c0fe5714368b62951d2513b684e5215beaceab2c6629549ddb15036/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b90b0496570bd6b0321724a330d8b545827c4df2034b6ddfc5f5275f55da2ad", size = 419041, upload-time = "2025-08-27T12:15:42.191Z" },
- { url = "https://files.pythonhosted.org/packages/8e/7e/83a508f6b8e219bba2d4af077c35ba0e0cdd35a751a3be6a7cba5a55ad71/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879b0e14a2da6a1102a3fc8af580fc1ead37e6d6692a781bd8c83da37429b5ab", size = 560084, upload-time = "2025-08-27T12:15:43.839Z" },
- { url = "https://files.pythonhosted.org/packages/66/66/bb945683b958a1b19eb0fe715594630d0f36396ebdef4d9b89c2fa09aa56/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:0d807710df3b5faa66c731afa162ea29717ab3be17bdc15f90f2d9f183da4059", size = 590115, upload-time = "2025-08-27T12:15:46.647Z" },
- { url = "https://files.pythonhosted.org/packages/12/00/ccfaafaf7db7e7adace915e5c2f2c2410e16402561801e9c7f96683002d3/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3adc388fc3afb6540aec081fa59e6e0d3908722771aa1e37ffe22b220a436f0b", size = 556561, upload-time = "2025-08-27T12:15:48.219Z" },
- { url = "https://files.pythonhosted.org/packages/e1/b7/92b6ed9aad103bfe1c45df98453dfae40969eef2cb6c6239c58d7e96f1b3/rpds_py-0.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c796c0c1cc68cb08b0284db4229f5af76168172670c74908fdbd4b7d7f515819", size = 229125, upload-time = "2025-08-27T12:15:49.956Z" },
- { url = "https://files.pythonhosted.org/packages/0c/ed/e1fba02de17f4f76318b834425257c8ea297e415e12c68b4361f63e8ae92/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df", size = 371402, upload-time = "2025-08-27T12:15:51.561Z" },
- { url = "https://files.pythonhosted.org/packages/af/7c/e16b959b316048b55585a697e94add55a4ae0d984434d279ea83442e460d/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3", size = 354084, upload-time = "2025-08-27T12:15:53.219Z" },
- { url = "https://files.pythonhosted.org/packages/de/c1/ade645f55de76799fdd08682d51ae6724cb46f318573f18be49b1e040428/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9", size = 383090, upload-time = "2025-08-27T12:15:55.158Z" },
- { url = "https://files.pythonhosted.org/packages/1f/27/89070ca9b856e52960da1472efcb6c20ba27cfe902f4f23ed095b9cfc61d/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc", size = 394519, upload-time = "2025-08-27T12:15:57.238Z" },
- { url = "https://files.pythonhosted.org/packages/b3/28/be120586874ef906aa5aeeae95ae8df4184bc757e5b6bd1c729ccff45ed5/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4", size = 523817, upload-time = "2025-08-27T12:15:59.237Z" },
- { url = "https://files.pythonhosted.org/packages/a8/ef/70cc197bc11cfcde02a86f36ac1eed15c56667c2ebddbdb76a47e90306da/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66", size = 403240, upload-time = "2025-08-27T12:16:00.923Z" },
- { url = "https://files.pythonhosted.org/packages/cf/35/46936cca449f7f518f2f4996e0e8344db4b57e2081e752441154089d2a5f/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e", size = 385194, upload-time = "2025-08-27T12:16:02.802Z" },
- { url = "https://files.pythonhosted.org/packages/e1/62/29c0d3e5125c3270b51415af7cbff1ec587379c84f55a5761cc9efa8cd06/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c", size = 402086, upload-time = "2025-08-27T12:16:04.806Z" },
- { url = "https://files.pythonhosted.org/packages/8f/66/03e1087679227785474466fdd04157fb793b3b76e3fcf01cbf4c693c1949/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf", size = 419272, upload-time = "2025-08-27T12:16:06.471Z" },
- { url = "https://files.pythonhosted.org/packages/6a/24/e3e72d265121e00b063aef3e3501e5b2473cf1b23511d56e529531acf01e/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf", size = 560003, upload-time = "2025-08-27T12:16:08.06Z" },
- { url = "https://files.pythonhosted.org/packages/26/ca/f5a344c534214cc2d41118c0699fffbdc2c1bc7046f2a2b9609765ab9c92/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6", size = 590482, upload-time = "2025-08-27T12:16:10.137Z" },
- { url = "https://files.pythonhosted.org/packages/ce/08/4349bdd5c64d9d193c360aa9db89adeee6f6682ab8825dca0a3f535f434f/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a", size = 556523, upload-time = "2025-08-27T12:16:12.188Z" },
- { url = "https://files.pythonhosted.org/packages/4e/ea/5463cd5048a7a2fcdae308b6e96432802132c141bfb9420260142632a0f1/rpds_py-0.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa8933159edc50be265ed22b401125c9eebff3171f570258854dbce3ecd55475", size = 371778, upload-time = "2025-08-27T12:16:13.851Z" },
- { url = "https://files.pythonhosted.org/packages/0d/c8/f38c099db07f5114029c1467649d308543906933eebbc226d4527a5f4693/rpds_py-0.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a50431bf02583e21bf273c71b89d710e7a710ad5e39c725b14e685610555926f", size = 354394, upload-time = "2025-08-27T12:16:15.609Z" },
- { url = "https://files.pythonhosted.org/packages/7d/79/b76f97704d9dd8ddbd76fed4c4048153a847c5d6003afe20a6b5c3339065/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78af06ddc7fe5cc0e967085a9115accee665fb912c22a3f54bad70cc65b05fe6", size = 382348, upload-time = "2025-08-27T12:16:17.251Z" },
- { url = "https://files.pythonhosted.org/packages/8a/3f/ef23d3c1be1b837b648a3016d5bbe7cfe711422ad110b4081c0a90ef5a53/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70d0738ef8fee13c003b100c2fbd667ec4f133468109b3472d249231108283a3", size = 394159, upload-time = "2025-08-27T12:16:19.251Z" },
- { url = "https://files.pythonhosted.org/packages/74/8a/9e62693af1a34fd28b1a190d463d12407bd7cf561748cb4745845d9548d3/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2f6fd8a1cea5bbe599b6e78a6e5ee08db434fc8ffea51ff201c8765679698b3", size = 522775, upload-time = "2025-08-27T12:16:20.929Z" },
- { url = "https://files.pythonhosted.org/packages/36/0d/8d5bb122bf7a60976b54c5c99a739a3819f49f02d69df3ea2ca2aff47d5c/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8177002868d1426305bb5de1e138161c2ec9eb2d939be38291d7c431c4712df8", size = 402633, upload-time = "2025-08-27T12:16:22.548Z" },
- { url = "https://files.pythonhosted.org/packages/0f/0e/237948c1f425e23e0cf5a566d702652a6e55c6f8fbd332a1792eb7043daf/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:008b839781d6c9bf3b6a8984d1d8e56f0ec46dc56df61fd669c49b58ae800400", size = 384867, upload-time = "2025-08-27T12:16:24.29Z" },
- { url = "https://files.pythonhosted.org/packages/d6/0a/da0813efcd998d260cbe876d97f55b0f469ada8ba9cbc47490a132554540/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:a55b9132bb1ade6c734ddd2759c8dc132aa63687d259e725221f106b83a0e485", size = 401791, upload-time = "2025-08-27T12:16:25.954Z" },
- { url = "https://files.pythonhosted.org/packages/51/78/c6c9e8a8aaca416a6f0d1b6b4a6ee35b88fe2c5401d02235d0a056eceed2/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a46fdec0083a26415f11d5f236b79fa1291c32aaa4a17684d82f7017a1f818b1", size = 419525, upload-time = "2025-08-27T12:16:27.659Z" },
- { url = "https://files.pythonhosted.org/packages/a3/69/5af37e1d71487cf6d56dd1420dc7e0c2732c1b6ff612aa7a88374061c0a8/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8a63b640a7845f2bdd232eb0d0a4a2dd939bcdd6c57e6bb134526487f3160ec5", size = 559255, upload-time = "2025-08-27T12:16:29.343Z" },
- { url = "https://files.pythonhosted.org/packages/40/7f/8b7b136069ef7ac3960eda25d832639bdb163018a34c960ed042dd1707c8/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7e32721e5d4922deaaf963469d795d5bde6093207c52fec719bd22e5d1bedbc4", size = 590384, upload-time = "2025-08-27T12:16:31.005Z" },
- { url = "https://files.pythonhosted.org/packages/d8/06/c316d3f6ff03f43ccb0eba7de61376f8ec4ea850067dddfafe98274ae13c/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2c426b99a068601b5f4623573df7a7c3d72e87533a2dd2253353a03e7502566c", size = 555959, upload-time = "2025-08-27T12:16:32.73Z" },
- { url = "https://files.pythonhosted.org/packages/60/94/384cf54c430b9dac742bbd2ec26c23feb78ded0d43d6d78563a281aec017/rpds_py-0.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4fc9b7fe29478824361ead6e14e4f5aed570d477e06088826537e202d25fe859", size = 228784, upload-time = "2025-08-27T12:16:34.428Z" },
-]
-
[[package]]
name = "rpds-py"
version = "0.30.0"
source = { registry = "https://pypi.org/simple" }
-resolution-markers = [
- "python_full_version >= '3.10'",
-]
sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" },
@@ -1693,12 +1291,3 @@ sdist = { url = "https://files.pythonhosted.org/packages/dd/b2/381be8cfdee792dd1
wheels = [
{ url = "https://files.pythonhosted.org/packages/93/8c/2e650f2afeb7ee576912636c23ddb621c91ac6a98e66dc8d29c3c69446e1/werkzeug-3.1.8-py3-none-any.whl", hash = "sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50", size = 226459, upload-time = "2026-04-02T18:49:12.72Z" },
]
-
-[[package]]
-name = "zipp"
-version = "3.23.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" },
-]
From f13c30452e60378c3af07d52e8a875cc56182070 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Thu, 23 Apr 2026 00:17:58 +0200
Subject: [PATCH 02/56] CI: add cargo updates to dependabot
---
.github/dependabot.yml | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 6867e71..083ac61 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -9,3 +9,29 @@ updates:
directory: "/"
schedule:
interval: "weekly"
+ - package-ecosystem: "cargo"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ day: "monday"
+ time: "06:00"
+ timezone: "UTC"
+
+ groups:
+ all-dependencies:
+ patterns:
+ - "*"
+
+ cooldown:
+ default-days: 7
+
+ open-pull-requests-limit: 1
+
+ versioning-strategy: "auto"
+
+ labels:
+ - "dependencies"
+ - "rust"
+
+ allow:
+ - dependency-type: "all"
From 3caf173a8667636a6f1903ec349b7075001983c3 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Thu, 23 Apr 2026 00:20:12 +0200
Subject: [PATCH 03/56] CI: update to CLN v26.04
---
.../{latest_v25.02.yml => latest_v26.04.yml} | 8 +++----
.../{master_v25.02.yml => master_v26.04.yml} | 6 ++---
README.md | 24 +++++++++----------
3 files changed, 19 insertions(+), 19 deletions(-)
rename .github/workflows/{latest_v25.02.yml => latest_v26.04.yml} (51%)
rename .github/workflows/{master_v25.02.yml => master_v26.04.yml} (80%)
diff --git a/.github/workflows/latest_v25.02.yml b/.github/workflows/latest_v26.04.yml
similarity index 51%
rename from .github/workflows/latest_v25.02.yml
rename to .github/workflows/latest_v26.04.yml
index 6d8590c..f545ca4 100644
--- a/.github/workflows/latest_v25.02.yml
+++ b/.github/workflows/latest_v26.04.yml
@@ -1,4 +1,4 @@
-name: Latest release on CLN v25.02.x
+name: Latest release on CLN v26.04.x
on:
release:
@@ -9,6 +9,6 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.02.1"
- pyln-version: "25.2.1"
- tagged-release: true
\ No newline at end of file
+ cln-version: "v26.04"
+ pyln-version: "26.4"
+ tagged-release: true
diff --git a/.github/workflows/master_v25.02.yml b/.github/workflows/master_v26.04.yml
similarity index 80%
rename from .github/workflows/master_v25.02.yml
rename to .github/workflows/master_v26.04.yml
index e7b060f..5fcd616 100644
--- a/.github/workflows/master_v25.02.yml
+++ b/.github/workflows/master_v26.04.yml
@@ -1,4 +1,4 @@
-name: master on CLN v25.02.x
+name: master on CLN v26.04.x
on:
push:
@@ -19,6 +19,6 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.02.1"
- pyln-version: "25.2.1"
+ cln-version: "v26.04"
+ pyln-version: "26.4"
tagged-release: false
diff --git a/README.md b/README.md
index 8d8c56b..6d78898 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,4 @@
From 80926ba9b7d7cb9f5955a6e97c359822b4880fee Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Thu, 23 Apr 2026 00:20:49 +0200
Subject: [PATCH 04/56] CI: update to min python 3.10 and bitcoind 31.0
---
.github/workflows/ci.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 44922b0..5275ba9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,10 +24,10 @@ jobs:
strategy:
fail-fast: false
matrix:
- bitcoind-version: ["30.2"]
+ bitcoind-version: ["31.0"]
experimental: [1]
deprecated: [0]
- python-version: ["3.9", "3.14"]
+ python-version: ["3.10", "3.14"]
os: ["ubuntu-latest"]
runs-on: ${{ matrix.os }}
From f26b82bb518a45c95d83ac7654c3b53f6b69bb2e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 22 Apr 2026 21:34:24 +0000
Subject: [PATCH 05/56] Bump the cargo group across 1 directory with 2 updates
Bumps the cargo group with 2 updates in the / directory: [rand](https://github.com/rust-random/rand) and [rustls-webpki](https://github.com/rustls/webpki).
Updates `rand` from 0.8.5 to 0.8.6
- [Release notes](https://github.com/rust-random/rand/releases)
- [Changelog](https://github.com/rust-random/rand/blob/0.8.6/CHANGELOG.md)
- [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.8.6)
Updates `rustls-webpki` from 0.103.10 to 0.103.13
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.10...v/0.103.13)
---
updated-dependencies:
- dependency-name: rand
dependency-version: 0.8.6
dependency-type: indirect
dependency-group: cargo
- dependency-name: rustls-webpki
dependency-version: 0.103.13
dependency-type: indirect
dependency-group: cargo
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 3da29df..914b225 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1094,9 +1094,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
dependencies = [
"libc",
"rand_chacha 0.3.1",
@@ -1228,9 +1228,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
-version = "0.103.10"
+version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
+checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
dependencies = [
"ring",
"rustls-pki-types",
@@ -1277,7 +1277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113"
dependencies = [
"bitcoin_hashes",
- "rand 0.8.5",
+ "rand 0.8.6",
"secp256k1-sys",
"serde",
]
From aff911ed90f3c602747c2b77e68039fce7c77990 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 23 Apr 2026 07:16:28 +0000
Subject: [PATCH 06/56] Bump the all-dependencies group with 10 updates
Bumps the all-dependencies group with 10 updates:
| Package | From | To |
| --- | --- | --- |
| [tokio](https://github.com/tokio-rs/tokio) | `1.50.0` | `1.52.0` |
| [uuid](https://github.com/uuid-rs/uuid) | `1.23.0` | `1.23.1` |
| [bitflags](https://github.com/bitflags/bitflags) | `2.11.0` | `2.11.1` |
| [cc](https://github.com/rust-lang/cc-rs) | `1.2.58` | `1.2.60` |
| [indexmap](https://github.com/indexmap-rs/indexmap) | `2.13.1` | `2.14.0` |
| [libc](https://github.com/rust-lang/libc) | `0.2.184` | `0.2.185` |
| [lru](https://github.com/jeromefroe/lru-rs) | `0.16.3` | `0.16.4` |
| [rustls](https://github.com/rustls/rustls) | `0.23.37` | `0.23.38` |
| [semver](https://github.com/dtolnay/semver) | `1.0.27` | `1.0.28` |
| [tokio-macros](https://github.com/tokio-rs/tokio) | `2.6.1` | `2.7.0` |
Updates `tokio` from 1.50.0 to 1.52.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.50.0...tokio-1.52.0)
Updates `uuid` from 1.23.0 to 1.23.1
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.23.0...v1.23.1)
Updates `bitflags` from 2.11.0 to 2.11.1
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.11.0...2.11.1)
Updates `cc` from 1.2.58 to 1.2.60
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.58...cc-v1.2.60)
Updates `indexmap` from 2.13.1 to 2.14.0
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.13.1...2.14.0)
Updates `libc` from 0.2.184 to 0.2.185
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.185/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.184...0.2.185)
Updates `lru` from 0.16.3 to 0.16.4
- [Changelog](https://github.com/jeromefroe/lru-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jeromefroe/lru-rs/compare/0.16.3...0.16.4)
Updates `rustls` from 0.23.37 to 0.23.38
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.37...v/0.23.38)
Updates `semver` from 1.0.27 to 1.0.28
- [Release notes](https://github.com/dtolnay/semver/releases)
- [Commits](https://github.com/dtolnay/semver/compare/1.0.27...1.0.28)
Updates `tokio-macros` from 2.6.1 to 2.7.0
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-macros-2.6.1...tokio-macros-2.7.0)
---
updated-dependencies:
- dependency-name: tokio
dependency-version: 1.52.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: all-dependencies
- dependency-name: uuid
dependency-version: 1.23.1
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: bitflags
dependency-version: 2.11.1
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: cc
dependency-version: 1.2.60
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: indexmap
dependency-version: 2.14.0
dependency-type: indirect
update-type: version-update:semver-minor
dependency-group: all-dependencies
- dependency-name: libc
dependency-version: 0.2.185
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: lru
dependency-version: 0.16.4
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: rustls
dependency-version: 0.23.38
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: semver
dependency-version: 1.0.28
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: tokio-macros
dependency-version: 2.7.0
dependency-type: indirect
update-type: version-update:semver-minor
dependency-group: all-dependencies
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 46 +++++++++++++++++++++++-----------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 914b225..88dc220 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -176,9 +176,9 @@ dependencies = [
[[package]]
name = "bitflags"
-version = "2.11.0"
+version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
+checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
[[package]]
name = "block-buffer"
@@ -221,9 +221,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.58"
+version = "1.2.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
+checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -566,9 +566,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.16.1"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
[[package]]
name = "heck"
@@ -732,12 +732,12 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.13.1"
+version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff"
+checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
- "hashbrown 0.16.1",
+ "hashbrown 0.17.0",
"serde",
"serde_core",
]
@@ -796,9 +796,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
-version = "0.2.184"
+version = "0.2.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
+checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
[[package]]
name = "litemap"
@@ -832,9 +832,9 @@ dependencies = [
[[package]]
name = "lru"
-version = "0.16.3"
+version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
+checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
[[package]]
name = "matchers"
@@ -1205,9 +1205,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.37"
+version = "0.23.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
+checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e"
dependencies = [
"once_cell",
"ring",
@@ -1293,9 +1293,9 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.27"
+version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
+checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
[[package]]
name = "serde"
@@ -1509,9 +1509,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.50.0"
+version = "1.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
+checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776"
dependencies = [
"bytes",
"libc",
@@ -1524,9 +1524,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.6.1"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
+checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
@@ -1746,9 +1746,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
-version = "1.23.0"
+version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9"
+checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
dependencies = [
"getrandom 0.4.2",
"js-sys",
From ce0e1fe5853103f48a1e4ae02b40a0e2a5a9623a Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Thu, 23 Apr 2026 09:31:54 +0200
Subject: [PATCH 07/56] Cargo.lock: update tokio to v1.52.1
---
Cargo.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 88dc220..9a88dd3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1509,9 +1509,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.52.0"
+version = "1.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a91135f59b1cbf38c91e73cf3386fca9bb77915c45ce2771460c9d92f0f3d776"
+checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
dependencies = [
"bytes",
"libc",
From 7ec1e68d6cd293dcc7b08d130ccbc755314e4482 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Thu, 23 Apr 2026 11:00:51 +0200
Subject: [PATCH 08/56] fix budget race condition
---
CHANGELOG.md | 5 +++++
Cargo.lock | 2 +-
Cargo.toml | 2 +-
coffee.yml | 2 +-
src/rpc.rs | 8 ++++----
5 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2cb0208..6eb4680 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## [0.1.9] 2026-04-23
+
+### Fixed
+- ``nip47-budget``: race condition where new budget settings would sometimes be ignored
+
## [0.1.8] 2026-04-03
### Changed
diff --git a/Cargo.lock b/Cargo.lock
index 9a88dd3..99c47f9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -272,7 +272,7 @@ dependencies = [
[[package]]
name = "cln-nip47"
-version = "0.1.8"
+version = "0.1.9"
dependencies = [
"anyhow",
"cln-plugin",
diff --git a/Cargo.toml b/Cargo.toml
index f846dd5..554256b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cln-nip47"
-version = "0.1.8"
+version = "0.1.9"
edition = "2024"
rust-version = "1.85.0"
diff --git a/coffee.yml b/coffee.yml
index 9c7d20d..980549a 100644
--- a/coffee.yml
+++ b/coffee.yml
@@ -1,6 +1,6 @@
plugin:
name: cln-nip47
- version: 0.1.8
+ version: 0.1.9
lang: rust
install: |
cargo build --release && cp target/release/cln-nip47 . && cargo clean
diff --git a/src/rpc.rs b/src/rpc.rs
index bbc12db..272d483 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -6,15 +6,15 @@ use cln_rpc::model::requests::{
DeldatastoreRequest,
ListdatastoreRequest,
};
-use nostr_sdk::{nips::nip47::NostrWalletConnectURI, Keys, SecretKey, Timestamp};
+use nostr_sdk::{Keys, SecretKey, Timestamp, nips::nip47::NostrWalletConnectURI};
use serde_json::json;
use crate::{
+ PLUGIN_NAME,
nwc::{run_nwc, send_nwc_info_event, start_nwc_budget_job, stop_nwc, stop_nwc_budget_job},
parse::parse_time_period,
structs::{BudgetIntervalConfig, NwcStore, PluginState},
util::{build_capabilities, is_read_only_nwc, load_nwc_store, update_nwc_store},
- PLUGIN_NAME,
};
pub async fn nwc_create(
@@ -140,12 +140,12 @@ pub async fn nwc_budget(
let is_new_nwc_read_only = is_read_only_nwc(&nwc_store);
+ update_nwc_store(&mut rpc, &label, nwc_store.clone()).await?;
+
if nwc_store.interval_config.is_some() {
start_nwc_budget_job(&plugin, label.clone());
}
- update_nwc_store(&mut rpc, &label, nwc_store.clone()).await?;
-
if is_old_nwc_read_only != is_new_nwc_read_only {
let wallet_keys = Keys::new(SecretKey::from_hex(&nwc_store.walletkey)?);
let (method_capabilities, _) = build_capabilities(is_new_nwc_read_only, &plugin);
From 07159082d80bfb6ed89cbc7f4dcce4a0db23be59 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 27 Apr 2026 06:46:14 +0000
Subject: [PATCH 09/56] Bump the all-dependencies group with 2 updates
Bumps the all-dependencies group with 2 updates: [bitcoin-units](https://github.com/rust-bitcoin/rust-bitcoin) and [typenum](https://github.com/paholg/typenum).
Updates `bitcoin-units` from 0.1.2 to 0.1.3
- [Release notes](https://github.com/rust-bitcoin/rust-bitcoin/releases)
- [Changelog](https://github.com/rust-bitcoin/rust-bitcoin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-bitcoin/rust-bitcoin/compare/io-0.1.2...bitcoin-units-0.1.3)
Updates `typenum` from 1.19.0 to 1.20.0
- [Release notes](https://github.com/paholg/typenum/releases)
- [Changelog](https://github.com/paholg/typenum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/paholg/typenum/compare/v1.19.0...v1.20.0)
---
updated-dependencies:
- dependency-name: bitcoin-units
dependency-version: 0.1.3
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: typenum
dependency-version: 1.20.0
dependency-type: indirect
update-type: version-update:semver-minor
dependency-group: all-dependencies
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 99c47f9..37c8388 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -155,9 +155,9 @@ checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953"
[[package]]
name = "bitcoin-units"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2"
+checksum = "346568ebaab2918487cea76dd55dae13c27bb618cdb737c952e69eb2017c4118"
dependencies = [
"bitcoin-internals",
"serde",
@@ -1678,9 +1678,9 @@ dependencies = [
[[package]]
name = "typenum"
-version = "1.19.0"
+version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
+checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]]
name = "unicode-ident"
From 0c2a2a15fb2d260b980352f438f6901cd1e3ec53 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 4 May 2026 06:56:06 +0000
Subject: [PATCH 10/56] Bump the all-dependencies group with 4 updates
Bumps the all-dependencies group with 4 updates: [cc](https://github.com/rust-lang/cc-rs), [data-encoding](https://github.com/ia0/data-encoding), [libc](https://github.com/rust-lang/libc) and [rustls-pki-types](https://github.com/rustls/pki-types).
Updates `cc` from 1.2.60 to 1.2.61
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.60...cc-v1.2.61)
Updates `data-encoding` from 2.10.0 to 2.11.0
- [Commits](https://github.com/ia0/data-encoding/compare/v2.10.0...v2.11.0)
Updates `libc` from 0.2.185 to 0.2.186
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.186/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.185...0.2.186)
Updates `rustls-pki-types` from 1.14.0 to 1.14.1
- [Release notes](https://github.com/rustls/pki-types/releases)
- [Commits](https://github.com/rustls/pki-types/compare/v/1.14.0...v/1.14.1)
---
updated-dependencies:
- dependency-name: cc
dependency-version: 1.2.61
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: data-encoding
dependency-version: 2.11.0
dependency-type: indirect
update-type: version-update:semver-minor
dependency-group: all-dependencies
- dependency-name: libc
dependency-version: 0.2.186
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: rustls-pki-types
dependency-version: 1.14.1
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 37c8388..957e671 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -221,9 +221,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.60"
+version = "1.2.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
+checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -348,9 +348,9 @@ dependencies = [
[[package]]
name = "data-encoding"
-version = "2.10.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
+checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
[[package]]
name = "digest"
@@ -796,9 +796,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
-version = "0.2.185"
+version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "litemap"
@@ -1219,9 +1219,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.14.0"
+version = "1.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
+checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
dependencies = [
"zeroize",
]
From a2781bee20933244c6006108ef57ab4e665dbc4c Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 11 May 2026 07:30:53 +0000
Subject: [PATCH 11/56] Bump rustls from 0.23.39 to 0.23.40 in the
all-dependencies group
Bumps the all-dependencies group with 1 update: [rustls](https://github.com/rustls/rustls).
Updates `rustls` from 0.23.39 to 0.23.40
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rustls/rustls/compare/v/0.23.39...v/0.23.40)
---
updated-dependencies:
- dependency-name: rustls
dependency-version: 0.23.40
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 957e671..00f6ec3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1205,9 +1205,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.39"
+version = "0.23.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e"
+checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
dependencies = [
"once_cell",
"ring",
From 004e403d48f0d428561d8ebb921fe9b7acc05ef7 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 18 May 2026 09:11:09 +0000
Subject: [PATCH 12/56] Bump the all-dependencies group with 3 updates
Bumps the all-dependencies group with 3 updates: [tokio](https://github.com/tokio-rs/tokio), [bitcoin](https://github.com/rust-bitcoin/rust-bitcoin) and [cc](https://github.com/rust-lang/cc-rs).
Updates `tokio` from 1.52.1 to 1.52.3
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.52.1...tokio-1.52.3)
Updates `bitcoin` from 0.32.8 to 0.32.9
- [Release notes](https://github.com/rust-bitcoin/rust-bitcoin/releases)
- [Changelog](https://github.com/rust-bitcoin/rust-bitcoin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-bitcoin/rust-bitcoin/compare/bitcoin-0.32.8...bitcoin-0.32.9)
Updates `cc` from 1.2.61 to 1.2.62
- [Release notes](https://github.com/rust-lang/cc-rs/releases)
- [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.61...cc-v1.2.62)
---
updated-dependencies:
- dependency-name: tokio
dependency-version: 1.52.3
dependency-type: direct:production
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: bitcoin
dependency-version: 0.32.9
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
- dependency-name: cc
dependency-version: 1.2.62
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 00f6ec3..5c81662 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -122,9 +122,9 @@ dependencies = [
[[package]]
name = "bitcoin"
-version = "0.32.8"
+version = "0.32.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e499f9fc0407f50fe98af744ab44fa67d409f76b6772e1689ec8485eb0c0f66"
+checksum = "9cf93e61f2dbc3e3c41234ca26a65e2c0b0975c52e0f069ab9893ebbede584d3"
dependencies = [
"base58ck",
"bech32",
@@ -221,9 +221,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.61"
+version = "1.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
+checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -1509,9 +1509,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.52.1"
+version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
+checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes",
"libc",
From 140d295eeca2a85e394f635f2a1745e57d54b65e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 25 May 2026 08:37:45 +0000
Subject: [PATCH 13/56] Bump zerofrom from 0.1.7 to 0.1.8 in the
all-dependencies group
Bumps the all-dependencies group with 1 update: [zerofrom](https://github.com/unicode-org/icu4x).
Updates `zerofrom` from 0.1.7 to 0.1.8
- [Release notes](https://github.com/unicode-org/icu4x/releases)
- [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unicode-org/icu4x/commits)
---
updated-dependencies:
- dependency-name: zerofrom
dependency-version: 0.1.8
dependency-type: indirect
update-type: version-update:semver-patch
dependency-group: all-dependencies
...
Signed-off-by: dependabot[bot]
---
Cargo.lock | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 5c81662..4943b81 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2141,9 +2141,9 @@ dependencies = [
[[package]]
name = "zerofrom"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
+checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
dependencies = [
"zerofrom-derive",
]
From c956338bcd9ed7d9786c0ec40d757ccbb1145b16 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Sat, 8 Nov 2025 13:41:11 +0100
Subject: [PATCH 14/56] add support for holdinvoices
---
CHANGELOG.md | 6 +
Cargo.lock | 476 +++++++++++++++++++++++++++++++--
Cargo.toml | 11 +
README.md | 7 +
build.rs | 6 +
protos/hold.proto | 185 +++++++++++++
src/main.rs | 124 ++++++++-
src/nwc.rs | 36 +--
src/nwc_hold.rs | 274 +++++++++++++++----
src/nwc_lookups.rs | 369 +++++++++++++++++++++++---
src/nwc_notifications.rs | 129 ++++++++-
src/structs.rs | 5 +
src/util.rs | 33 ++-
tests/config.toml | 2 +-
tests/setup.sh | 14 +
tests/test_cln-nip47.py | 557 ++++++++++++++++++++++++++++++++++++++-
tests/util.py | 23 +-
tests/uv.lock | 142 +++++-----
18 files changed, 2192 insertions(+), 207 deletions(-)
create mode 100644 build.rs
create mode 100644 protos/hold.proto
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6eb4680..91f2c5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## Unreleased
+
+### Added
+- holdinvoice methods: ``make_hold_invoice``, ``cancel_hold_invoice``, ``settle_hold_invoice``
+- holdinvoice notification: ``hold_invoice_accepted``
+
## [0.1.9] 2026-04-23
### Fixed
diff --git a/Cargo.lock b/Cargo.lock
index 4943b81..55e0cde 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -44,6 +44,17 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+[[package]]
+name = "async-trait"
+version = "0.1.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "async-utility"
version = "0.3.1"
@@ -81,6 +92,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4"
+[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
[[package]]
name = "base58ck"
version = "0.1.0"
@@ -282,10 +299,14 @@ dependencies = [
"log-panics",
"nostr-sdk",
"parking_lot",
+ "prost",
"regex",
"serde",
"serde_json",
"tokio",
+ "tonic",
+ "tonic-prost",
+ "tonic-prost-build",
"uuid",
]
@@ -386,12 +407,40 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
+
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+[[package]]
+name = "fixedbitset"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
[[package]]
name = "foldhash"
version = "0.1.5"
@@ -555,6 +604,25 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "h2"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
[[package]]
name = "hashbrown"
version = "0.15.5"
@@ -566,9 +634,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.17.0"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "heck"
@@ -616,12 +684,96 @@ dependencies = [
"itoa",
]
+[[package]]
+name = "http-body"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "pin-project-lite",
+]
+
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
+ "tokio",
+ "want",
+]
+
+[[package]]
+name = "hyper-timeout"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
+dependencies = [
+ "hyper",
+ "hyper-util",
+ "pin-project-lite",
+ "tokio",
+ "tower-service",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "libc",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+]
+
[[package]]
name = "icu_collections"
version = "2.1.1"
@@ -737,7 +889,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
- "hashbrown 0.17.0",
+ "hashbrown 0.17.1",
"serde",
"serde_core",
]
@@ -764,6 +916,15 @@ dependencies = [
"web-sys",
]
+[[package]]
+name = "itertools"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "itoa"
version = "1.0.18"
@@ -772,9 +933,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
-version = "0.3.94"
+version = "0.3.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
+checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
dependencies = [
"cfg-if",
"futures-util",
@@ -800,6 +961,12 @@ version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+[[package]]
+name = "linux-raw-sys"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+
[[package]]
name = "litemap"
version = "0.8.2"
@@ -862,6 +1029,12 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "multimap"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
+
[[package]]
name = "negentropy"
version = "0.5.0"
@@ -1017,6 +1190,37 @@ version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
+[[package]]
+name = "petgraph"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
+dependencies = [
+ "fixedbitset",
+ "hashbrown 0.15.5",
+ "indexmap",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "pin-project-lite"
version = "0.2.17"
@@ -1071,6 +1275,79 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "prost"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
+dependencies = [
+ "bytes",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
+dependencies = [
+ "heck",
+ "itertools",
+ "log",
+ "multimap",
+ "petgraph",
+ "prettyplease",
+ "prost",
+ "prost-types",
+ "pulldown-cmark",
+ "pulldown-cmark-to-cmark",
+ "regex",
+ "syn",
+ "tempfile",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
+dependencies = [
+ "anyhow",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
+dependencies = [
+ "prost",
+]
+
+[[package]]
+name = "pulldown-cmark"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad"
+dependencies = [
+ "bitflags",
+ "memchr",
+ "unicase",
+]
+
+[[package]]
+name = "pulldown-cmark-to-cmark"
+version = "22.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90"
+dependencies = [
+ "pulldown-cmark",
+]
+
[[package]]
name = "quote"
version = "1.0.45"
@@ -1105,9 +1382,9 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.9.2"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
+checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.5",
@@ -1203,12 +1480,26 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "rustix"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.61.2",
+]
+
[[package]]
name = "rustls"
version = "0.23.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
dependencies = [
+ "log",
"once_cell",
"ring",
"rustls-pki-types",
@@ -1422,6 +1713,12 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "sync_wrapper"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
+
[[package]]
name = "synstructure"
version = "0.13.2"
@@ -1433,6 +1730,19 @@ dependencies = [
"syn",
]
+[[package]]
+name = "tempfile"
+version = "3.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
+dependencies = [
+ "fastrand",
+ "getrandom 0.4.2",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.61.2",
+]
+
[[package]]
name = "thiserror"
version = "1.0.69"
@@ -1595,6 +1905,105 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "tonic"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec"
+dependencies = [
+ "async-trait",
+ "base64",
+ "bytes",
+ "h2",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-timeout",
+ "hyper-util",
+ "percent-encoding",
+ "pin-project",
+ "socket2",
+ "sync_wrapper",
+ "tokio",
+ "tokio-rustls",
+ "tokio-stream",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tonic-build"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734"
+dependencies = [
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tonic-prost"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309"
+dependencies = [
+ "bytes",
+ "prost",
+ "tonic",
+]
+
+[[package]]
+name = "tonic-prost-build"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a"
+dependencies = [
+ "prettyplease",
+ "proc-macro2",
+ "prost-build",
+ "prost-types",
+ "quote",
+ "syn",
+ "tempfile",
+ "tonic-build",
+]
+
+[[package]]
+name = "tower"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project-lite",
+ "slab",
+ "sync_wrapper",
+ "tokio",
+ "tokio-util",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
+
+[[package]]
+name = "tower-service"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
+
[[package]]
name = "tracing"
version = "0.1.44"
@@ -1657,6 +2066,12 @@ dependencies = [
"tracing-log",
]
+[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
[[package]]
name = "tungstenite"
version = "0.26.2"
@@ -1668,7 +2083,7 @@ dependencies = [
"http",
"httparse",
"log",
- "rand 0.9.2",
+ "rand 0.9.4",
"rustls",
"rustls-pki-types",
"sha1",
@@ -1682,6 +2097,12 @@ version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
+[[package]]
+name = "unicase"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
+
[[package]]
name = "unicode-ident"
version = "1.0.24"
@@ -1767,6 +2188,15 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
@@ -1793,9 +2223,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen"
-version = "0.2.117"
+version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
+checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790"
dependencies = [
"cfg-if",
"once_cell",
@@ -1806,9 +2236,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.67"
+version = "0.4.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e"
+checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -1816,9 +2246,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.117"
+version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
+checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -1826,9 +2256,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.117"
+version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
+checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2"
dependencies = [
"bumpalo",
"proc-macro2",
@@ -1839,9 +2269,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.117"
+version = "0.2.121"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
+checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441"
dependencies = [
"unicode-ident",
]
@@ -1882,9 +2312,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.94"
+version = "0.3.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a"
+checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -1896,14 +2326,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
- "webpki-roots 1.0.6",
+ "webpki-roots 1.0.7",
]
[[package]]
name = "webpki-roots"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
+checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d"
dependencies = [
"rustls-pki-types",
]
diff --git a/Cargo.toml b/Cargo.toml
index 554256b..c5b1a1c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,17 @@ hex = "0.4"
regex = "1"
+tonic = { version = "0.14", default-features = false, features = [
+ "codegen",
+ "transport",
+ "tls-ring",
+] }
+prost = "0.14"
+tonic-prost = "0.14"
+
+[build-dependencies]
+tonic-prost-build = "0.14"
+
[profile.optimized]
inherits = "release"
diff --git a/README.md b/README.md
index 6d78898..02fbb10 100644
--- a/README.md
+++ b/README.md
@@ -127,6 +127,9 @@ For a private relay you can for example use [nostr-rs-relay](https://github.com/
* list all NWC configurations or just the one with ``label``
* ***label***: optional. The label the NWC was created with
+## Holdinvoice support
+For methods or notifications related to holdinvoices you need v0.3.2+ of [hold](https://github.com/BoltzExchange/hold) with enabled grpc (which is the default just make sure the port is free)
+
## Supported NWC methods
* ``pay_invoice``
* ``multi_pay_invoice``
@@ -137,10 +140,14 @@ For a private relay you can for example use [nostr-rs-relay](https://github.com/
* ``list_transactions``
* ``get_balance``
* ``get_info`` (no ``block_hash``)
+* ``make_hold_invoice`` (requires [Holdinvoice support](#holdinvoice_support))
+* ``cancel_hold_invoice`` (requires [Holdinvoice support](#holdinvoice_support))
+* ``settle_hold_invoice`` (requires [Holdinvoice support](#holdinvoice_support))
## Supported NWC notifications
* ``payment_received``
* ``payment_sent``
+* ``hold_invoice_accepted`` (requires [Holdinvoice support](#holdinvoice_support))
## Supported content encryption:
* [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md)
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..3e87891
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,6 @@
+fn main() {
+ tonic_prost_build::configure()
+ .protoc_arg("--experimental_allow_proto3_optional")
+ .compile_protos(&["protos/hold.proto"], &["protos"])
+ .unwrap_or_else(|e| panic!("Could not build protos: {e}"));
+}
diff --git a/protos/hold.proto b/protos/hold.proto
new file mode 100644
index 0000000..e7ad240
--- /dev/null
+++ b/protos/hold.proto
@@ -0,0 +1,185 @@
+syntax = "proto3";
+
+package hold;
+
+service Hold {
+ rpc GetInfo (GetInfoRequest) returns (GetInfoResponse);
+
+ rpc Invoice (InvoiceRequest) returns (InvoiceResponse) {}
+ rpc Inject (InjectRequest) returns (InjectResponse) {}
+
+ rpc List (ListRequest) returns (ListResponse) {}
+
+ rpc Settle (SettleRequest) returns (SettleResponse) {}
+ rpc Cancel (CancelRequest) returns (CancelResponse) {}
+
+ // Cleans cancelled invoices
+ rpc Clean (CleanRequest) returns (CleanResponse) {}
+
+ rpc Track (TrackRequest) returns (stream TrackResponse) {}
+ rpc TrackAll (TrackAllRequest) returns (stream TrackAllResponse) {}
+
+ rpc OnionMessages (stream OnionMessageResponse) returns (stream OnionMessage) {}
+}
+
+enum HookAction {
+ Continue = 0;
+ Resolve = 1;
+}
+
+message GetInfoRequest {}
+message GetInfoResponse {
+ string version = 1;
+}
+
+message Hop {
+ bytes public_key = 1;
+ uint64 short_channel_id = 2;
+ uint64 base_fee = 3;
+ uint64 ppm_fee = 4;
+ uint64 cltv_expiry_delta = 5;
+}
+
+message RoutingHint {
+ repeated Hop hops = 1;
+}
+
+message InvoiceRequest {
+ bytes payment_hash = 1;
+ uint64 amount_msat = 2;
+
+ oneof description {
+ string memo = 3;
+ bytes hash = 4;
+ }
+
+ optional uint64 expiry = 5;
+ optional uint64 min_final_cltv_expiry = 6;
+ repeated RoutingHint routing_hints = 7;
+}
+message InvoiceResponse {
+ string bolt11 = 1;
+}
+
+message InjectRequest {
+ string invoice = 1;
+ optional uint64 min_cltv_expiry = 2;
+}
+message InjectResponse {}
+
+message ListRequest {
+ message Pagination {
+ // Inclusive
+ int64 index_start = 1;
+ uint64 limit = 2;
+ }
+
+ oneof constraint {
+ bytes payment_hash = 1;
+ Pagination pagination = 2;
+ }
+}
+
+enum InvoiceState {
+ UNPAID = 0;
+ ACCEPTED = 1;
+ PAID = 2;
+ CANCELLED = 3;
+}
+
+message Htlc {
+ int64 id = 1;
+ InvoiceState state = 2;
+ string scid = 3;
+ uint64 channel_id = 4;
+ uint64 msat = 5;
+ uint64 created_at = 6;
+ optional uint64 cltv_expiry = 7;
+}
+
+message Invoice {
+ int64 id = 1;
+ bytes payment_hash = 2;
+ optional bytes preimage = 3;
+ string invoice = 4;
+ InvoiceState state = 5;
+ uint64 created_at = 6;
+ optional uint64 settled_at = 8;
+
+ repeated Htlc htlcs = 7;
+
+ optional uint64 min_cltv_expiry = 9;
+}
+
+message ListResponse {
+ repeated Invoice invoices = 1;
+}
+
+message SettleRequest {
+ bytes payment_preimage = 1;
+}
+message SettleResponse {}
+
+message CancelRequest {
+ bytes payment_hash = 1;
+}
+message CancelResponse {}
+
+message CleanRequest {
+ // Clean everything older than age seconds
+ optional uint64 age = 1;
+}
+message CleanResponse {
+ uint64 cleaned = 1;
+}
+
+message TrackRequest {
+ bytes payment_hash = 1;
+}
+
+message TrackResponse {
+ InvoiceState state = 1;
+}
+
+message TrackAllRequest {
+ repeated bytes payment_hashes = 1;
+}
+
+message TrackAllResponse {
+ bytes payment_hash = 1;
+ string bolt11 = 2;
+ InvoiceState state = 3;
+}
+
+message OnionMessage {
+ message ReplyBlindedPath {
+ message Hop {
+ optional bytes blinded_node_id = 1;
+ optional bytes encrypted_recipient_data = 2;
+ }
+
+ optional bytes first_node_id = 1;
+ optional string first_scid = 2;
+ optional uint64 first_scid_dir = 3;
+ optional bytes first_path_key = 4;
+ repeated Hop hops = 5;
+ }
+
+ message UnknownField {
+ uint64 number = 1;
+ bytes value = 2;
+ }
+
+ uint64 id = 1;
+ optional bytes pathsecret = 2;
+ optional ReplyBlindedPath reply_blindedpath = 3;
+ optional bytes invoice_request = 4;
+ optional bytes invoice = 5;
+ optional bytes invoice_error = 6;
+ repeated UnknownField unknown_fields = 7;
+}
+
+message OnionMessageResponse {
+ uint64 id = 1;
+ HookAction action = 2;
+}
diff --git a/src/main.rs b/src/main.rs
index 778d840..957f9c8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,8 @@
-use std::{path::Path, time::Duration};
+use std::{
+ path::{Path, PathBuf},
+ str::FromStr,
+ time::Duration,
+};
use anyhow::anyhow;
use cln_plugin::{
@@ -12,10 +16,17 @@ use nwc::run_nwc;
use nwc_notifications::{payment_received_handler, payment_sent_handler};
use parse::read_startup_options;
use rpc::{nwc_budget, nwc_create, nwc_list, nwc_revoke};
+use serde_json::json;
use structs::PluginState;
use tokio::time;
+use tonic::transport::{Certificate, ClientTlsConfig, Endpoint, Identity};
use util::{load_nwc_store, update_nwc_store};
+use crate::{
+ hold::{hold_client::HoldClient, InvoiceState, ListRequest},
+ nwc_notifications::holdinvoice_accepted_handler,
+};
+
mod nwc;
mod nwc_balance;
mod nwc_hold;
@@ -32,6 +43,9 @@ mod tasks;
mod util;
pub const STARTUP_DELAY: u64 = 1;
+pub mod hold {
+ tonic::include_proto!("hold");
+}
const OPT_RELAYS: StringArrayConfigOption = ConfigOption::new_str_arr_no_default(
"nip47-relays",
@@ -56,10 +70,17 @@ pub const WALLET_PAY_METHODS: [nip47::Method; 4] = [
nip47::Method::PayKeysend,
nip47::Method::MultiPayKeysend,
];
+pub const WALLET_HOLD_METHODS: [nip47::Method; 3] = [
+ nip47::Method::MakeHoldInvoice,
+ nip47::Method::CancelHoldInvoice,
+ nip47::Method::SettleHoldInvoice,
+];
pub const WALLET_NOTIFICATIONS: [nip47::NotificationType; 2] = [
nip47::NotificationType::PaymentReceived,
nip47::NotificationType::PaymentSent,
];
+pub const WALLET_HOLD_NOTIFICATIONS: [nip47::NotificationType; 1] =
+ [nip47::NotificationType::HoldInvoiceAccepted];
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
@@ -109,6 +130,16 @@ async fn main() -> Result<(), anyhow::Error> {
};
let plugin = confplugin.start(state).await?;
+ match check_hold_support(plugin.clone()).await {
+ Ok(()) => {
+ log::info!("Hold support activated, loading pending invoices...");
+ if let Err(e) = load_pending_hold_invoices(plugin.clone()).await {
+ log::error!("Error loading pending hold invoices: {e}");
+ }
+ }
+ Err(e) => log::info!("Hold support not activated: {e}"),
+ }
+
{
let mut rpc = plugin.state().rpc_lock.lock().await;
@@ -167,3 +198,94 @@ async fn load_nwcs(plugin: Plugin, rpc: &mut ClnRpc) -> Result<(),
}
Ok(())
}
+
+async fn load_pending_hold_invoices(plugin: Plugin) -> Result<(), anyhow::Error> {
+ let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
+ let invoices_request = ListRequest { constraint: None };
+ let invoices = hold_client
+ .list(invoices_request)
+ .await?
+ .into_inner()
+ .invoices;
+
+ for invoice in invoices {
+ if invoice.state() == InvoiceState::Accepted || invoice.state() == InvoiceState::Unpaid {
+ log::debug!(
+ "Starting holdinvoice accepted handler for {}",
+ hex::encode(&invoice.payment_hash)
+ );
+ tokio::spawn(holdinvoice_accepted_handler(
+ plugin.clone(),
+ invoice.payment_hash,
+ ));
+ }
+ }
+
+ Ok(())
+}
+
+async fn check_hold_support(plugin: Plugin) -> Result<(), anyhow::Error> {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+ let hold_grpc_host_response: serde_json::Value = rpc
+ .call_raw("listconfigs", &json!({"config": "hold-grpc-host"}))
+ .await?;
+
+ let Some(hold_grpc_host_configs) = hold_grpc_host_response.get("configs") else {
+ return Err(anyhow!("Unsopprted listconfigs response!"));
+ };
+ let Some(hold_grpc_host_config) = hold_grpc_host_configs.get("hold-grpc-host") else {
+ return Err(anyhow!("hold-grpc-host config not found"));
+ };
+ let Some(hold_grpc_host_value) = hold_grpc_host_config.get("value_str") else {
+ return Err(anyhow!("hold-grpc-host config not a string"));
+ };
+ let Some(hold_grpc_host) = hold_grpc_host_value.as_str() else {
+ return Err(anyhow!("hold-grpc-host config not convertable to string"));
+ };
+
+ let hold_grpc_port_response: serde_json::Value = rpc
+ .call_raw("listconfigs", &json!({"config": "hold-grpc-port"}))
+ .await?;
+ let Some(hold_grpc_port_configs) = hold_grpc_port_response.get("configs") else {
+ return Err(anyhow!("Unsopprted listconfigs response!"));
+ };
+ let Some(hold_grpc_port_config) = hold_grpc_port_configs.get("hold-grpc-port") else {
+ return Err(anyhow!("hold-grpc-port config not found"));
+ };
+ let Some(hold_grpc_port_value) = hold_grpc_port_config.get("value_int") else {
+ return Err(anyhow!("hold-grpc-port config not a number"));
+ };
+ let hold_grpc_port = if let Some(hgh) = hold_grpc_port_value.as_u64() {
+ u16::try_from(hgh)?
+ } else {
+ return Err(anyhow!("hold-grpc-port config not convertable to integer"));
+ };
+
+ let cert_dir = PathBuf::from_str(&plugin.configuration().lightning_dir)?.join("hold");
+
+ log::debug!(
+ "Searching {} for hold plugin certs",
+ cert_dir.to_str().unwrap()
+ );
+
+ let ca_cert = tokio::fs::read(cert_dir.join("ca.pem")).await?;
+ let client_cert = tokio::fs::read(cert_dir.join("client.pem")).await?;
+ let client_key = tokio::fs::read(cert_dir.join("client-key.pem")).await?;
+
+ let identity = Identity::from_pem(client_cert, client_key);
+
+ let ca = Certificate::from_pem(ca_cert);
+
+ let tls_config = ClientTlsConfig::new()
+ .ca_certificate(ca)
+ .identity(identity)
+ .domain_name("hold");
+
+ let hold_channel = Endpoint::from_shared(format!("https://{hold_grpc_host}:{hold_grpc_port}"))?
+ .tls_config(tls_config)?
+ .keep_alive_while_idle(true)
+ .connect_lazy();
+ *plugin.state().hold_client.lock() = Some(HoldClient::new(hold_channel));
+
+ Ok(())
+}
diff --git a/src/nwc.rs b/src/nwc.rs
index 448334b..247aedc 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -55,29 +55,29 @@ pub async fn run_nwc(
);
let client_pubkey = Keys::new(nwc_store.uri.secret.clone()).public_key();
- let client = Client::new(wallet_keys.clone());
+ let nostr_client = Client::new(wallet_keys.clone());
log::debug!("relay_count:{}", nwc_store.uri.relays.len());
for relay in &nwc_store.uri.relays {
log::debug!("Adding relay: {relay}");
- client.add_relay(relay).await?;
+ nostr_client.add_relay(relay).await?;
}
if nwc_store.interval_config.is_some() {
start_nwc_budget_job(&plugin, label.clone());
}
- let client_clone = client.clone();
+ let nostr_client_clone = nostr_client.clone();
let plugin_clone = plugin.clone();
let label_clone = label.clone();
tokio::spawn(async move {
loop {
- client_clone.connect().await;
- client_clone
+ nostr_client_clone.connect().await;
+ nostr_client_clone
.wait_for_connection(Duration::from_secs(30))
.await;
- let relays = client_clone.relays().await;
+ let relays = nostr_client_clone.relays().await;
if relays.is_empty() {
log::info!("No more relays left, we probably shut down. Exiting...");
break;
@@ -98,14 +98,14 @@ pub async fn run_nwc(
if let Err(e) = send_nwc_info_event(
plugin_clone.clone(),
- client_clone.clone(),
+ nostr_client_clone.clone(),
method_capabilities.clone(),
wallet_keys.clone(),
)
.await
{
log::warn!("{e}");
- client_clone.disconnect().await;
+ nostr_client_clone.disconnect().await;
time::sleep(Duration::from_secs(5)).await;
continue;
}
@@ -115,15 +115,15 @@ pub async fn run_nwc(
.author(client_pubkey)
.since(Timestamp::now() - STARTUP_DELAY - 1);
- if let Err(e) = client_clone.subscribe(filter, None).await {
+ if let Err(e) = nostr_client_clone.subscribe(filter, None).await {
log::warn!("Could not subscribe to nwc events! {e}");
- client_clone.disconnect().await;
+ nostr_client_clone.disconnect().await;
time::sleep(Duration::from_secs(5)).await;
continue;
}
- let client_clone_handler = client_clone.clone();
- match client_clone
+ let client_clone_handler = nostr_client_clone.clone();
+ match nostr_client_clone
.handle_notifications(|notification| {
let client_clone_handler = client_clone_handler.clone();
let plugin_clone = plugin_clone.clone();
@@ -152,7 +152,7 @@ pub async fn run_nwc(
let mut locked_handles = plugin.state().handles.lock().await;
locked_handles.insert(
label.clone(),
- (client, Keys::new(nwc_store.uri.secret).public_key()),
+ (nostr_client, Keys::new(nwc_store.uri.secret).public_key()),
);
Ok(())
}
@@ -227,7 +227,7 @@ pub fn stop_nwc_budget_job(plugin: &Plugin, label: &String) {
async fn nwc_request_handler(
notification: RelayPoolNotification,
- client: client::Client,
+ nostr_client: client::Client,
plugin: Plugin,
label: String,
wallet_keys: Keys,
@@ -281,13 +281,13 @@ async fn nwc_request_handler(
nip47::RequestParams::GetBalance => get_balance_response(plugin.clone(), &label).await,
nip47::RequestParams::GetInfo => get_info_response(plugin.clone(), &label).await,
nip47::RequestParams::MakeHoldInvoice(make_hold_invoice_request) => {
- make_hold_invoice_response(plugin.clone(), make_hold_invoice_request, &label).await
+ make_hold_invoice_response(plugin.clone(), make_hold_invoice_request).await
}
nip47::RequestParams::CancelHoldInvoice(cancel_hold_invoice_request) => {
- cancel_hold_invoice_response(plugin.clone(), cancel_hold_invoice_request, &label).await
+ cancel_hold_invoice_response(plugin.clone(), cancel_hold_invoice_request).await
}
nip47::RequestParams::SettleHoldInvoice(settle_hold_invoice_request) => {
- settle_hold_invoice_response(plugin.clone(), settle_hold_invoice_request, &label).await
+ settle_hold_invoice_response(plugin.clone(), settle_hold_invoice_request).await
}
};
for (response, id) in responses {
@@ -309,7 +309,7 @@ async fn nwc_request_handler(
}
};
- let send_result = match client.send_event(&response_event).await {
+ let send_result = match nostr_client.send_event(&response_event).await {
Ok(o) => o,
Err(e) => {
log::warn!("Error sending response event! {e}");
diff --git a/src/nwc_hold.rs b/src/nwc_hold.rs
index e048d0c..a706bde 100644
--- a/src/nwc_hold.rs
+++ b/src/nwc_hold.rs
@@ -1,58 +1,242 @@
-use cln_plugin::Plugin;
-use nostr_sdk::nips::nip47;
+use std::str::FromStr;
-use crate::structs::PluginState;
+use cln_plugin::Plugin;
+use cln_rpc::primitives::Sha256;
+use nostr_sdk::{nips::nip47, Timestamp};
+
+use crate::{
+ hold::{invoice_request::Description, CancelRequest, InvoiceRequest, SettleRequest},
+ nwc_notifications::holdinvoice_accepted_handler,
+ structs::PluginState,
+};
pub async fn make_hold_invoice_response(
- _plugin: Plugin,
- _params: nip47::MakeHoldInvoiceRequest,
- _label: &str,
+ plugin: Plugin,
+ params: nip47::MakeHoldInvoiceRequest,
) -> Vec<(nip47::Response, Option)> {
- vec![(
- nip47::Response {
- result_type: nip47::Method::MakeHoldInvoice,
- error: Some(nip47::NIP47Error {
- code: nip47::ErrorCode::NotImplemented,
- message: "Not implemented".to_owned(),
- }),
- result: None,
- },
- None,
- )]
+ vec![match make_hold_invoice(plugin, params).await {
+ Ok(o) => (
+ nip47::Response {
+ result_type: nip47::Method::MakeHoldInvoice,
+ error: None,
+ result: Some(nip47::ResponseResult::MakeHoldInvoice(o)),
+ },
+ None,
+ ),
+ Err(e) => (
+ nip47::Response {
+ result_type: nip47::Method::MakeHoldInvoice,
+ error: Some(e),
+ result: None,
+ },
+ None,
+ ),
+ }]
+}
+
+async fn make_hold_invoice(
+ plugin: Plugin,
+ params: nip47::MakeHoldInvoiceRequest,
+) -> Result {
+ let Some(mut hold_client) = plugin.state().hold_client.lock().clone() else {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::NotImplemented,
+ message: "No hold plugin found".to_owned(),
+ });
+ };
+
+ let description: Option = if let Some(d_hash) = ¶ms.description_hash {
+ if let Some(description) = ¶ms.description {
+ let my_description_hash = Sha256::const_hash(description.as_bytes());
+ let description_hash = Sha256::from_str(d_hash).map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ if my_description_hash != description_hash {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "description_hash not matching description".to_owned(),
+ });
+ }
+ }
+
+ let desc_hash_bytes = match hex::decode(d_hash) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Could not convert description hash to bytes".to_owned(),
+ })
+ }
+ };
+ Some(Description::Hash(desc_hash_bytes))
+ } else {
+ params
+ .description
+ .as_ref()
+ .map(|desc| Description::Memo(desc.clone()))
+ };
+
+ let payment_hash = match hex::decode(¶ms.payment_hash) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid payment hash".to_owned(),
+ })
+ }
+ };
+
+ let expiry = params.expiry.unwrap_or(60 * 60);
+
+ let holdinvoice_request = InvoiceRequest {
+ payment_hash: payment_hash.clone(),
+ amount_msat: params.amount,
+ expiry: Some(expiry),
+ min_final_cltv_expiry: params.cltv_expiry_delta.map(u64::from),
+ routing_hints: Vec::new(),
+ description,
+ };
+
+ let holdinvoice = hold_client
+ .invoice(holdinvoice_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Error creating hold invoice: {e}"),
+ })?
+ .into_inner();
+
+ let response = nip47::MakeHoldInvoiceResponse {
+ invoice: Some(holdinvoice.bolt11),
+ transaction_type: nip47::TransactionType::Incoming,
+ description: params.description,
+ description_hash: params.description_hash,
+ amount: params.amount,
+ created_at: Timestamp::now(),
+ expires_at: Timestamp::now() + expiry,
+ metadata: None,
+ payment_hash: params.payment_hash,
+ };
+
+ tokio::spawn(holdinvoice_accepted_handler(plugin, payment_hash));
+ Ok(response)
}
pub async fn cancel_hold_invoice_response(
- _plugin: Plugin,
- _params: nip47::CancelHoldInvoiceRequest,
- _label: &str,
+ plugin: Plugin,
+ params: nip47::CancelHoldInvoiceRequest,
) -> Vec<(nip47::Response, Option)> {
- vec![(
- nip47::Response {
- result_type: nip47::Method::MakeHoldInvoice,
- error: Some(nip47::NIP47Error {
- code: nip47::ErrorCode::NotImplemented,
- message: "Not implemented".to_owned(),
- }),
- result: None,
- },
- None,
- )]
+ vec![match cancel_hold_invoice(plugin, params).await {
+ Ok(o) => (
+ nip47::Response {
+ result_type: nip47::Method::CancelHoldInvoice,
+ error: None,
+ result: Some(nip47::ResponseResult::CancelHoldInvoice(o)),
+ },
+ None,
+ ),
+ Err(e) => (
+ nip47::Response {
+ result_type: nip47::Method::CancelHoldInvoice,
+ error: Some(e),
+ result: None,
+ },
+ None,
+ ),
+ }]
+}
+
+async fn cancel_hold_invoice(
+ plugin: Plugin,
+ params: nip47::CancelHoldInvoiceRequest,
+) -> Result {
+ let Some(mut hold_client) = plugin.state().hold_client.lock().clone() else {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::NotImplemented,
+ message: "No hold plugin found".to_owned(),
+ });
+ };
+
+ let payment_hash = match hex::decode(¶ms.payment_hash) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid payment hash".to_owned(),
+ })
+ }
+ };
+
+ let hold_cancel_request = CancelRequest { payment_hash };
+
+ let hold_cancel_response = hold_client.cancel(hold_cancel_request).await;
+
+ match hold_cancel_response {
+ Ok(_o) => Ok(nip47::CancelHoldInvoiceResponse {}),
+ Err(e) => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ }
}
pub async fn settle_hold_invoice_response(
- _plugin: Plugin,
- _params: nip47::SettleHoldInvoiceRequest,
- _label: &str,
+ plugin: Plugin,
+ params: nip47::SettleHoldInvoiceRequest,
) -> Vec<(nip47::Response, Option)> {
- vec![(
- nip47::Response {
- result_type: nip47::Method::MakeHoldInvoice,
- error: Some(nip47::NIP47Error {
- code: nip47::ErrorCode::NotImplemented,
- message: "Not implemented".to_owned(),
- }),
- result: None,
- },
- None,
- )]
+ vec![match settle_hold_invoice(plugin, params).await {
+ Ok(o) => (
+ nip47::Response {
+ result_type: nip47::Method::SettleHoldInvoice,
+ error: None,
+ result: Some(nip47::ResponseResult::SettleHoldInvoice(o)),
+ },
+ None,
+ ),
+ Err(e) => (
+ nip47::Response {
+ result_type: nip47::Method::SettleHoldInvoice,
+ error: Some(e),
+ result: None,
+ },
+ None,
+ ),
+ }]
+}
+
+async fn settle_hold_invoice(
+ plugin: Plugin,
+ params: nip47::SettleHoldInvoiceRequest,
+) -> Result {
+ let Some(mut hold_client) = plugin.state().hold_client.lock().clone() else {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::NotImplemented,
+ message: "No hold plugin found".to_owned(),
+ });
+ };
+
+ let preimage = match hex::decode(¶ms.preimage) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid preimage".to_owned(),
+ })
+ }
+ };
+
+ let hold_settle_request = SettleRequest {
+ payment_preimage: preimage,
+ };
+
+ let hold_settle_response = hold_client.settle(hold_settle_request).await;
+
+ match hold_settle_response {
+ Ok(_o) => Ok(nip47::SettleHoldInvoiceResponse {}),
+ Err(e) => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ }
}
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index 33bea1f..b15a54b 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -5,6 +5,7 @@ use cln_rpc::{
model::{
requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest},
responses::{
+ DecodeType,
ListinvoicesInvoices,
ListinvoicesInvoicesStatus,
ListpaysPays,
@@ -16,7 +17,10 @@ use cln_rpc::{
};
use nostr_sdk::{nips::nip47, Timestamp};
-use crate::structs::{PluginState, NOT_INV_ERR};
+use crate::{
+ hold::{self, list_request::Constraint, ListRequest},
+ structs::{PluginState, NOT_INV_ERR},
+};
pub async fn lookup_invoice_response(
plugin: Plugin,
@@ -58,7 +62,7 @@ async fn lookup_invoice(
let invoice = if params.payment_hash.is_some() && params.invoice.is_some() {
None
} else {
- params.invoice
+ params.invoice.clone()
};
let invoices = rpc
@@ -81,47 +85,234 @@ async fn lookup_invoice(
if invoices.len() == 1 {
let invoice_response = invoices.into_iter().next().unwrap();
- make_lookup_response_from_listinvoices(&mut rpc, invoice_response).await
+ return make_lookup_response_from_listinvoices(&mut rpc, invoice_response).await;
+ }
+
+ let payment_hash_hash = if let Some(hash) = ¶ms.payment_hash {
+ if let Ok(res) = Sha256::from_str(hash) {
+ Some(res)
+ } else {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: "Could not convert payment hash".to_owned(),
+ });
+ }
} else {
- let payment_hash_hash = if let Some(hash) = params.payment_hash {
- if let Ok(res) = Sha256::from_str(&hash) {
- Some(res)
- } else {
+ None
+ };
+
+ let pays = rpc
+ .call_typed(&ListpaysRequest {
+ bolt11: invoice,
+ index: None,
+ limit: None,
+ payment_hash: payment_hash_hash,
+ start: None,
+ status: None,
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?
+ .pays;
+
+ if pays.len() == 1 {
+ let list_pay = pays.into_iter().next().unwrap();
+
+ return make_lookup_response_from_listpays(&mut rpc, list_pay).await;
+ }
+
+ let holdinvoice_support = plugin.state().hold_client.lock().is_some();
+
+ if holdinvoice_support {
+ let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
+
+ let (hold_invoice, invoice_decoded) = if let Some(ph) = ¶ms.payment_hash {
+ let payment_hash_hash = match hex::decode(ph) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid payment hash".to_owned(),
+ })
+ }
+ };
+ let list_request = ListRequest {
+ constraint: Some(Constraint::PaymentHash(payment_hash_hash)),
+ };
+ let hold_lookup = hold_client
+ .list(list_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Could not fetch hold invoice: {e}"),
+ })?
+ .into_inner();
+
+ if hold_lookup.invoices.len() != 1 {
return Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: "Could not convert payment hash".to_owned(),
+ code: nip47::ErrorCode::Other,
+ message: "Transaction not found".to_owned(),
});
}
+
+ let hold_invoice = hold_lookup.invoices.into_iter().next().unwrap();
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+
+ (hold_invoice, invoice_decoded)
+ } else {
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: params.invoice.unwrap(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ let ph = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_payment_hash.unwrap(),
+ DecodeType::BOLT11_INVOICE => invoice_decoded.payment_hash.unwrap().to_string(),
+ _ => todo!(),
+ };
+ let payment_hash_hash = match hex::decode(&ph) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid payment hash in invoice".to_owned(),
+ })
+ }
+ };
+
+ let list_request = ListRequest {
+ constraint: Some(Constraint::PaymentHash(payment_hash_hash)),
+ };
+
+ let hold_lookup = hold_client
+ .list(list_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Could not fetch hold invoice: {e}"),
+ })?
+ .into_inner();
+
+ if hold_lookup.invoices.len() != 1 {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Transaction not found".to_owned(),
+ });
+ }
+
+ let hold_invoice = hold_lookup.invoices.into_iter().next().unwrap();
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ (hold_invoice, invoice_decoded)
+ };
+ let not_invoice_err = Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: NOT_INV_ERR.to_owned(),
+ });
+
+ let description = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description,
+ _ => return not_invoice_err,
+ };
+ let description_hash = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => None,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description_hash.map(|h| h.to_string()),
+ _ => return not_invoice_err,
+ };
+
+ let created_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
+ }
+ DecodeType::BOLT11_INVOICE => Timestamp::from_secs(invoice_decoded.created_at.unwrap()),
+ _ => return not_invoice_err,
+ };
+
+ let amount = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_amount_msat.unwrap().msat(),
+ DecodeType::BOLT11_INVOICE => {
+ if let Some(amt) = invoice_decoded.amount_msat {
+ amt.msat()
+ } else {
+ // amount: `any` but have to put a value...
+ 0
+ }
+ }
+ _ => return not_invoice_err,
+ };
+
+ let expires_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded
+ .invoice_relative_expiry
+ .map(|e_at| created_at + Timestamp::from_secs(u64::from(e_at))),
+ DecodeType::BOLT11_INVOICE => invoice_decoded
+ .expiry
+ .map(|e_at| created_at + Timestamp::from_secs(e_at)),
+ _ => return not_invoice_err,
+ };
+
+ let state = match hold_invoice.state() {
+ hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
+ hold::InvoiceState::Accepted => nip47::TransactionState::Pending, // TODO ACCEPTED STATE
+ hold::InvoiceState::Paid => nip47::TransactionState::Settled,
+ hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
+ };
+
+ let settled_at = if hold_invoice.settled_at() != 0 {
+ Some(Timestamp::from_secs(hold_invoice.settled_at()))
} else {
None
};
- let pays = rpc
- .call_typed(&ListpaysRequest {
- bolt11: invoice,
- index: None,
- limit: None,
- payment_hash: payment_hash_hash,
- start: None,
- status: None,
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?
- .pays;
+ let preimage = if hold_invoice.state() == hold::InvoiceState::Paid {
+ Some(hex::encode(hold_invoice.preimage()))
+ } else {
+ None
+ };
- if pays.len() != 1 {
- return Err(nip47::NIP47Error {
- code: nip47::ErrorCode::NotFound,
- message: "Transaction not found".to_owned(),
- });
- }
- let list_pay = pays.into_iter().next().unwrap();
-
- make_lookup_response_from_listpays(&mut rpc, list_pay).await
+ return Ok(nip47::LookupInvoiceResponse {
+ transaction_type: Some(nip47::TransactionType::Incoming),
+ invoice: Some(hold_invoice.invoice.clone()),
+ description,
+ description_hash,
+ preimage,
+ payment_hash: hex::encode(hold_invoice.payment_hash),
+ amount,
+ fees_paid: 0,
+ created_at,
+ expires_at,
+ settled_at,
+ metadata: None,
+ state: Some(state),
+ });
}
+
+ Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::NotFound,
+ message: "Transaction not found".to_owned(),
+ })
}
pub async fn list_transactions_response(
@@ -193,6 +384,118 @@ async fn list_transactions(
Err(_e) => (),
}
}
+
+ let holdinvoice_support = plugin.state().hold_client.lock().is_some();
+
+ if holdinvoice_support {
+ let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
+
+ let lookup_request = ListRequest { constraint: None };
+
+ let hold_lookup = hold_client
+ .list(lookup_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Could not fetch hold invoices: {e}"),
+ })?
+ .into_inner();
+
+ for hold_invoice in hold_lookup.invoices {
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+
+ let description = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description,
+ _ => continue,
+ };
+ let description_hash = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => None,
+ DecodeType::BOLT11_INVOICE => {
+ invoice_decoded.description_hash.map(|h| h.to_string())
+ }
+ _ => continue,
+ };
+
+ let created_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
+ }
+ DecodeType::BOLT11_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.created_at.unwrap())
+ }
+ _ => continue,
+ };
+
+ let amount = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => {
+ invoice_decoded.invoice_amount_msat.unwrap().msat()
+ }
+ DecodeType::BOLT11_INVOICE => {
+ if let Some(amt) = invoice_decoded.amount_msat {
+ amt.msat()
+ } else {
+ // amount: `any` but have to put a value...
+ 0
+ }
+ }
+ _ => continue,
+ };
+
+ let expires_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded
+ .invoice_relative_expiry
+ .map(|e_at| created_at + Timestamp::from_secs(u64::from(e_at))),
+ DecodeType::BOLT11_INVOICE => invoice_decoded
+ .expiry
+ .map(|e_at| created_at + Timestamp::from_secs(e_at)),
+ _ => continue,
+ };
+
+ let state = match hold_invoice.state() {
+ hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
+ hold::InvoiceState::Accepted => nip47::TransactionState::Pending, // TODO: ACCEPTED STATE
+ hold::InvoiceState::Paid => nip47::TransactionState::Settled,
+ hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
+ };
+
+ let settled_at = if hold_invoice.settled_at() != 0 {
+ Some(Timestamp::from_secs(hold_invoice.settled_at()))
+ } else {
+ None
+ };
+
+ let preimage = if hold_invoice.state() == hold::InvoiceState::Paid {
+ Some(hex::encode(hold_invoice.preimage()))
+ } else {
+ None
+ };
+
+ transactions.push(nip47::LookupInvoiceResponse {
+ transaction_type: Some(nip47::TransactionType::Incoming),
+ invoice: Some(hold_invoice.invoice.clone()),
+ description,
+ description_hash,
+ preimage,
+ payment_hash: hex::encode(hold_invoice.payment_hash),
+ amount,
+ fees_paid: 0,
+ created_at,
+ expires_at,
+ settled_at,
+ metadata: None,
+ state: Some(state),
+ });
+ }
+ }
}
if query_payments {
diff --git a/src/nwc_notifications.rs b/src/nwc_notifications.rs
index 8f02b6a..e86afaf 100644
--- a/src/nwc_notifications.rs
+++ b/src/nwc_notifications.rs
@@ -4,7 +4,7 @@ use anyhow::anyhow;
use cln_plugin::Plugin;
use cln_rpc::{
model::{
- requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest},
+ requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest, ListpeerchannelsRequest},
responses::{
DecodeResponse,
ListinvoicesInvoices,
@@ -24,6 +24,7 @@ use nostr_sdk::{
};
use crate::{
+ hold::{list_request::Constraint, InvoiceState, ListRequest, TrackRequest},
structs::{PluginState, NOT_INV_ERR},
OPT_NOTIFICATIONS,
};
@@ -380,3 +381,129 @@ async fn send_notification(
Ok(())
}
+
+pub async fn holdinvoice_accepted_handler(
+ plugin: Plugin,
+ payment_hash: Vec,
+) -> Result<(), anyhow::Error> {
+ let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
+
+ let track_request = TrackRequest {
+ payment_hash: payment_hash.clone(),
+ };
+ let mut track_stream = hold_client.track(track_request).await?.into_inner();
+
+ while let Some(response) = track_stream.message().await? {
+ log::debug!("Invoice status: {}", response.state().as_str_name());
+ if response.state() == InvoiceState::Accepted {
+ break;
+ }
+ }
+
+ let list_request = ListRequest {
+ constraint: Some(Constraint::PaymentHash(payment_hash.clone())),
+ };
+
+ let hold_lookup = hold_client.list(list_request).await?.into_inner();
+
+ if hold_lookup.invoices.len() != 1 {
+ return Err(anyhow!("hold plugin did not return exactly one invoice"));
+ }
+
+ let hold_invoice = hold_lookup.invoices.first().unwrap();
+
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await?;
+
+ let amount = match invoice_decoded.item_type {
+ cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
+ invoice_decoded.invoice_amount_msat.unwrap().msat()
+ }
+ cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
+ if let Some(amt) = invoice_decoded.amount_msat {
+ amt.msat()
+ } else {
+ // amount: `any` but have to put a value...
+ 0
+ }
+ }
+ _ => return Err(anyhow!("hold plugin did not return an invoice string")),
+ };
+
+ let created_at = match invoice_decoded.item_type {
+ cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
+ }
+ cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.created_at.unwrap())
+ }
+ _ => return Err(anyhow!("hold plugin did not return an invoice string")),
+ };
+
+ let expires_at = match invoice_decoded.item_type {
+ cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
+ created_at
+ + Timestamp::from_secs(u64::from(invoice_decoded.invoice_relative_expiry.unwrap()))
+ }
+ cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
+ created_at + Timestamp::from_secs(invoice_decoded.expiry.unwrap())
+ }
+ _ => return Err(anyhow!("hold plugin did not return an invoice string")),
+ };
+
+ let list_peer_channels = rpc
+ .call_typed(&ListpeerchannelsRequest {
+ id: None,
+ short_channel_id: None,
+ })
+ .await?
+ .channels;
+
+ let payment_hash_hash = Sha256::from_str(&hex::encode(payment_hash))?;
+
+ let mut lowest_htlc_expiry = 0;
+
+ for peer in list_peer_channels {
+ if let Some(htlcs) = peer.htlcs {
+ for htlc in htlcs {
+ if htlc.payment_hash != payment_hash_hash {
+ continue;
+ }
+ if htlc.expiry < lowest_htlc_expiry {
+ lowest_htlc_expiry = htlc.expiry;
+ }
+ }
+ }
+ }
+
+ let clients = plugin.state().handles.lock().await;
+
+ let content = nip47::Notification {
+ notification_type: nip47::NotificationType::HoldInvoiceAccepted,
+ notification: nip47::NotificationResult::HoldInvoiceAccepted(
+ nip47::HoldInvoiceAcceptedNotification {
+ transaction_type: nip47::TransactionType::Incoming,
+ invoice: hold_invoice.invoice.clone(),
+ description: None,
+ description_hash: None,
+ payment_hash: hex::encode(&hold_invoice.payment_hash),
+ amount,
+ created_at,
+ expires_at,
+ settle_deadline: lowest_htlc_expiry,
+ metadata: None,
+ },
+ ),
+ };
+ let notification = serde_json::to_string(&content).unwrap();
+
+ for (client, client_pubkey) in clients.values() {
+ send_notification(¬ification, client, client_pubkey).await?;
+ }
+ Ok(())
+}
diff --git a/src/structs.rs b/src/structs.rs
index c96db5a..8964bfd 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -5,6 +5,9 @@ use nostr_sdk::{client, nips::nip47, nostr};
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use tokio::sync::oneshot;
+use tonic::transport::Channel;
+
+use crate::hold::hold_client::HoldClient;
pub const NOT_INV_ERR: &str = "Not an invoice or invalid invoice";
@@ -14,6 +17,7 @@ pub struct PluginState {
pub handles: Arc>>,
pub rpc_lock: Arc>,
pub budget_jobs: Arc>>>,
+ pub hold_client: Arc>>>,
}
impl PluginState {
pub async fn new(path: PathBuf) -> Result {
@@ -22,6 +26,7 @@ impl PluginState {
handles: Arc::new(tokio::sync::Mutex::new(HashMap::new())),
rpc_lock: Arc::new(tokio::sync::Mutex::new(ClnRpc::new(path).await?)),
budget_jobs: Arc::new(Mutex::new(HashMap::new())),
+ hold_client: Arc::new(Mutex::new(None)),
})
}
}
diff --git a/src/util.rs b/src/util.rs
index 36cc484..6956d9e 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -10,6 +10,8 @@ use crate::{
structs::{NwcStore, PluginState},
OPT_NOTIFICATIONS,
PLUGIN_NAME,
+ WALLET_HOLD_METHODS,
+ WALLET_HOLD_NOTIFICATIONS,
WALLET_NOTIFICATIONS,
WALLET_PAY_METHODS,
WALLET_READ_METHODS,
@@ -124,11 +126,22 @@ pub fn at_or_above_version(my_version: &str, min_version: &str) -> Result) -> (String, String) {
+ let holdinvoice_support = plugin.state().hold_client.lock().is_some();
+
let mut methods = WALLET_READ_METHODS.map(|m| m.to_string()).join(" ");
if !is_read_only {
methods.push(' ');
methods.push_str(WALLET_PAY_METHODS.map(|m| m.to_string()).join(" ").as_str());
}
+ if holdinvoice_support {
+ methods.push(' ');
+ methods.push_str(
+ WALLET_HOLD_METHODS
+ .map(|m| m.to_string())
+ .join(" ")
+ .as_str(),
+ );
+ }
let mut notifications = String::new();
if plugin.option(&OPT_NOTIFICATIONS).unwrap() {
@@ -138,23 +151,41 @@ pub fn build_capabilities(is_read_only: bool, plugin: &Plugin) -> (
.join(" ")
.as_str(),
);
+ if holdinvoice_support {
+ notifications.push(' ');
+ notifications.push_str(
+ WALLET_HOLD_NOTIFICATIONS
+ .map(|m| m.to_string())
+ .join(" ")
+ .as_str(),
+ );
+ }
}
(methods, notifications)
}
-pub fn build_methods_vec(is_read_only: bool, _plugin: &Plugin) -> Vec {
+pub fn build_methods_vec(is_read_only: bool, plugin: &Plugin) -> Vec {
+ let holdinvoice_support = plugin.state().hold_client.lock().is_some();
let mut methods = WALLET_READ_METHODS.to_vec();
if !is_read_only {
methods.extend_from_slice(&WALLET_PAY_METHODS);
}
+ if holdinvoice_support {
+ methods.extend_from_slice(&WALLET_HOLD_METHODS);
+ }
methods
}
pub fn build_notifications_vec(plugin: &Plugin) -> Vec {
+ let holdinvoice_support = plugin.state().hold_client.lock().is_some();
+
let mut notifications = Vec::new();
if plugin.option(&OPT_NOTIFICATIONS).unwrap() {
notifications.extend_from_slice(&WALLET_NOTIFICATIONS.map(|m| m.to_string()));
+ if holdinvoice_support {
+ notifications.extend_from_slice(&WALLET_HOLD_NOTIFICATIONS.map(|m| m.to_string()));
+ }
}
notifications
}
diff --git a/tests/config.toml b/tests/config.toml
index 062124b..3afabc9 100644
--- a/tests/config.toml
+++ b/tests/config.toml
@@ -9,4 +9,4 @@ reject_future_seconds = 1800
[limits]
limit_scrapers = false
[network]
-address = "0.0.0.0"
+address = "127.0.0.1"
diff --git a/tests/setup.sh b/tests/setup.sh
index 0fe9440..829a336 100755
--- a/tests/setup.sh
+++ b/tests/setup.sh
@@ -81,3 +81,17 @@ if [ -d "$proto_path" ]; then
exit 1
fi
fi
+
+hold_url="https://github.com/BoltzExchange/hold/releases/download/v0.3.3/hold-linux-amd64.tar.gz"
+
+if ! curl -L "$hold_url" -o "$script_dir/hold-linux-amd64.tar.gz"; then
+ echo "Error downloading the file from $hold_url" >&2
+ exit 1
+fi
+
+if ! tar -xzvf "$script_dir/hold-linux-amd64.tar.gz" -C "$script_dir"; then
+ echo "Error extracting the contents of hold-linux-amd64.tar.gz" >&2
+ exit 1
+fi
+
+mv "$script_dir/build/hold-linux-amd64" "$script_dir/hold"
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
index daf256c..3642c96 100755
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -4,13 +4,15 @@ import json
import logging
import time
import asyncio
+import secrets
+import uuid
from datetime import datetime, timedelta
from typing import Any, Awaitable, Callable, Union
import pytest
from pyln.testing.fixtures import * # noqa: F403
from pyln.testing.utils import RpcError, wait_for, TIMEOUT
-from util import generate_random_label, get_plugin # noqa: F401
+from util import generate_random_label, get_plugin, get_hold # noqa: F401
from nostr_sdk import (
Alphabet,
@@ -75,7 +77,10 @@ async def fetch_event_responses(
) -> tuple[list[Event], Any]:
events = []
response_filter = Filter().kind(Kind(event_kind)).pubkey(client_pubkey)
- await client.subscribe(response_filter)
+
+ id = uuid.uuid4().hex
+ LOGGER.info(f"Subscribing with id {id} to {response_filter}")
+ await client.subscribe_with_id(id, response_filter)
handler = NotificationHandler(events, stop_after)
task = asyncio.create_task(client.handle_notifications(handler))
@@ -1454,3 +1459,551 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
info_event.tags().find(TagKind.UNKNOWN("notifications")).content()
== "payment_received payment_sent"
)
+
+
+@pytest.mark.asyncio
+async def test_hold_invoice(
+ node_factory,
+ executor,
+ get_plugin, # noqa: F811
+ get_hold, # noqa: F811
+ nostr_relay,
+):
+ url = nostr_relay
+ l1, l2 = node_factory.line_graph(
+ 2,
+ wait_for_announce=True,
+ opts=[
+ {
+ "log-level": "debug",
+ "may_reconnect": True,
+ },
+ {
+ "log-level": "debug",
+ "plugin": get_plugin,
+ "important-plugin": get_hold,
+ "nip47-relays": url,
+ "may_reconnect": True,
+ },
+ ],
+ )
+ uri_res = l2.rpc.call("nip47-create", ["test1", 3010])
+ uri_str = uri_res["uri"]
+ client_pubkey = PublicKey.parse(uri_res["clientkey_public"])
+ LOGGER.info(uri_str)
+ uri = NostrWalletConnectUri.parse(uri_str)
+
+ nwc = Nwc(uri)
+
+ preimage = secrets.token_hex(32)
+ payment_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
+ LOGGER.info(f"preimage: {preimage}")
+ LOGGER.info(f"payment_hash: {payment_hash}")
+ content = {
+ "method": "make_hold_invoice",
+ "params": {
+ "amount": 5000,
+ "payment_hash": payment_hash,
+ },
+ }
+ content = json.dumps(content)
+ signer = NostrSigner.keys(Keys(uri.secret()))
+ encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ event = (
+ await EventBuilder(Kind(23194), encrypted_content)
+ .tags([Tag.public_key(uri.public_key())])
+ .sign(signer)
+ )
+ client = Client(signer)
+ relay_url = RelayUrl.parse(url)
+ await client.add_relay(relay_url)
+ await client.connect()
+
+ await fetch_info_event(client, uri)
+
+ (responses1, _res) = await fetch_event_responses(
+ client, client_pubkey, 23195, client.send_event(event), 1
+ )
+ error_events = []
+ success_events = []
+ for event in responses1:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if "result" in content and content["result"] is not None:
+ success_events.append(content)
+ if "error" in content and content["error"] is not None:
+ error_events.append(content)
+
+ assert len(success_events) == 1
+ assert len(error_events) == 0
+
+ assert success_events[0]["result_type"] == "make_hold_invoice"
+ assert success_events[0]["result"]["payment_hash"] == payment_hash
+ assert success_events[0]["result"]["type"] == "incoming"
+ assert success_events[0]["result"]["invoice"] is not None
+ invoice1 = success_events[0]["result"]["invoice"]
+ assert "description" not in success_events[0]["result"]
+ assert "description_hash" not in success_events[0]["result"]
+ assert success_events[0]["result"]["amount"] == 5000
+ invoice1_created_at = pytest.approx(int(time.time()), abs=1)
+ assert success_events[0]["result"]["created_at"] == invoice1_created_at
+ invoice1_expires_at = pytest.approx(int(time.time()) + 3600, abs=1)
+ assert success_events[0]["result"]["expires_at"] == invoice1_expires_at
+ assert "metadata" not in success_events[0]["result"]
+
+ lookup_hold = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=None,
+ )
+ )
+ assert lookup_hold.invoice == success_events[0]["result"]["invoice"]
+ assert lookup_hold.amount == 5000
+ assert lookup_hold.description is None
+ assert lookup_hold.created_at.as_secs() == success_events[0]["result"]["created_at"]
+ assert lookup_hold.description_hash is None
+ assert lookup_hold.expires_at.as_secs() == success_events[0]["result"]["expires_at"]
+ assert lookup_hold.fees_paid == 0
+ assert lookup_hold.metadata is None
+ assert lookup_hold.preimage is None
+ assert lookup_hold.payment_hash == payment_hash
+ assert lookup_hold.transaction_type.name == "INCOMING"
+ assert lookup_hold.state.name == "PENDING"
+ assert lookup_hold.settled_at is None
+
+ (responses2, _res) = await fetch_event_responses(
+ client,
+ client_pubkey,
+ 23196,
+ lambda: executor.submit(
+ l1.rpc.call, "xpay", [success_events[0]["result"]["invoice"]]
+ ),
+ 1,
+ )
+ hold_events = []
+ for event in responses2:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if content["notification_type"] == "hold_invoice_accepted":
+ hold_events.append(content)
+ assert content["notification"]["payment_hash"] == payment_hash
+
+ lookup_hold = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=None,
+ invoice=invoice1,
+ )
+ )
+ assert lookup_hold.invoice == invoice1
+ assert lookup_hold.amount == 5000
+ assert lookup_hold.description is None
+ assert lookup_hold.created_at.as_secs() == invoice1_created_at
+ assert lookup_hold.description_hash is None
+ assert lookup_hold.expires_at.as_secs() == invoice1_expires_at
+ assert lookup_hold.fees_paid == 0
+ assert lookup_hold.metadata is None
+ assert lookup_hold.preimage is None
+ assert lookup_hold.payment_hash == payment_hash
+ assert lookup_hold.transaction_type.name == "INCOMING"
+ assert lookup_hold.state.name == "PENDING" # TODO ACCEPTED STATE
+ assert lookup_hold.settled_at is None
+
+ content = {
+ "method": "settle_hold_invoice",
+ "params": {
+ "preimage": preimage,
+ },
+ }
+ content = json.dumps(content)
+ encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ event = (
+ await EventBuilder(Kind(23194), encrypted_content)
+ .tags([Tag.public_key(uri.public_key())])
+ .sign(signer)
+ )
+
+ (responses3, _res) = await fetch_event_responses(
+ client, client_pubkey, 23195, client.send_event(event), 1
+ )
+ error_events = []
+ success_events = []
+ for event in responses3:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if (
+ "result" in content
+ and content["result"] is not None
+ and content["result_type"] == "settle_hold_invoice"
+ ):
+ success_events.append(content)
+ if "error" in content and content["error"] is not None:
+ error_events.append(content)
+
+ assert len(success_events) == 1
+ assert len(error_events) == 0
+ for content in success_events:
+ assert content["result_type"] == "settle_hold_invoice"
+ lookup_hold = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=None,
+ invoice=invoice1,
+ )
+ )
+ assert lookup_hold.invoice == invoice1
+ assert lookup_hold.amount == 5000
+ assert lookup_hold.description is None
+ assert lookup_hold.created_at.as_secs() == invoice1_created_at
+ assert lookup_hold.description_hash is None
+ assert lookup_hold.expires_at.as_secs() == invoice1_expires_at
+ assert lookup_hold.fees_paid == 0
+ assert lookup_hold.metadata is None
+ assert lookup_hold.preimage == preimage
+ assert lookup_hold.payment_hash == payment_hash
+ assert lookup_hold.transaction_type.name == "INCOMING"
+ assert lookup_hold.state.name == "SETTLED"
+ assert lookup_hold.settled_at.as_secs() == pytest.approx(
+ int(time.time()), abs=1
+ )
+
+ wait_for(
+ lambda: l1.rpc.call("listpays", {"payment_hash": payment_hash})["pays"][0][
+ "status"
+ ]
+ == "complete"
+ )
+
+ preimage = secrets.token_hex(32)
+ payment_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
+ content = {
+ "method": "make_hold_invoice",
+ "params": {
+ "amount": 5000,
+ "payment_hash": payment_hash,
+ "description": "cancel_hold",
+ "expiry": 1000,
+ "cltv_expiry_delta": 200,
+ },
+ }
+ content = json.dumps(content)
+ signer = NostrSigner.keys(Keys(uri.secret()))
+ encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ event = (
+ await EventBuilder(Kind(23194), encrypted_content)
+ .tags([Tag.public_key(uri.public_key())])
+ .sign(signer)
+ )
+
+ (responses4, _res) = await fetch_event_responses(
+ client, client_pubkey, 23195, client.send_event(event), 1
+ )
+ error_events = []
+ success_events = []
+ for event in responses4:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if (
+ "result" in content
+ and content["result"] is not None
+ and content["result_type"] == "make_hold_invoice"
+ and content["result"]["payment_hash"] == payment_hash
+ ):
+ success_events.append(content)
+ if "error" in content and content["error"] is not None:
+ error_events.append(content)
+
+ assert len(success_events) == 1
+ assert len(error_events) == 0
+ for content in success_events:
+ assert content["result_type"] == "make_hold_invoice"
+ assert content["result"]["payment_hash"] == payment_hash
+ invoice2 = content["result"]["invoice"]
+ invoice2_created_at = pytest.approx(int(time.time()), abs=1)
+ invoice2_expires_at = pytest.approx(int(time.time()) + 1000, abs=1)
+
+ (responses5, _res) = await fetch_event_responses(
+ client,
+ client_pubkey,
+ 23196,
+ lambda: executor.submit(
+ l1.rpc.call, "xpay", [success_events[0]["result"]["invoice"]]
+ ),
+ 1,
+ )
+ hold_events = []
+ for event in responses5:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if (
+ content["notification_type"] == "hold_invoice_accepted"
+ and content["notification"]["payment_hash"] == payment_hash
+ ):
+ hold_events.append(content)
+ assert len(hold_events) == 1
+
+ content = {
+ "method": "cancel_hold_invoice",
+ "params": {
+ "payment_hash": payment_hash,
+ },
+ }
+ content = json.dumps(content)
+ encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ event = (
+ await EventBuilder(Kind(23194), encrypted_content)
+ .tags([Tag.public_key(uri.public_key())])
+ .sign(signer)
+ )
+
+ (responses6, _res) = await fetch_event_responses(
+ client,
+ client_pubkey,
+ 23195,
+ client.send_event(event),
+ 1,
+ )
+ error_events = []
+ success_events = []
+ for event in responses6:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if (
+ "result" in content
+ and content["result"] is not None
+ and content["result_type"] == "cancel_hold_invoice"
+ ):
+ success_events.append(content)
+ if "error" in content and content["error"] is not None:
+ error_events.append(content)
+
+ assert len(success_events) == 1
+ assert len(error_events) == 0
+ for content in success_events:
+ assert content["result_type"] == "cancel_hold_invoice"
+ lookup_hold = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=None,
+ invoice=invoice2,
+ )
+ )
+ assert lookup_hold.invoice == invoice2
+ assert lookup_hold.amount == 5000
+ assert lookup_hold.description == "cancel_hold"
+ assert lookup_hold.created_at.as_secs() == invoice2_created_at
+ assert lookup_hold.description_hash is None
+ assert lookup_hold.expires_at.as_secs() == invoice2_expires_at
+ assert lookup_hold.fees_paid == 0
+ assert lookup_hold.metadata is None
+ assert lookup_hold.preimage is None
+ assert lookup_hold.payment_hash == payment_hash
+ assert lookup_hold.transaction_type.name == "INCOMING"
+ assert lookup_hold.state.name == "EXPIRED"
+ assert lookup_hold.settled_at is None
+
+ invoice2_decoded = l1.rpc.call("decode", [invoice2])
+ assert invoice2_decoded["min_final_cltv_expiry"] == 200
+
+ wait_for(
+ lambda: l1.rpc.call("listpays", {"payment_hash": payment_hash})["pays"][0][
+ "status"
+ ]
+ == "failed"
+ )
+
+ nwc = Nwc(uri)
+
+ invoice_lookup1 = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=None,
+ )
+ )
+ invoice_lookup2 = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=None,
+ invoice=invoice2,
+ )
+ )
+ invoice_lookup3 = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=invoice2,
+ )
+ )
+ assert invoice_lookup1 == invoice_lookup2
+ assert invoice_lookup1 == invoice_lookup3
+
+ invoice_lookup4 = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=None,
+ invoice=invoice1,
+ )
+ )
+
+ result = await nwc.list_transactions(
+ ListTransactionsRequest(
+ _from=None,
+ until=None,
+ limit=None,
+ offset=None,
+ unpaid=True,
+ transaction_type=None,
+ )
+ )
+ assert len(result) == 2
+ assert result == [invoice_lookup1, invoice_lookup4] or result == [
+ invoice_lookup4,
+ invoice_lookup1,
+ ]
+
+ description3 = "test3"
+ description_hash3 = hashlib.sha256(description3.encode()).hexdigest()
+ preimage = secrets.token_hex(32)
+ payment_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
+ content = {
+ "method": "make_hold_invoice",
+ "params": {
+ "amount": 5001,
+ "payment_hash": payment_hash,
+ "description": description3,
+ "description_hash": description_hash3,
+ },
+ }
+ content = json.dumps(content)
+ encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ event = (
+ await EventBuilder(Kind(23194), encrypted_content)
+ .tags([Tag.public_key(uri.public_key())])
+ .sign(signer)
+ )
+ await client.send_event(event)
+
+ start_time = datetime.now()
+ while (datetime.now() - start_time) < timedelta(seconds=10):
+ time.sleep(1)
+ try:
+ await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=None,
+ )
+ )
+ break
+ except Exception:
+ continue
+
+ lookup_hold = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=None,
+ )
+ )
+ assert lookup_hold.amount == 5001
+ assert lookup_hold.description is None
+ assert lookup_hold.description_hash == description_hash3
+ assert lookup_hold.metadata is None
+ assert lookup_hold.preimage is None
+ assert lookup_hold.payment_hash == payment_hash
+ assert lookup_hold.transaction_type.name == "INCOMING"
+ assert lookup_hold.state.name == "PENDING"
+ assert lookup_hold.settled_at is None
+
+ description4 = "test4"
+ description_hash4 = hashlib.sha256(description4.encode()).hexdigest()
+ preimage = secrets.token_hex(32)
+ payment_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
+ content = {
+ "method": "make_hold_invoice",
+ "params": {
+ "amount": 5002,
+ "payment_hash": payment_hash,
+ "description_hash": description_hash4,
+ },
+ }
+ content = json.dumps(content)
+ encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ event = (
+ await EventBuilder(Kind(23194), encrypted_content)
+ .tags([Tag.public_key(uri.public_key())])
+ .sign(signer)
+ )
+ await client.send_event(event)
+
+ start_time = datetime.now()
+ while (datetime.now() - start_time) < timedelta(seconds=10):
+ time.sleep(1)
+ try:
+ await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=None,
+ )
+ )
+ break
+ except Exception:
+ continue
+
+ lookup_hold = await nwc.lookup_invoice(
+ LookupInvoiceRequest(
+ payment_hash=payment_hash,
+ invoice=None,
+ )
+ )
+ assert lookup_hold.amount == 5002
+ assert lookup_hold.description is None
+ assert lookup_hold.description_hash == description_hash4
+ assert lookup_hold.metadata is None
+ assert lookup_hold.preimage is None
+ assert lookup_hold.payment_hash == payment_hash
+ assert lookup_hold.transaction_type.name == "INCOMING"
+ assert lookup_hold.state.name == "PENDING"
+ assert lookup_hold.settled_at is None
+
+ info_event = await fetch_info_event(client, uri)
+ assert (
+ info_event.content()
+ == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice multi_pay_invoice pay_keysend multi_pay_keysend make_hold_invoice cancel_hold_invoice settle_hold_invoice notifications"
+ )
+ assert (
+ info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
+ == "nip44_v2 nip04"
+ )
+ assert (
+ info_event.tags().find(TagKind.UNKNOWN("notifications")).content()
+ == "payment_received payment_sent hold_invoice_accepted"
+ )
+
+ l2.restart()
+
+ l1.rpc.connect(l2.info["id"], "localhost", l2.port)
+
+ (responses7, _res) = await fetch_event_responses(
+ client,
+ client_pubkey,
+ 23196,
+ lambda: executor.submit(l1.rpc.call, "xpay", [lookup_hold.invoice]),
+ 1,
+ )
+ hold_events = []
+ for event in responses7:
+ LOGGER.info(event)
+ content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = json.loads(content)
+ LOGGER.info(content)
+ if (
+ content["notification_type"] == "hold_invoice_accepted"
+ and content["notification"]["payment_hash"] == payment_hash
+ ):
+ hold_events.append(content)
+ assert len(hold_events) == 1
diff --git a/tests/util.py b/tests/util.py
index a3f69aa..393a970 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -1,8 +1,8 @@
-import logging
import os
import random
import string
from pathlib import Path
+from hashlib import sha256
import pytest
@@ -11,9 +11,11 @@ plugin_dir = Path(__file__).parent.parent.resolve()
COMPILED_PATH = plugin_dir / "target" / RUST_PROFILE / "cln-nip47"
DOWNLOAD_PATH = plugin_dir / "tests" / "cln-nip47"
+DOWNLOAD_HOLD_PATH = plugin_dir / "tests" / "hold"
+
@pytest.fixture
-def get_plugin(directory):
+def get_plugin():
if COMPILED_PATH.is_file():
return COMPILED_PATH
elif DOWNLOAD_PATH.is_file():
@@ -22,6 +24,14 @@ def get_plugin(directory):
raise ValueError("No files were found.")
+@pytest.fixture
+def get_hold():
+ if DOWNLOAD_HOLD_PATH.is_file():
+ return DOWNLOAD_HOLD_PATH
+ else:
+ raise ValueError("No files were found.")
+
+
def generate_random_label():
label_length = 8
random_label = "".join(
@@ -34,15 +44,6 @@ def generate_random_number():
return random.randint(1, 20_000_000_000_000_00_000)
-def pay_with_thread(rpc, bolt11):
- LOGGER = logging.getLogger(__name__)
- try:
- rpc.dev_pay(bolt11, dev_use_shadow=False)
- except Exception as e:
- LOGGER.info(f"holdinvoice: Error paying payment hash:{e}")
- pass
-
-
def update_config_file_option(lightning_dir, option_name, option_value):
with open(lightning_dir + "/config", "r") as file:
lines = file.readlines()
diff --git a/tests/uv.lock b/tests/uv.lock
index 6c3395a..7baa4f7 100644
--- a/tests/uv.lock
+++ b/tests/uv.lock
@@ -451,62 +451,62 @@ wheels = [
[[package]]
name = "cryptography"
-version = "46.0.7"
+version = "48.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/47/93/ac8f3d5ff04d54bc814e961a43ae5b0b146154c89c61b47bb07557679b18/cryptography-46.0.7.tar.gz", hash = "sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5", size = 750652, upload-time = "2026-04-08T01:57:54.692Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/9f/a9/db8f313fdcd85d767d4973515e1db101f9c71f95fced83233de224673757/cryptography-48.0.0.tar.gz", hash = "sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920", size = 832984, upload-time = "2026-05-04T22:59:38.133Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/0b/5d/4a8f770695d73be252331e60e526291e3df0c9b27556a90a6b47bccca4c2/cryptography-46.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4", size = 7179869, upload-time = "2026-04-08T01:56:17.157Z" },
- { url = "https://files.pythonhosted.org/packages/5f/45/6d80dc379b0bbc1f9d1e429f42e4cb9e1d319c7a8201beffd967c516ea01/cryptography-46.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325", size = 4275492, upload-time = "2026-04-08T01:56:19.36Z" },
- { url = "https://files.pythonhosted.org/packages/4a/9a/1765afe9f572e239c3469f2cb429f3ba7b31878c893b246b4b2994ffe2fe/cryptography-46.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308", size = 4426670, upload-time = "2026-04-08T01:56:21.415Z" },
- { url = "https://files.pythonhosted.org/packages/8f/3e/af9246aaf23cd4ee060699adab1e47ced3f5f7e7a8ffdd339f817b446462/cryptography-46.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77", size = 4280275, upload-time = "2026-04-08T01:56:23.539Z" },
- { url = "https://files.pythonhosted.org/packages/0f/54/6bbbfc5efe86f9d71041827b793c24811a017c6ac0fd12883e4caa86b8ed/cryptography-46.0.7-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1", size = 4928402, upload-time = "2026-04-08T01:56:25.624Z" },
- { url = "https://files.pythonhosted.org/packages/2d/cf/054b9d8220f81509939599c8bdbc0c408dbd2bdd41688616a20731371fe0/cryptography-46.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef", size = 4459985, upload-time = "2026-04-08T01:56:27.309Z" },
- { url = "https://files.pythonhosted.org/packages/f9/46/4e4e9c6040fb01c7467d47217d2f882daddeb8828f7df800cb806d8a2288/cryptography-46.0.7-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de", size = 3990652, upload-time = "2026-04-08T01:56:29.095Z" },
- { url = "https://files.pythonhosted.org/packages/36/5f/313586c3be5a2fbe87e4c9a254207b860155a8e1f3cca99f9910008e7d08/cryptography-46.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83", size = 4279805, upload-time = "2026-04-08T01:56:30.928Z" },
- { url = "https://files.pythonhosted.org/packages/69/33/60dfc4595f334a2082749673386a4d05e4f0cf4df8248e63b2c3437585f2/cryptography-46.0.7-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb", size = 4892883, upload-time = "2026-04-08T01:56:32.614Z" },
- { url = "https://files.pythonhosted.org/packages/c7/0b/333ddab4270c4f5b972f980adef4faa66951a4aaf646ca067af597f15563/cryptography-46.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b", size = 4459756, upload-time = "2026-04-08T01:56:34.306Z" },
- { url = "https://files.pythonhosted.org/packages/d2/14/633913398b43b75f1234834170947957c6b623d1701ffc7a9600da907e89/cryptography-46.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85", size = 4410244, upload-time = "2026-04-08T01:56:35.977Z" },
- { url = "https://files.pythonhosted.org/packages/10/f2/19ceb3b3dc14009373432af0c13f46aa08e3ce334ec6eff13492e1812ccd/cryptography-46.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e", size = 4674868, upload-time = "2026-04-08T01:56:38.034Z" },
- { url = "https://files.pythonhosted.org/packages/1a/bb/a5c213c19ee94b15dfccc48f363738633a493812687f5567addbcbba9f6f/cryptography-46.0.7-cp311-abi3-win32.whl", hash = "sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457", size = 3026504, upload-time = "2026-04-08T01:56:39.666Z" },
- { url = "https://files.pythonhosted.org/packages/2b/02/7788f9fefa1d060ca68717c3901ae7fffa21ee087a90b7f23c7a603c32ae/cryptography-46.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b", size = 3488363, upload-time = "2026-04-08T01:56:41.893Z" },
- { url = "https://files.pythonhosted.org/packages/7b/56/15619b210e689c5403bb0540e4cb7dbf11a6bf42e483b7644e471a2812b3/cryptography-46.0.7-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842", size = 7119671, upload-time = "2026-04-08T01:56:44Z" },
- { url = "https://files.pythonhosted.org/packages/74/66/e3ce040721b0b5599e175ba91ab08884c75928fbeb74597dd10ef13505d2/cryptography-46.0.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c", size = 4268551, upload-time = "2026-04-08T01:56:46.071Z" },
- { url = "https://files.pythonhosted.org/packages/03/11/5e395f961d6868269835dee1bafec6a1ac176505a167f68b7d8818431068/cryptography-46.0.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902", size = 4408887, upload-time = "2026-04-08T01:56:47.718Z" },
- { url = "https://files.pythonhosted.org/packages/40/53/8ed1cf4c3b9c8e611e7122fb56f1c32d09e1fff0f1d77e78d9ff7c82653e/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d", size = 4271354, upload-time = "2026-04-08T01:56:49.312Z" },
- { url = "https://files.pythonhosted.org/packages/50/46/cf71e26025c2e767c5609162c866a78e8a2915bbcfa408b7ca495c6140c4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022", size = 4905845, upload-time = "2026-04-08T01:56:50.916Z" },
- { url = "https://files.pythonhosted.org/packages/c0/ea/01276740375bac6249d0a971ebdf6b4dc9ead0ee0a34ef3b5a88c1a9b0d4/cryptography-46.0.7-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce", size = 4444641, upload-time = "2026-04-08T01:56:52.882Z" },
- { url = "https://files.pythonhosted.org/packages/3d/4c/7d258f169ae71230f25d9f3d06caabcff8c3baf0978e2b7d65e0acac3827/cryptography-46.0.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f", size = 3967749, upload-time = "2026-04-08T01:56:54.597Z" },
- { url = "https://files.pythonhosted.org/packages/b5/2a/2ea0767cad19e71b3530e4cad9605d0b5e338b6a1e72c37c9c1ceb86c333/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99", size = 4270942, upload-time = "2026-04-08T01:56:56.416Z" },
- { url = "https://files.pythonhosted.org/packages/41/3d/fe14df95a83319af25717677e956567a105bb6ab25641acaa093db79975d/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1", size = 4871079, upload-time = "2026-04-08T01:56:58.31Z" },
- { url = "https://files.pythonhosted.org/packages/9c/59/4a479e0f36f8f378d397f4eab4c850b4ffb79a2f0d58704b8fa0703ddc11/cryptography-46.0.7-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2", size = 4443999, upload-time = "2026-04-08T01:57:00.508Z" },
- { url = "https://files.pythonhosted.org/packages/28/17/b59a741645822ec6d04732b43c5d35e4ef58be7bfa84a81e5ae6f05a1d33/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e", size = 4399191, upload-time = "2026-04-08T01:57:02.654Z" },
- { url = "https://files.pythonhosted.org/packages/59/6a/bb2e166d6d0e0955f1e9ff70f10ec4b2824c9cfcdb4da772c7dd69cc7d80/cryptography-46.0.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee", size = 4655782, upload-time = "2026-04-08T01:57:04.592Z" },
- { url = "https://files.pythonhosted.org/packages/95/b6/3da51d48415bcb63b00dc17c2eff3a651b7c4fed484308d0f19b30e8cb2c/cryptography-46.0.7-cp314-cp314t-win32.whl", hash = "sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298", size = 3002227, upload-time = "2026-04-08T01:57:06.91Z" },
- { url = "https://files.pythonhosted.org/packages/32/a8/9f0e4ed57ec9cebe506e58db11ae472972ecb0c659e4d52bbaee80ca340a/cryptography-46.0.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb", size = 3475332, upload-time = "2026-04-08T01:57:08.807Z" },
- { url = "https://files.pythonhosted.org/packages/a7/7f/cd42fc3614386bc0c12f0cb3c4ae1fc2bbca5c9662dfed031514911d513d/cryptography-46.0.7-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4", size = 7165618, upload-time = "2026-04-08T01:57:10.645Z" },
- { url = "https://files.pythonhosted.org/packages/a5/d0/36a49f0262d2319139d2829f773f1b97ef8aef7f97e6e5bd21455e5a8fb5/cryptography-46.0.7-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7", size = 4270628, upload-time = "2026-04-08T01:57:12.885Z" },
- { url = "https://files.pythonhosted.org/packages/8a/6c/1a42450f464dda6ffbe578a911f773e54dd48c10f9895a23a7e88b3e7db5/cryptography-46.0.7-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832", size = 4415405, upload-time = "2026-04-08T01:57:14.923Z" },
- { url = "https://files.pythonhosted.org/packages/9a/92/4ed714dbe93a066dc1f4b4581a464d2d7dbec9046f7c8b7016f5286329e2/cryptography-46.0.7-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163", size = 4272715, upload-time = "2026-04-08T01:57:16.638Z" },
- { url = "https://files.pythonhosted.org/packages/b7/e6/a26b84096eddd51494bba19111f8fffe976f6a09f132706f8f1bf03f51f7/cryptography-46.0.7-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2", size = 4918400, upload-time = "2026-04-08T01:57:19.021Z" },
- { url = "https://files.pythonhosted.org/packages/c7/08/ffd537b605568a148543ac3c2b239708ae0bd635064bab41359252ef88ed/cryptography-46.0.7-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067", size = 4450634, upload-time = "2026-04-08T01:57:21.185Z" },
- { url = "https://files.pythonhosted.org/packages/16/01/0cd51dd86ab5b9befe0d031e276510491976c3a80e9f6e31810cce46c4ad/cryptography-46.0.7-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0", size = 3985233, upload-time = "2026-04-08T01:57:22.862Z" },
- { url = "https://files.pythonhosted.org/packages/92/49/819d6ed3a7d9349c2939f81b500a738cb733ab62fbecdbc1e38e83d45e12/cryptography-46.0.7-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba", size = 4271955, upload-time = "2026-04-08T01:57:24.814Z" },
- { url = "https://files.pythonhosted.org/packages/80/07/ad9b3c56ebb95ed2473d46df0847357e01583f4c52a85754d1a55e29e4d0/cryptography-46.0.7-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006", size = 4879888, upload-time = "2026-04-08T01:57:26.88Z" },
- { url = "https://files.pythonhosted.org/packages/b8/c7/201d3d58f30c4c2bdbe9b03844c291feb77c20511cc3586daf7edc12a47b/cryptography-46.0.7-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0", size = 4449961, upload-time = "2026-04-08T01:57:29.068Z" },
- { url = "https://files.pythonhosted.org/packages/a5/ef/649750cbf96f3033c3c976e112265c33906f8e462291a33d77f90356548c/cryptography-46.0.7-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85", size = 4401696, upload-time = "2026-04-08T01:57:31.029Z" },
- { url = "https://files.pythonhosted.org/packages/41/52/a8908dcb1a389a459a29008c29966c1d552588d4ae6d43f3a1a4512e0ebe/cryptography-46.0.7-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e", size = 4664256, upload-time = "2026-04-08T01:57:33.144Z" },
- { url = "https://files.pythonhosted.org/packages/4b/fa/f0ab06238e899cc3fb332623f337a7364f36f4bb3f2534c2bb95a35b132c/cryptography-46.0.7-cp38-abi3-win32.whl", hash = "sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246", size = 3013001, upload-time = "2026-04-08T01:57:34.933Z" },
- { url = "https://files.pythonhosted.org/packages/d2/f1/00ce3bde3ca542d1acd8f8cfa38e446840945aa6363f9b74746394b14127/cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3", size = 3472985, upload-time = "2026-04-08T01:57:36.714Z" },
- { url = "https://files.pythonhosted.org/packages/63/0c/dca8abb64e7ca4f6b2978769f6fea5ad06686a190cec381f0a796fdcaaba/cryptography-46.0.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fc9ab8856ae6cf7c9358430e49b368f3108f050031442eaeb6b9d87e4dcf4e4f", size = 3476879, upload-time = "2026-04-08T01:57:38.664Z" },
- { url = "https://files.pythonhosted.org/packages/3a/ea/075aac6a84b7c271578d81a2f9968acb6e273002408729f2ddff517fed4a/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d3b99c535a9de0adced13d159c5a9cf65c325601aa30f4be08afd680643e9c15", size = 4219700, upload-time = "2026-04-08T01:57:40.625Z" },
- { url = "https://files.pythonhosted.org/packages/6c/7b/1c55db7242b5e5612b29fc7a630e91ee7a6e3c8e7bf5406d22e206875fbd/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d02c738dacda7dc2a74d1b2b3177042009d5cab7c7079db74afc19e56ca1b455", size = 4385982, upload-time = "2026-04-08T01:57:42.725Z" },
- { url = "https://files.pythonhosted.org/packages/cb/da/9870eec4b69c63ef5925bf7d8342b7e13bc2ee3d47791461c4e49ca212f4/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:04959522f938493042d595a736e7dbdff6eb6cc2339c11465b3ff89343b65f65", size = 4219115, upload-time = "2026-04-08T01:57:44.939Z" },
- { url = "https://files.pythonhosted.org/packages/f4/72/05aa5832b82dd341969e9a734d1812a6aadb088d9eb6f0430fc337cc5a8f/cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:3986ac1dee6def53797289999eabe84798ad7817f3e97779b5061a95b0ee4968", size = 4385479, upload-time = "2026-04-08T01:57:46.86Z" },
- { url = "https://files.pythonhosted.org/packages/20/2a/1b016902351a523aa2bd446b50a5bc1175d7a7d1cf90fe2ef904f9b84ebc/cryptography-46.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:258514877e15963bd43b558917bc9f54cf7cf866c38aa576ebf47a77ddbc43a4", size = 3412829, upload-time = "2026-04-08T01:57:48.874Z" },
+ { url = "https://files.pythonhosted.org/packages/df/3d/01f6dd9190170a5a241e0e98c2d04be3664a9e6f5b9b872cde63aff1c3dd/cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6", size = 8001587, upload-time = "2026-05-04T22:57:36.803Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/6e/e90527eef33f309beb811cf7c982c3aeffcce8e3edb178baa4ca3ae4a6fa/cryptography-48.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c", size = 4690433, upload-time = "2026-05-04T22:57:40.373Z" },
+ { url = "https://files.pythonhosted.org/packages/90/04/673510ed51ddff56575f306cf1617d80411ee76831ccd3097599140efdfe/cryptography-48.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3", size = 4710620, upload-time = "2026-05-04T22:57:42.935Z" },
+ { url = "https://files.pythonhosted.org/packages/14/d5/e9c4ef932c8d800490c34d8bd589d64a31d5890e27ec9e9ad532be893294/cryptography-48.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5", size = 4696283, upload-time = "2026-05-04T22:57:45.294Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/29/174b9dfb60b12d59ecfc6cfa04bc88c21b42a54f01b8aae09bb6e51e4c7f/cryptography-48.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c", size = 5296573, upload-time = "2026-05-04T22:57:47.933Z" },
+ { url = "https://files.pythonhosted.org/packages/95/38/0d29a6fd7d0d1373f0c0c88a04ba20e359b257753ac497564cd660fc1d55/cryptography-48.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f", size = 4743677, upload-time = "2026-05-04T22:57:50.067Z" },
+ { url = "https://files.pythonhosted.org/packages/30/be/eef653013d5c63b6a490529e0316f9ac14a37602965d4903efed1399f32b/cryptography-48.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25", size = 4330808, upload-time = "2026-05-04T22:57:52.301Z" },
+ { url = "https://files.pythonhosted.org/packages/84/9e/500463e87abb7a0a0f9f256ec21123ecde0a7b5541a15e840ea54551fd81/cryptography-48.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602", size = 4695941, upload-time = "2026-05-04T22:57:54.603Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/dc/7303087450c2ec9e7fbb750e17c2abfbc658f23cbd0e54009509b7cc4091/cryptography-48.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c", size = 5252579, upload-time = "2026-05-04T22:57:57.207Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/c0/7101d3b7215edcdc90c45da544961fd8ed2d6448f77577460fa75a8443f7/cryptography-48.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5", size = 4743326, upload-time = "2026-05-04T22:57:59.535Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/d8/5b833bad13016f562ab9d063d68199a4bd121d18458e439515601d3357ec/cryptography-48.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321", size = 4826672, upload-time = "2026-05-04T22:58:01.996Z" },
+ { url = "https://files.pythonhosted.org/packages/98/e1/7074eb8bf3c135558c73fc2bcf0f5633f912e6fb87e868a55c454080ef09/cryptography-48.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74", size = 4972574, upload-time = "2026-05-04T22:58:03.968Z" },
+ { url = "https://files.pythonhosted.org/packages/04/70/e5a1b41d325f797f39427aa44ef8baf0be500065ab6d8e10369d850d4a4f/cryptography-48.0.0-cp311-abi3-win32.whl", hash = "sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4", size = 3294868, upload-time = "2026-05-04T22:58:06.467Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/ac/8ac51b4a5fc5932eb7ee5c517ba7dc8cd834f0048962b6b352f00f41ebf9/cryptography-48.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7", size = 3817107, upload-time = "2026-05-04T22:58:08.845Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/84/70e3feea9feea87fd7cbe77efb2712ae1e3e6edf10749dc6e95f4e60e455/cryptography-48.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec", size = 7986556, upload-time = "2026-05-04T22:58:11.172Z" },
+ { url = "https://files.pythonhosted.org/packages/89/6e/18e07a618bb5442ba10cf4df16e99c071365528aa570dfcb8c02e25a303b/cryptography-48.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18", size = 4684776, upload-time = "2026-05-04T22:58:13.712Z" },
+ { url = "https://files.pythonhosted.org/packages/be/6a/4ea3b4c6c6759794d5ee2103c304a5076dc4b19ae1f9fe47dba439e159e9/cryptography-48.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20", size = 4698121, upload-time = "2026-05-04T22:58:16.448Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/59/6ff6ad6cae03bb887da2a5860b2c9805f8dac969ef01ce563336c49bd1d1/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff", size = 4690042, upload-time = "2026-05-04T22:58:18.544Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/b4/fc334ed8cfd705aca282fe4d8f5ae64a8e0f74932e9feecb344610cf6e4d/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c", size = 5282526, upload-time = "2026-05-04T22:58:20.75Z" },
+ { url = "https://files.pythonhosted.org/packages/11/08/9f8c5386cc4cd90d8255c7cdd0f5baf459a08502a09de30dc51f553d38dc/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db", size = 4733116, upload-time = "2026-05-04T22:58:23.627Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/77/99307d7574045699f8805aa500fa0fb83422d115b5400a064ddd306d7750/cryptography-48.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741", size = 4316030, upload-time = "2026-05-04T22:58:25.581Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/36/a608b98337af3cb2aff4818e406649d30572b7031918b04c87d979495348/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166", size = 4689640, upload-time = "2026-05-04T22:58:27.747Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/a6/825010a291b4438aecc1f568bc428189fc1175515223632477c07dc0a6df/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336", size = 5237657, upload-time = "2026-05-04T22:58:29.848Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/09/4e76a09b4caa29aad535ddc806f5d4c5d01885bd978bd984fbc6ca032cae/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057", size = 4732362, upload-time = "2026-05-04T22:58:32.009Z" },
+ { url = "https://files.pythonhosted.org/packages/18/78/444fa04a77d0cb95f417dda20d450e13c56ba8e5220fc892a1658f44f882/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae", size = 4819580, upload-time = "2026-05-04T22:58:34.254Z" },
+ { url = "https://files.pythonhosted.org/packages/38/85/ea67067c70a1fd4be2c63d35eeed82658023021affccc7b17705f8527dd2/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c", size = 4963283, upload-time = "2026-05-04T22:58:36.376Z" },
+ { url = "https://files.pythonhosted.org/packages/75/54/cc6d0f3deac3e81c7f847e8a189a12b6cdd65059b43dad25d4316abd849a/cryptography-48.0.0-cp314-cp314t-win32.whl", hash = "sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f", size = 3270954, upload-time = "2026-05-04T22:58:38.791Z" },
+ { url = "https://files.pythonhosted.org/packages/49/67/cc947e288c0758a4e5473d1dcb743037ab7785541265a969240b8885441a/cryptography-48.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12", size = 3797313, upload-time = "2026-05-04T22:58:40.746Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86", size = 7983482, upload-time = "2026-05-04T22:58:43.769Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/ac/f5b5995b87770c693e2596559ffafe195b4033a57f14a82268a2842953f3/cryptography-48.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e", size = 4683266, upload-time = "2026-05-04T22:58:46.064Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/c6/8b14f67e18338fbc4adb76f66c001f5c3610b3e2d1837f268f47a347dbbb/cryptography-48.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f", size = 4696228, upload-time = "2026-05-04T22:58:48.22Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/73/f808fbae9514bd91b47875b003f13e284c8c6bdfd904b7944e803937eec1/cryptography-48.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7", size = 4689097, upload-time = "2026-05-04T22:58:50.9Z" },
+ { url = "https://files.pythonhosted.org/packages/93/01/d86632d7d28db8ae83221995752eeb6639ffb374c2d22955648cf8d52797/cryptography-48.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832", size = 5283582, upload-time = "2026-05-04T22:58:53.017Z" },
+ { url = "https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c", size = 4730479, upload-time = "2026-05-04T22:58:55.611Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/af/99a582b1b1641ff5911ac559beb45097cf79efd4ead4657f578ef1af2d47/cryptography-48.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a", size = 4326481, upload-time = "2026-05-04T22:58:57.607Z" },
+ { url = "https://files.pythonhosted.org/packages/90/ee/89aa26a06ef0a7d7611788ffd571a7c50e368cc6a4d5eef8b4884e866edb/cryptography-48.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a", size = 4688713, upload-time = "2026-05-04T22:59:00.077Z" },
+ { url = "https://files.pythonhosted.org/packages/70/ba/bcb1b0bb7a33d4c7c0c4d4c7874b4a62ae4f56113a5f4baefa362dfb1f0f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a", size = 5238165, upload-time = "2026-05-04T22:59:02.317Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/70/ca4003b1ce5ca3dc3186ada51908c8a9b9ff7d5cab83cc0d43ee14ec144f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239", size = 4729947, upload-time = "2026-05-04T22:59:05.255Z" },
+ { url = "https://files.pythonhosted.org/packages/44/a0/4ec7cf774207905aef1a8d11c3750d5a1db805eb380ee4e16df317870128/cryptography-48.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c", size = 4822059, upload-time = "2026-05-04T22:59:07.802Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/75/a2e55f99c16fcac7b5d6c1eb19ad8e00799854d6be5ca845f9259eae1681/cryptography-48.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4", size = 4960575, upload-time = "2026-05-04T22:59:09.851Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/23/6e6f32143ab5d8b36ca848a502c4bcd477ae75b9e1677e3530d669062578/cryptography-48.0.0-cp39-abi3-win32.whl", hash = "sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd", size = 3279117, upload-time = "2026-05-04T22:59:12.019Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" },
+ { url = "https://files.pythonhosted.org/packages/be/d2/024b5e06be9d44cb021fb0e1a03d34d63989cf56a0fe62f3dfbab695b9b4/cryptography-48.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855", size = 3950391, upload-time = "2026-05-04T22:59:17.415Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/17/3861e17c56fa0fd37491a14a8673fdb77c57fc5693cafe745ea8b06dba75/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b", size = 4637126, upload-time = "2026-05-04T22:59:20.197Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/0a/7e226dbff530f21480727eb764973a7bff2b912f8e15cd4f129e71b56d1d/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13", size = 4667270, upload-time = "2026-05-04T22:59:22.647Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/f2/5a72274ca9f1b2a8b44a662ee0bf1b435909deb473d6f97bcd035bcdbc71/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb", size = 4636797, upload-time = "2026-05-04T22:59:24.912Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/e1/48cedb2fe63626e91ded1edad159e2a4fb8b6906c4425eb7749673077ce7/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355", size = 4666800, upload-time = "2026-05-04T22:59:27.474Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/ca/7e8365deec19afb2b2c7be7c1c0aa8f99633b54e90c570999acda93260fc/cryptography-48.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a", size = 3739536, upload-time = "2026-05-04T22:59:29.61Z" },
]
[[package]]
@@ -558,11 +558,11 @@ wheels = [
[[package]]
name = "idna"
-version = "3.13"
+version = "3.14"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/05/b1/efac073e0c297ecf2fb33c346989a529d4e19164f1759102dee5953ee17e/idna-3.14.tar.gz", hash = "sha256:466d810d7a2cc1022bea9b037c39728d51ae7dad40d480fc9b7d7ecf98ba8ee3", size = 198272, upload-time = "2026-05-10T20:32:15.935Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/3c/3f62dee257eb3d6b2c1ef2a09d36d9793c7111156a73b5654d2c2305e5ce/idna-3.14-py3-none-any.whl", hash = "sha256:e677eaf072e290f7b725f9acf0b3a2bd55f9fd6f7c70abe5f0e34823d0accf69", size = 72184, upload-time = "2026-05-10T20:32:14.295Z" },
]
[[package]]
@@ -759,11 +759,11 @@ wheels = [
[[package]]
name = "packaging"
-version = "26.1"
+version = "26.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" },
+ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" },
]
[[package]]
@@ -895,20 +895,20 @@ wheels = [
[[package]]
name = "pyln-client"
-version = "26.4"
+version = "26.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyln-bolt7" },
{ name = "pyln-proto" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/8a/14/0faf6b8b04f368629897a010357d3b8d21c8a800b972b433a358caebe32b/pyln_client-26.4.tar.gz", hash = "sha256:e696076fcf1329ee22198097b8139a096f653cbbfc6a03e471455ca6f5d68a46", size = 92160, upload-time = "2026-04-20T04:58:12.666Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/28/fe/e1e19c59dd7520dec2de992f0a3da6292db24162c9830be279616a7b8810/pyln_client-26.4.1.tar.gz", hash = "sha256:26dfb21ac39c61b7ab7a40db18798b002f3f19a179ff2ec40374a9419d032050", size = 92170, upload-time = "2026-04-24T04:53:08.46Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/60/41/f67df5064b4b9d258fb30e96e1d3ca8f0395c7c0098b24091dde6238fb8e/pyln_client-26.4-py3-none-any.whl", hash = "sha256:d5470e1ecccc1b6e46e39658c1019c62868c5aed4a0203635052803ddedcce2e", size = 37655, upload-time = "2026-04-20T04:58:11.429Z" },
+ { url = "https://files.pythonhosted.org/packages/65/90/d3b5e11f85cf076b1011a1ea6031ced3745abf451e47a1697216e1ea7c29/pyln_client-26.4.1-py3-none-any.whl", hash = "sha256:a9afba9b117818023bf4567a94c34633e9f2e89f0e1ca11e433329a2c678a685", size = 37673, upload-time = "2026-04-24T04:53:07.187Z" },
]
[[package]]
name = "pyln-proto"
-version = "26.4"
+version = "26.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "base58" },
@@ -917,14 +917,14 @@ dependencies = [
{ name = "cryptography" },
{ name = "pysocks" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/0d/35/5d30332fcaa8d77be87290c5534d45c48822310611ae6ea6d3e48c242ded/pyln_proto-26.4.tar.gz", hash = "sha256:dde9e243c7bf6fbcf7904e0dbd18c4f05dc17e668b074bfab090a7376e3de6cf", size = 44861, upload-time = "2026-04-20T04:58:09.361Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/8c/4b/c8d676ad84d6066553b203668c0e36f45cfae0a4d7140eb88aed6d65b38b/pyln_proto-26.4.1.tar.gz", hash = "sha256:d73f261bacc06a6a613dcece05fc429699b740a4673f24dffb7c41bd3542d589", size = 44864, upload-time = "2026-04-24T04:53:10.196Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/0b/c9/8a34960e1e9550f87697d1f05208d9cc916c14419f18f2d6013801079fc1/pyln_proto-26.4-py3-none-any.whl", hash = "sha256:97772d285aa0d0c8a1545577aeef8821e08d59676f63ae760d270e1b3015bc9d", size = 31811, upload-time = "2026-04-20T04:58:08.369Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/f1/6541b6cd8a017d3505fcb49885d3f01b8e6bb09e40db18e686edb9edeb99/pyln_proto-26.4.1-py3-none-any.whl", hash = "sha256:b5d10d5e69cf3debd9b289e2ffa49713fca6c349a71cb0eaf9e733024f15b3da", size = 31833, upload-time = "2026-04-24T04:53:08.686Z" },
]
[[package]]
name = "pyln-testing"
-version = "26.4"
+version = "26.4.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cheroot" },
@@ -939,9 +939,9 @@ dependencies = [
{ name = "python-bitcoinlib" },
{ name = "requests" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/17/7e/275f0416e30faa3093ad31703f3d8702dc06569164a185813b23672ba6d9/pyln_testing-26.4.tar.gz", hash = "sha256:cca1f4fec65f12bfda809674ea7c231285a96ef0b8bc2c69ef4919f1b465d2ae", size = 52609, upload-time = "2026-04-20T04:58:07.746Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/64/73/d969847564591fe16633b11bf8be9f8184ccd885e367acee171e9fd6d2d8/pyln_testing-26.4.1.tar.gz", hash = "sha256:0a40d66ec2f0840df95bdbc4845c214aede01e9d7a89a422f5b6b00a89e63690", size = 52617, upload-time = "2026-04-24T04:53:10.904Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/4f/c4/3cb55bf86a2499510a24b310897903efafce847869eb1ec1c7b67b7fcfa4/pyln_testing-26.4-py3-none-any.whl", hash = "sha256:ccb7641bbbb1b6b650f1b8238aacf04d7ebeea944ebd2855a901e25d18846804", size = 54365, upload-time = "2026-04-20T04:58:06.793Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/ad/603ff35f7b60bcc6cf364a101c58a73887132063f0773767108946361ed2/pyln_testing-26.4.1-py3-none-any.whl", hash = "sha256:dd0e9d8a865593ddc9a14ef43e9aaec0fe0d348ce9ec2fcd23807a35c98c9e8c", size = 54381, upload-time = "2026-04-24T04:53:09.599Z" },
]
[[package]]
@@ -1035,7 +1035,7 @@ wheels = [
[[package]]
name = "requests"
-version = "2.33.1"
+version = "2.34.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
@@ -1043,9 +1043,9 @@ dependencies = [
{ name = "idna" },
{ name = "urllib3" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/43/b8/7a707d60fea4c49094e40262cc0e2ca6c768cca21587e34d3f705afec47e/requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a", size = 142436, upload-time = "2026-05-11T19:29:51.717Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/e6/e300fce5fe83c30520607a015dabd985df3251e188d234bfe9492e17a389/requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60", size = 73021, upload-time = "2026-05-11T19:29:49.923Z" },
]
[[package]]
@@ -1273,11 +1273,11 @@ wheels = [
[[package]]
name = "urllib3"
-version = "2.6.3"
+version = "2.7.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
]
[[package]]
From 5c5f49de294a2b8b0c91840a0771a225b49cac20 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Mon, 5 Jan 2026 14:49:33 +0100
Subject: [PATCH 15/56] wait for hold certs to be generated
---
src/main.rs | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/main.rs b/src/main.rs
index 957f9c8..59e5eed 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -268,6 +268,14 @@ async fn check_hold_support(plugin: Plugin) -> Result<(), anyhow::E
cert_dir.to_str().unwrap()
);
+ let max_retries = 10;
+ let mut retries = 0;
+ while retries < max_retries && !do_certificates_exist(&cert_dir) {
+ log::debug!("Hold certificates incomplete. Waiting...");
+ time::sleep(Duration::from_millis(500)).await;
+ retries += 1;
+ }
+
let ca_cert = tokio::fs::read(cert_dir.join("ca.pem")).await?;
let client_cert = tokio::fs::read(cert_dir.join("client.pem")).await?;
let client_key = tokio::fs::read(cert_dir.join("client-key.pem")).await?;
@@ -289,3 +297,12 @@ async fn check_hold_support(plugin: Plugin) -> Result<(), anyhow::E
Ok(())
}
+
+fn do_certificates_exist(cert_dir: &Path) -> bool {
+ let required_files = ["client.pem", "client-key.pem", "ca.pem"];
+
+ required_files.iter().all(|file| {
+ let path = cert_dir.join(file);
+ path.exists() && path.metadata().map(|m| m.len() > 0).unwrap_or(false)
+ })
+}
From 78ac7cac0536b16e8cab130e5a763beed42bd11b Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Tue, 3 Feb 2026 22:33:00 +0100
Subject: [PATCH 16/56] prepare for nostr 0.45
---
Cargo.lock | 90 +++++++++-----------------------
Cargo.toml | 11 +++-
src/main.rs | 4 +-
src/nwc.rs | 109 +++++++++++++++++++++------------------
src/nwc_balance.rs | 2 +-
src/nwc_hold.rs | 4 +-
src/nwc_info.rs | 2 +-
src/nwc_invoice.rs | 6 +--
src/nwc_keysend.rs | 2 +-
src/nwc_lookups.rs | 2 +-
src/nwc_notifications.rs | 18 +++----
src/nwc_pay.rs | 2 +-
src/parse.rs | 3 +-
src/rpc.rs | 4 +-
src/structs.rs | 7 +--
src/tasks.rs | 2 +-
src/util.rs | 2 +-
tests/test_cln-nip47.py | 19 +++----
18 files changed, 132 insertions(+), 157 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 55e0cde..696565d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -86,12 +86,6 @@ dependencies = [
"web-sys",
]
-[[package]]
-name = "atomic-destructor"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4"
-
[[package]]
name = "atomic-waker"
version = "1.1.2"
@@ -215,6 +209,12 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "btreecap"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6160c957d8aa33d0a8ba1dbab98e3cb57023ad9374c501441e88559f99e6c4c9"
+
[[package]]
name = "bumpalo"
version = "3.20.2"
@@ -294,9 +294,11 @@ dependencies = [
"anyhow",
"cln-plugin",
"cln-rpc",
+ "futures",
"hex",
"log",
"log-panics",
+ "nostr",
"nostr-sdk",
"parking_lot",
"prost",
@@ -363,7 +365,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
- "rand_core 0.6.4",
"typenum",
]
@@ -561,10 +562,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
- "js-sys",
"libc",
"wasi",
- "wasm-bindgen",
]
[[package]]
@@ -911,9 +910,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
dependencies = [
"cfg-if",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
]
[[package]]
@@ -1043,9 +1039,8 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "nostr"
-version = "0.44.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3aa5e3b6a278ed061835fe1ee293b71641e6bf8b401cfe4e1834bbf4ef0a34e1"
+version = "0.44.1"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
dependencies = [
"aes",
"base64",
@@ -1055,9 +1050,10 @@ dependencies = [
"cbc",
"chacha20",
"chacha20poly1305",
- "getrandom 0.2.17",
"hex",
"instant",
+ "once_cell",
+ "rand",
"scrypt",
"secp256k1",
"serde",
@@ -1069,9 +1065,9 @@ dependencies = [
[[package]]
name = "nostr-database"
version = "0.44.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7462c9d8ae5ef6a28d66a192d399ad2530f1f2130b13186296dbb11bdef5b3d1"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
dependencies = [
+ "btreecap",
"lru",
"nostr",
"tokio",
@@ -1080,42 +1076,27 @@ dependencies = [
[[package]]
name = "nostr-gossip"
version = "0.44.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ade30de16869618919c6b5efc8258f47b654a98b51541eb77f85e8ec5e3c83a6"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
dependencies = [
"nostr",
]
-[[package]]
-name = "nostr-relay-pool"
-version = "0.44.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b1073ccfbaea5549fb914a9d52c68dab2aecda61535e5143dd73e95445a804b"
-dependencies = [
- "async-utility",
- "async-wsocket",
- "atomic-destructor",
- "hex",
- "lru",
- "negentropy",
- "nostr",
- "nostr-database",
- "tokio",
- "tracing",
-]
-
[[package]]
name = "nostr-sdk"
version = "0.44.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "471732576710e779b64f04c55e3f8b5292f865fea228436daf19694f0bf70393"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
dependencies = [
"async-utility",
+ "async-wsocket",
+ "futures",
+ "hex",
+ "lru",
+ "negentropy",
"nostr",
"nostr-database",
"nostr-gossip",
- "nostr-relay-pool",
"tokio",
+ "tokio-stream",
"tracing",
]
@@ -1369,37 +1350,16 @@ version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
-[[package]]
-name = "rand"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
-dependencies = [
- "libc",
- "rand_chacha 0.3.1",
- "rand_core 0.6.4",
-]
-
[[package]]
name = "rand"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
dependencies = [
- "rand_chacha 0.9.0",
+ "rand_chacha",
"rand_core 0.9.5",
]
-[[package]]
-name = "rand_chacha"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
-dependencies = [
- "ppv-lite86",
- "rand_core 0.6.4",
-]
-
[[package]]
name = "rand_chacha"
version = "0.9.0"
@@ -1568,7 +1528,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113"
dependencies = [
"bitcoin_hashes",
- "rand 0.8.6",
"secp256k1-sys",
"serde",
]
@@ -1874,6 +1833,7 @@ dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
+ "tokio-util",
]
[[package]]
@@ -2083,7 +2043,7 @@ dependencies = [
"http",
"httparse",
"log",
- "rand 0.9.4",
+ "rand",
"rustls",
"rustls-pki-types",
"sha1",
diff --git a/Cargo.toml b/Cargo.toml
index c5b1a1c..d7be3be 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,8 +18,15 @@ cln-plugin = "0.6"
# cln-plugin = { path = "../lightning/plugins/", version = "^0.6" }
parking_lot = "0.12"
-# nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", rev = "f7122f5", features = ["nip47", "nip04", "nip44"]}
-nostr-sdk = { version = "0.44", features = ["nip47", "nip04", "nip44"] }
+nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", rev = "bf3028eb11b4e324c0c660b4e4c83348cdcc00c2" }
+nostr = { git = "https://github.com/rust-nostr/nostr.git", rev = "bf3028eb11b4e324c0c660b4e4c83348cdcc00c2", features = [
+ "nip47",
+ "nip04",
+ "nip44",
+] }
+# nostr-sdk = { version = "0.44", features = ["nip47", "nip04", "nip44"] }
+
+futures = "0.3"
uuid = { version = "1", features = ["v4"] }
diff --git a/src/main.rs b/src/main.rs
index 59e5eed..bb172bf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,7 +11,7 @@ use cln_plugin::{
options::{ConfigOption, DefaultBooleanConfigOption, StringArrayConfigOption},
};
use cln_rpc::{ClnRpc, model::requests::ListdatastoreRequest};
-use nostr_sdk::nips::nip47;
+use nostr::nips::nip47;
use nwc::run_nwc;
use nwc_notifications::{payment_received_handler, payment_sent_handler};
use parse::read_startup_options;
@@ -23,7 +23,7 @@ use tonic::transport::{Certificate, ClientTlsConfig, Endpoint, Identity};
use util::{load_nwc_store, update_nwc_store};
use crate::{
- hold::{hold_client::HoldClient, InvoiceState, ListRequest},
+ hold::{InvoiceState, ListRequest, hold_client::HoldClient},
nwc_notifications::holdinvoice_accepted_handler,
};
diff --git a/src/nwc.rs b/src/nwc.rs
index 247aedc..423e0cf 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -2,24 +2,27 @@ use std::{borrow::Cow, time::Duration};
use anyhow::anyhow;
use cln_plugin::Plugin;
-use nostr_sdk::{
+use futures::StreamExt;
+use nostr::{
Alphabet,
- Client,
Event,
EventBuilder,
EventId,
+ Filter,
Keys,
+ Kind,
PublicKey,
- RelayPoolNotification,
- RelayStatus,
SecretKey,
SignerError,
SingleLetterTag,
+ Tag,
TagKind,
Timestamp,
- client,
nips::{nip04, nip44, nip47},
- nostr::{Filter, Kind, Tag},
+};
+use nostr_sdk::{
+ client::{self, Client, ClientNotification, Error},
+ relay::RelayStatus,
};
use tokio::{sync::oneshot, time};
@@ -46,16 +49,16 @@ pub async fn run_nwc(
plugin: Plugin,
label: String,
nwc_store: NwcStore,
-) -> Result<(), client::Error> {
+) -> Result<(), Error> {
let (method_capabilities, _) = build_capabilities(is_read_only_nwc(&nwc_store), &plugin);
let wallet_keys = Keys::new(
SecretKey::from_hex(&nwc_store.walletkey)
- .map_err(|e| client::Error::Signer(SignerError::backend(e)))?,
+ .map_err(|e| Error::Signer(SignerError::backend(e)))?,
);
let client_pubkey = Keys::new(nwc_store.uri.secret.clone()).public_key();
- let nostr_client = Client::new(wallet_keys.clone());
+ let nostr_client = Client::builder().signer(wallet_keys.clone()).build();
log::debug!("relay_count:{}", nwc_store.uri.relays.len());
@@ -73,9 +76,9 @@ pub async fn run_nwc(
let label_clone = label.clone();
tokio::spawn(async move {
loop {
- nostr_client_clone.connect().await;
nostr_client_clone
- .wait_for_connection(Duration::from_secs(30))
+ .connect()
+ .and_wait(Duration::from_secs(30))
.await;
let relays = nostr_client_clone.relays().await;
if relays.is_empty() {
@@ -115,37 +118,41 @@ pub async fn run_nwc(
.author(client_pubkey)
.since(Timestamp::now() - STARTUP_DELAY - 1);
- if let Err(e) = nostr_client_clone.subscribe(filter, None).await {
- log::warn!("Could not subscribe to nwc events! {e}");
- nostr_client_clone.disconnect().await;
- time::sleep(Duration::from_secs(5)).await;
- continue;
+ let mut notifications = nostr_client_clone.notifications();
+
+ match nostr_client_clone.subscribe(filter).await {
+ Ok(o) => {
+ if o.success.is_empty() {
+ log::warn!("Could not subscribe to any relay!");
+ nostr_client_clone.disconnect().await;
+ time::sleep(Duration::from_secs(5)).await;
+ continue;
+ }
+ }
+ Err(e) => {
+ log::warn!("Error subscribing to relays: {e}");
+ nostr_client_clone.disconnect().await;
+ time::sleep(Duration::from_secs(5)).await;
+ continue;
+ }
}
- let client_clone_handler = nostr_client_clone.clone();
- match nostr_client_clone
- .handle_notifications(|notification| {
- let client_clone_handler = client_clone_handler.clone();
- let plugin_clone = plugin_clone.clone();
- let label_clone = label_clone.clone();
- let wallet_keys_clone = wallet_keys.clone();
- nwc_request_handler(
- notification,
- client_clone_handler,
- plugin_clone,
- label_clone,
- wallet_keys_clone,
- client_pubkey,
- )
- })
+ while let Some(notification) = notifications.next().await {
+ if let Err(e) = nwc_request_handler(
+ notification,
+ &nostr_client_clone,
+ &plugin_clone,
+ &label_clone,
+ &wallet_keys,
+ client_pubkey,
+ )
.await
- {
- Ok(()) => {
- log::info!("NWC handler for `{label_clone}` stopped");
- break;
- }
- Err(e) => log::warn!("NWC handler for `{label_clone}` had an error: {e}"),
+ {
+ log::warn!("NWC handler for `{label_clone}` had an error: {e}");
+ };
}
+
+ {};
}
});
@@ -226,29 +233,29 @@ pub fn stop_nwc_budget_job(plugin: &Plugin, label: &String) {
}
async fn nwc_request_handler(
- notification: RelayPoolNotification,
- nostr_client: client::Client,
- plugin: Plugin,
- label: String,
- wallet_keys: Keys,
+ notification: ClientNotification,
+ nostr_client: &client::Client,
+ plugin: &Plugin,
+ label: &String,
+ wallet_keys: &Keys,
client_pubkey: PublicKey,
-) -> Result> {
+) -> Result<(), Box> {
let (relay_url, subscription_id, event) = match notification {
- RelayPoolNotification::Event {
+ ClientNotification::Event {
relay_url,
subscription_id,
event,
} => (relay_url, subscription_id, event),
- RelayPoolNotification::Message {
+ ClientNotification::Message {
relay_url: _,
message: _,
- } => return Ok(false),
- RelayPoolNotification::Shutdown => return Ok(true),
+ } => return Ok(()),
+ ClientNotification::Shutdown => return Ok(()),
};
if let Some(expi) = event.tags.expiration() {
if *expi < Timestamp::now() {
- return Ok(false);
+ return Ok(());
}
}
log::debug!("relay_url:{relay_url} subscription_id:{subscription_id} {event:?}");
@@ -264,7 +271,7 @@ async fn nwc_request_handler(
multi_pay_invoice(plugin.clone(), multi_pay_invoice_request, &label).await
}
nip47::RequestParams::PayKeysend(pay_keysend_request) => {
- pay_keysend_response(plugin, pay_keysend_request, &label).await
+ pay_keysend_response(plugin.clone(), pay_keysend_request, &label).await
}
nip47::RequestParams::MultiPayKeysend(multi_pay_keysend_request) => {
multi_pay_keysend(plugin.clone(), multi_pay_keysend_request, &label).await
@@ -330,7 +337,7 @@ async fn nwc_request_handler(
log::debug!("SENT RESPONSE {response_event:?}");
}
- Ok(false)
+ Ok(())
}
fn check_nip44_support(event: &Event) -> bool {
diff --git a/src/nwc_balance.rs b/src/nwc_balance.rs
index c29b343..1c3c1ea 100644
--- a/src/nwc_balance.rs
+++ b/src/nwc_balance.rs
@@ -1,6 +1,6 @@
use cln_plugin::Plugin;
use cln_rpc::{model::requests::ListpeerchannelsRequest, primitives::ChannelState};
-use nostr_sdk::nips::nip47;
+use nostr::nips::nip47;
use crate::{structs::PluginState, util::load_nwc_store};
diff --git a/src/nwc_hold.rs b/src/nwc_hold.rs
index a706bde..d3b0d8f 100644
--- a/src/nwc_hold.rs
+++ b/src/nwc_hold.rs
@@ -2,7 +2,7 @@ use std::str::FromStr;
use cln_plugin::Plugin;
use cln_rpc::primitives::Sha256;
-use nostr_sdk::{nips::nip47, Timestamp};
+use nostr::{nips::nip47, Timestamp};
use crate::{
hold::{invoice_request::Description, CancelRequest, InvoiceRequest, SettleRequest},
@@ -93,7 +93,7 @@ async fn make_hold_invoice(
payment_hash: payment_hash.clone(),
amount_msat: params.amount,
expiry: Some(expiry),
- min_final_cltv_expiry: params.cltv_expiry_delta.map(u64::from),
+ min_final_cltv_expiry: params.min_cltv_expiry_delta.map(u64::from),
routing_hints: Vec::new(),
description,
};
diff --git a/src/nwc_info.rs b/src/nwc_info.rs
index d3930e2..27e196a 100644
--- a/src/nwc_info.rs
+++ b/src/nwc_info.rs
@@ -1,6 +1,6 @@
use cln_plugin::Plugin;
use cln_rpc::model::requests::GetinfoRequest;
-use nostr_sdk::nips::nip47;
+use nostr::nips::nip47;
use crate::{
structs::PluginState,
diff --git a/src/nwc_invoice.rs b/src/nwc_invoice.rs
index 654a0b0..f521673 100644
--- a/src/nwc_invoice.rs
+++ b/src/nwc_invoice.rs
@@ -5,7 +5,7 @@ use cln_rpc::{
model::requests::InvoiceRequest,
primitives::{Amount, AmountOrAny, Sha256},
};
-use nostr_sdk::nips::nip47;
+use nostr::{nips::nip47, types::Timestamp};
use uuid::Uuid;
use crate::structs::PluginState;
@@ -94,8 +94,8 @@ async fn make_invoice(
description_hash: params.description_hash,
preimage: None,
amount: Some(params.amount),
- created_at: Some(nostr_sdk::nostr::Timestamp::now()),
- expires_at: Some(nostr_sdk::nostr::Timestamp::from_secs(o.expires_at)),
+ created_at: Some(Timestamp::now()),
+ expires_at: Some(Timestamp::from_secs(o.expires_at)),
}),
Err(e) => Err(nip47::NIP47Error {
code: nip47::ErrorCode::Internal,
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index 477db88..fbbe1a0 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -5,7 +5,7 @@ use cln_rpc::{
model::requests::KeysendRequest,
primitives::{Amount, PublicKey, TlvEntry, TlvStream},
};
-use nostr_sdk::nips::nip47;
+use nostr::nips::nip47;
use tokio::time;
use crate::{
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index b15a54b..cef844c 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -15,7 +15,7 @@ use cln_rpc::{
primitives::Sha256,
ClnRpc,
};
-use nostr_sdk::{nips::nip47, Timestamp};
+use nostr::{nips::nip47, Timestamp};
use crate::{
hold::{self, list_request::Constraint, ListRequest},
diff --git a/src/nwc_notifications.rs b/src/nwc_notifications.rs
index e86afaf..8f77a99 100644
--- a/src/nwc_notifications.rs
+++ b/src/nwc_notifications.rs
@@ -3,6 +3,7 @@ use std::str::FromStr;
use anyhow::anyhow;
use cln_plugin::Plugin;
use cln_rpc::{
+ ClnRpc,
model::{
requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest, ListpeerchannelsRequest},
responses::{
@@ -14,19 +15,14 @@ use cln_rpc::{
},
},
primitives::Sha256,
- ClnRpc,
-};
-use nostr_sdk::{
- nips::nip47,
- nostr::{key::PublicKey, EventBuilder, Kind, Tag},
- Client,
- Timestamp,
};
+use nostr::{EventBuilder, Kind, Tag, Timestamp, key::PublicKey, nips::nip47};
+use nostr_sdk::client::Client;
use crate::{
- hold::{list_request::Constraint, InvoiceState, ListRequest, TrackRequest},
- structs::{PluginState, NOT_INV_ERR},
OPT_NOTIFICATIONS,
+ hold::{InvoiceState, ListRequest, TrackRequest, list_request::Constraint},
+ structs::{NOT_INV_ERR, PluginState},
};
pub async fn payment_received_handler(
@@ -341,7 +337,7 @@ async fn send_notification(
client: &Client,
client_pubkey: &PublicKey,
) -> Result<(), anyhow::Error> {
- let signer = client.signer().await?;
+ let signer = client.signer().unwrap().clone();
log::debug!("NOTIFICATION: {notification}");
let content_encrypted_nip04 = signer.nip04_encrypt(client_pubkey, notification).await?;
let event_nip04 = EventBuilder::new(Kind::from_u16(23196), content_encrypted_nip04)
@@ -460,6 +456,7 @@ pub async fn holdinvoice_accepted_handler(
.call_typed(&ListpeerchannelsRequest {
id: None,
short_channel_id: None,
+ channel_id: None,
})
.await?
.channels;
@@ -497,6 +494,7 @@ pub async fn holdinvoice_accepted_handler(
expires_at,
settle_deadline: lowest_htlc_expiry,
metadata: None,
+ state: Some(nip47::TransactionState::Accepted),
},
),
};
diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs
index 73b64a0..87b2733 100644
--- a/src/nwc_pay.rs
+++ b/src/nwc_pay.rs
@@ -10,7 +10,7 @@ use cln_rpc::{
ClnRpc,
RpcError,
};
-use nostr_sdk::nips::nip47;
+use nostr::nips::nip47;
use tokio::time;
use crate::{
diff --git a/src/parse.rs b/src/parse.rs
index 7c32966..b1dffed 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -3,6 +3,7 @@ use std::path::Path;
use anyhow::anyhow;
use cln_plugin::ConfiguredPlugin;
use cln_rpc::{model::requests::GetinfoRequest, ClnRpc};
+use nostr::types::RelayUrl;
use crate::{
structs::{PluginState, TimeUnit},
@@ -37,7 +38,7 @@ pub async fn read_startup_options(
config.my_cln_version = version;
for relay in relays_str {
log::debug!("RELAY:{relay}");
- config.relays.push(nostr_sdk::RelayUrl::parse(&relay)?);
+ config.relays.push(RelayUrl::parse(&relay)?);
}
Ok(())
}
diff --git a/src/rpc.rs b/src/rpc.rs
index 272d483..06387aa 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -6,7 +6,7 @@ use cln_rpc::model::requests::{
DeldatastoreRequest,
ListdatastoreRequest,
};
-use nostr_sdk::{Keys, SecretKey, Timestamp, nips::nip47::NostrWalletConnectURI};
+use nostr::{Keys, SecretKey, Timestamp, nips::nip47::NostrWalletConnectUri};
use serde_json::json;
use crate::{
@@ -29,7 +29,7 @@ pub async fn nwc_create(
let wallet_keys = Keys::generate();
let client_keys = Keys::generate();
- let uri = NostrWalletConnectURI::new(
+ let uri = NostrWalletConnectUri::new(
wallet_keys.public_key(),
config.relays.clone(),
client_keys.secret_key().clone(),
diff --git a/src/structs.rs b/src/structs.rs
index 8964bfd..e7eea09 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,7 +1,8 @@
use std::{collections::HashMap, path::PathBuf, str::FromStr, sync::Arc};
use cln_rpc::ClnRpc;
-use nostr_sdk::{client, nips::nip47, nostr};
+use nostr::{nips::nip47::NostrWalletConnectUri, types::RelayUrl};
+use nostr_sdk::client;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use tokio::sync::oneshot;
@@ -33,7 +34,7 @@ impl PluginState {
#[derive(Clone, Debug)]
pub struct Config {
- pub relays: Vec,
+ pub relays: Vec,
pub my_cln_version: String,
}
impl Config {
@@ -77,7 +78,7 @@ pub struct BudgetIntervalConfig {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NwcStore {
- pub uri: nip47::NostrWalletConnectURI,
+ pub uri: NostrWalletConnectUri,
pub walletkey: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub budget_msat: Option,
diff --git a/src/tasks.rs b/src/tasks.rs
index 2437e4a..e46ed40 100644
--- a/src/tasks.rs
+++ b/src/tasks.rs
@@ -3,7 +3,7 @@ use std::{path::Path, time::Duration};
use anyhow::anyhow;
use cln_plugin::Plugin;
use cln_rpc::ClnRpc;
-use nostr_sdk::Timestamp;
+use nostr::types::Timestamp;
use tokio::{sync::oneshot, time};
use crate::{
diff --git a/src/util.rs b/src/util.rs
index 6956d9e..6d769ad 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -4,7 +4,7 @@ use cln_rpc::{
model::requests::{DatastoreMode, DatastoreRequest, ListdatastoreRequest},
ClnRpc,
};
-use nostr_sdk::nips::nip47;
+use nostr::nips::nip47;
use crate::{
structs::{NwcStore, PluginState},
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
index 3642c96..6caba46 100755
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -1484,6 +1484,7 @@ async def test_hold_invoice(
"important-plugin": get_hold,
"nip47-relays": url,
"may_reconnect": True,
+ "broken_log": r"Relay receiver exited with error",
},
],
)
@@ -1672,10 +1673,10 @@ async def test_hold_invoice(
)
wait_for(
- lambda: l1.rpc.call("listpays", {"payment_hash": payment_hash})["pays"][0][
- "status"
- ]
- == "complete"
+ lambda: (
+ l1.rpc.call("listpays", {"payment_hash": payment_hash})["pays"][0]["status"]
+ == "complete"
+ )
)
preimage = secrets.token_hex(32)
@@ -1687,7 +1688,7 @@ async def test_hold_invoice(
"payment_hash": payment_hash,
"description": "cancel_hold",
"expiry": 1000,
- "cltv_expiry_delta": 200,
+ "min_cltv_expiry_delta": 200,
},
}
content = json.dumps(content)
@@ -1815,10 +1816,10 @@ async def test_hold_invoice(
assert invoice2_decoded["min_final_cltv_expiry"] == 200
wait_for(
- lambda: l1.rpc.call("listpays", {"payment_hash": payment_hash})["pays"][0][
- "status"
- ]
- == "failed"
+ lambda: (
+ l1.rpc.call("listpays", {"payment_hash": payment_hash})["pays"][0]["status"]
+ == "failed"
+ )
)
nwc = Nwc(uri)
From 6690c9d49d120b3368de7d51d8f293a383d5a533 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Tue, 24 Feb 2026 16:18:46 +0100
Subject: [PATCH 17/56] removed multi_* methods
---
CHANGELOG.md | 3 +
README.md | 2 -
src/main.rs | 8 +-
src/nwc.rs | 30 +++----
src/nwc_keysend.rs | 36 +-------
src/nwc_lookups.rs | 4 +-
src/nwc_pay.rs | 35 --------
tests/test_cln-nip47.py | 192 +---------------------------------------
8 files changed, 23 insertions(+), 287 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91f2c5e..f0fd46e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@
- holdinvoice methods: ``make_hold_invoice``, ``cancel_hold_invoice``, ``settle_hold_invoice``
- holdinvoice notification: ``hold_invoice_accepted``
+### Removed
+- ``multi_pay_invoice`` and ``multi_pay_keysend``, they were removed from the spec
+
## [0.1.9] 2026-04-23
### Fixed
diff --git a/README.md b/README.md
index 02fbb10..eb2425b 100644
--- a/README.md
+++ b/README.md
@@ -132,9 +132,7 @@ For methods or notifications related to holdinvoices you need v0.3.2+ of [hold](
## Supported NWC methods
* ``pay_invoice``
-* ``multi_pay_invoice``
* ``pay_keysend`` (no ``preimage`` in request allowed since CLN only supports generating it itself)
-* ``multi_pay_keysend`` (no ``preimage`` in request allowed since CLN only supports generating it itself)
* ``make_invoice``
* ``lookup_invoice``
* ``list_transactions``
diff --git a/src/main.rs b/src/main.rs
index bb172bf..dd70aad 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -64,12 +64,8 @@ pub const WALLET_READ_METHODS: [nip47::Method; 5] = [
nip47::Method::GetBalance,
nip47::Method::GetInfo,
];
-pub const WALLET_PAY_METHODS: [nip47::Method; 4] = [
- nip47::Method::PayInvoice,
- nip47::Method::MultiPayInvoice,
- nip47::Method::PayKeysend,
- nip47::Method::MultiPayKeysend,
-];
+pub const WALLET_PAY_METHODS: [nip47::Method; 2] =
+ [nip47::Method::PayInvoice, nip47::Method::PayKeysend];
pub const WALLET_HOLD_METHODS: [nip47::Method; 3] = [
nip47::Method::MakeHoldInvoice,
nip47::Method::CancelHoldInvoice,
diff --git a/src/nwc.rs b/src/nwc.rs
index 423e0cf..16c00c8 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -37,9 +37,9 @@ use crate::{
},
nwc_info::get_info_response,
nwc_invoice::make_invoice_response,
- nwc_keysend::{multi_pay_keysend, pay_keysend_response},
+ nwc_keysend::pay_keysend_response,
nwc_lookups::{list_transactions_response, lookup_invoice_response},
- nwc_pay::{multi_pay_invoice, pay_invoice_response},
+ nwc_pay::pay_invoice_response,
structs::{NwcStore, PluginState},
tasks::budget_task,
util::{build_capabilities, build_notifications_vec, is_read_only_nwc},
@@ -236,7 +236,7 @@ async fn nwc_request_handler(
notification: ClientNotification,
nostr_client: &client::Client,
plugin: &Plugin,
- label: &String,
+ label: &str,
wallet_keys: &Keys,
client_pubkey: PublicKey,
) -> Result<(), Box> {
@@ -249,8 +249,8 @@ async fn nwc_request_handler(
ClientNotification::Message {
relay_url: _,
message: _,
- } => return Ok(()),
- ClientNotification::Shutdown => return Ok(()),
+ }
+ | ClientNotification::Shutdown => return Ok(()),
};
if let Some(expi) = event.tags.expiration() {
@@ -261,20 +261,14 @@ async fn nwc_request_handler(
log::debug!("relay_url:{relay_url} subscription_id:{subscription_id} {event:?}");
let mut use_nip44 = check_nip44_support(&event);
- let request = decrypt_request(&event.content, &wallet_keys, &client_pubkey, &mut use_nip44)?;
+ let request = decrypt_request(&event.content, wallet_keys, &client_pubkey, &mut use_nip44)?;
let responses = match request.params {
nip47::RequestParams::PayInvoice(pay_invoice_request) => {
- pay_invoice_response(plugin.clone(), pay_invoice_request, &label).await
- }
- nip47::RequestParams::MultiPayInvoice(multi_pay_invoice_request) => {
- multi_pay_invoice(plugin.clone(), multi_pay_invoice_request, &label).await
+ pay_invoice_response(plugin.clone(), pay_invoice_request, label).await
}
nip47::RequestParams::PayKeysend(pay_keysend_request) => {
- pay_keysend_response(plugin.clone(), pay_keysend_request, &label).await
- }
- nip47::RequestParams::MultiPayKeysend(multi_pay_keysend_request) => {
- multi_pay_keysend(plugin.clone(), multi_pay_keysend_request, &label).await
+ pay_keysend_response(plugin.clone(), pay_keysend_request, label).await
}
nip47::RequestParams::MakeInvoice(make_invoice_request) => {
make_invoice_response(plugin.clone(), make_invoice_request).await
@@ -285,8 +279,8 @@ async fn nwc_request_handler(
nip47::RequestParams::ListTransactions(list_transactions_request) => {
list_transactions_response(plugin.clone(), list_transactions_request).await
}
- nip47::RequestParams::GetBalance => get_balance_response(plugin.clone(), &label).await,
- nip47::RequestParams::GetInfo => get_info_response(plugin.clone(), &label).await,
+ nip47::RequestParams::GetBalance => get_balance_response(plugin.clone(), label).await,
+ nip47::RequestParams::GetInfo => get_info_response(plugin.clone(), label).await,
nip47::RequestParams::MakeHoldInvoice(make_hold_invoice_request) => {
make_hold_invoice_response(plugin.clone(), make_hold_invoice_request).await
}
@@ -299,7 +293,7 @@ async fn nwc_request_handler(
};
for (response, id) in responses {
let content =
- match encrypt_response_content(&response, &wallet_keys, &client_pubkey, use_nip44) {
+ match encrypt_response_content(&response, wallet_keys, &client_pubkey, use_nip44) {
Ok(o) => o,
Err(e) => {
log::warn!("{e}");
@@ -308,7 +302,7 @@ async fn nwc_request_handler(
};
let response_event =
- match build_response_event(event.id, content, &wallet_keys, client_pubkey, id) {
+ match build_response_event(event.id, content, wallet_keys, client_pubkey, id) {
Ok(o) => o,
Err(e) => {
log::warn!("Error signing reponse event! {e}");
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index fbbe1a0..bc49ec2 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -1,4 +1,4 @@
-use std::{str::FromStr, time::Duration};
+use std::str::FromStr;
use cln_plugin::Plugin;
use cln_rpc::{
@@ -6,7 +6,6 @@ use cln_rpc::{
primitives::{Amount, PublicKey, TlvEntry, TlvStream},
};
use nostr::nips::nip47;
-use tokio::time;
use crate::{
structs::PluginState,
@@ -149,36 +148,3 @@ async fn pay_keysend(
},
}
}
-
-pub async fn multi_pay_keysend(
- plugin: Plugin,
- params: nip47::MultiPayKeysendRequest,
- label: &str,
-) -> Vec<(nip47::Response, Option)> {
- let mut responses = Vec::new();
- for pay in params.keysends {
- let result = pay_keysend(plugin.clone(), pay.clone(), label).await;
- let id = if let Some(i) = pay.id { i } else { pay.pubkey };
- let response_res = match result {
- Ok(resp) => (
- nip47::Response {
- result_type: nip47::Method::MultiPayKeysend,
- error: None,
- result: Some(nip47::ResponseResult::MultiPayKeysend(resp)),
- },
- Some(id),
- ),
- Err(e) => (
- nip47::Response {
- result_type: nip47::Method::MultiPayKeysend,
- error: Some(e),
- result: None,
- },
- Some(id),
- ),
- };
- responses.push(response_res);
- time::sleep(Duration::from_millis(100)).await;
- }
- responses
-}
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index cef844c..5b5090c 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -275,7 +275,7 @@ async fn lookup_invoice(
let state = match hold_invoice.state() {
hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
- hold::InvoiceState::Accepted => nip47::TransactionState::Pending, // TODO ACCEPTED STATE
+ hold::InvoiceState::Accepted => nip47::TransactionState::Accepted,
hold::InvoiceState::Paid => nip47::TransactionState::Settled,
hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
};
@@ -462,7 +462,7 @@ async fn list_transactions(
let state = match hold_invoice.state() {
hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
- hold::InvoiceState::Accepted => nip47::TransactionState::Pending, // TODO: ACCEPTED STATE
+ hold::InvoiceState::Accepted => nip47::TransactionState::Accepted,
hold::InvoiceState::Paid => nip47::TransactionState::Settled,
hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
};
diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs
index 87b2733..a313720 100644
--- a/src/nwc_pay.rs
+++ b/src/nwc_pay.rs
@@ -1,5 +1,3 @@
-use std::time::Duration;
-
use cln_plugin::Plugin;
use cln_rpc::{
model::{
@@ -11,7 +9,6 @@ use cln_rpc::{
RpcError,
};
use nostr::nips::nip47;
-use tokio::time;
use crate::{
structs::{NwcStore, PluginState, NOT_INV_ERR},
@@ -380,35 +377,3 @@ async fn pay_with_legacy_full(
)
.await
}
-
-pub async fn multi_pay_invoice(
- plugin: Plugin,
- params: nip47::MultiPayInvoiceRequest,
- label: &str,
-) -> Vec<(nip47::Response, Option)> {
- let mut responses = Vec::new();
- for pay in params.invoices {
- let result = pay_invoice(plugin.clone(), pay, label).await;
- let response_res = match result {
- Ok((resp, id)) => (
- nip47::Response {
- result_type: nip47::Method::MultiPayInvoice,
- error: None,
- result: Some(nip47::ResponseResult::MultiPayInvoice(resp)),
- },
- id,
- ),
- Err((e, id)) => (
- nip47::Response {
- result_type: nip47::Method::MultiPayInvoice,
- error: Some(e),
- result: None,
- },
- id,
- ),
- };
- responses.push(response_res);
- time::sleep(Duration::from_millis(100)).await;
- }
- responses
-}
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
index 6caba46..03210a9 100755
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -15,7 +15,6 @@ from pyln.testing.utils import RpcError, wait_for, TIMEOUT
from util import generate_random_label, get_plugin, get_hold # noqa: F401
from nostr_sdk import (
- Alphabet,
Client,
RelayUrl,
EventBuilder,
@@ -34,7 +33,6 @@ from nostr_sdk import (
Nwc,
PayInvoiceRequest,
PayKeysendRequest,
- SingleLetterTag,
Tag,
TagKind,
Method,
@@ -223,9 +221,7 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
Method.GET_BALANCE,
Method.GET_INFO,
Method.PAY_INVOICE,
- Method.MULTI_PAY_INVOICE,
Method.PAY_KEYSEND,
- Method.MULTI_PAY_KEYSEND,
]
assert get_info.network == "regtest"
assert get_info.notifications == ["payment_received", "payment_sent"]
@@ -255,9 +251,7 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
Method.GET_BALANCE,
Method.GET_INFO,
Method.PAY_INVOICE,
- Method.MULTI_PAY_INVOICE,
Method.PAY_KEYSEND,
- Method.MULTI_PAY_KEYSEND,
]
assert get_info.network == "regtest"
assert get_info.notifications == []
@@ -265,7 +259,7 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
assert (
info_event.content()
- == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice multi_pay_invoice pay_keysend multi_pay_keysend"
+ == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice pay_keysend"
)
assert (
info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
@@ -450,99 +444,6 @@ async def test_pay_keysend(nostr_relay, node_factory, get_plugin): # noqa: F811
)
-@pytest.mark.asyncio
-async def test_multi_keysend(nostr_relay, node_factory, get_plugin): # noqa: F811
- url = nostr_relay
- l1, l2, l3 = node_factory.line_graph(
- 3,
- wait_for_announce=True,
- opts=[
- {
- "log-level": "debug",
- "plugin": get_plugin,
- "nip47-relays": url,
- "broken_log": r"Relay receiver exited with error|Connection failed",
- },
- {"log-level": "debug"},
- {"log-level": "debug"},
- ],
- )
- uri_res = l1.rpc.call("nip47-create", ["test1", 3010])
- uri_str = uri_res["uri"]
- client_pubkey = PublicKey.parse(uri_res["clientkey_public"])
- LOGGER.info(uri_str)
- uri = NostrWalletConnectUri.parse(uri_str)
- content = {
- "method": "multi_pay_keysend",
- "params": {
- "keysends": [
- {"id": "4da52c32a1", "pubkey": l2.info["id"], "amount": 1000},
- {"id": "3da52c32a1", "pubkey": l3.info["id"], "amount": 2000},
- ],
- },
- }
- content = json.dumps(content)
- signer = NostrSigner.keys(Keys(uri.secret()))
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
- event = (
- await EventBuilder(Kind(23194), encrypted_content)
- .tags([Tag.public_key(uri.public_key())])
- .sign(signer)
- )
- client = Client(signer)
- await client.add_relay(RelayUrl.parse(url))
- await client.connect()
- (responses1, _res) = await fetch_event_responses(
- client, client_pubkey, 23195, client.send_event(event), 2
- )
-
- content = {
- "method": "multi_pay_keysend",
- "params": {
- "keysends": [
- {"id": "5da52c32a1", "pubkey": l2.info["id"], "amount": 5},
- {"id": "2da52c32a1", "pubkey": l3.info["id"], "amount": 5},
- ],
- },
- }
- content = json.dumps(content)
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
- event = (
- await EventBuilder(Kind(23194), encrypted_content)
- .tags([Tag.public_key(uri.public_key())])
- .sign(signer)
- )
- (responses2, _res) = await fetch_event_responses(
- client, client_pubkey, 23195, client.send_event(event), 2
- )
-
- reponses = responses1 + responses2
-
- error_events = []
- success_events = []
- for event in reponses:
- LOGGER.info(event)
- assert event.tags().find(
- TagKind.SINGLE_LETTER(SingleLetterTag.lowercase(Alphabet.D))
- )
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
- content = json.loads(content)
- if "result" in content and content["result"] is not None:
- success_events.append(content)
- if "error" in content and content["error"] is not None:
- error_events.append(content)
-
- assert len(success_events) == 3
- assert len(error_events) == 1
- for content in success_events:
- assert content["result_type"] == "multi_pay_keysend"
- assert content["result"]["preimage"] is not None
- for content in error_events:
- assert content["result_type"] == "multi_pay_keysend"
- assert content["error"]["message"] == "Payment exceeds budget!"
- assert content["error"]["code"] == "QUOTA_EXCEEDED"
-
-
@pytest.mark.asyncio
async def test_lookup_invoice(nostr_relay, node_factory, get_plugin): # noqa: F811
url = nostr_relay
@@ -1104,91 +1005,6 @@ async def test_pay_invoice(nostr_relay, node_factory, get_plugin): # noqa: F811
)
-@pytest.mark.asyncio
-async def test_multi_pay(nostr_relay, node_factory, get_plugin): # noqa: F811
- url = nostr_relay
- l1, l2 = node_factory.line_graph(
- 2,
- wait_for_announce=True,
- opts=[
- {
- "log-level": "debug",
- "plugin": get_plugin,
- "nip47-relays": url,
- "broken_log": r"Relay receiver exited with error|Connection failed",
- },
- {"log-level": "debug"},
- ],
- )
- uri_res = l1.rpc.call("nip47-create", ["test1", 30000])
- uri_str = uri_res["uri"]
- client_pubkey = PublicKey.parse(uri_res["clientkey_public"])
- LOGGER.info(uri_str)
- uri = NostrWalletConnectUri.parse(uri_str)
- invoice1 = l2.rpc.call(
- "invoice",
- {"label": generate_random_label(), "description": "test1", "amount_msat": 3000},
- )
- invoice2 = l2.rpc.call(
- "invoice",
- {"label": generate_random_label(), "description": "test2", "amount_msat": 4000},
- )
- invoice3 = l2.rpc.call(
- "invoice",
- {
- "label": generate_random_label(),
- "description": "test3",
- "amount_msat": 23001,
- },
- )
- content = {
- "method": "multi_pay_invoice",
- "params": {
- "invoices": [
- {"id": "4da52c32a1", "invoice": invoice1["bolt11"]},
- {"id": "3da52c32a1", "invoice": invoice2["bolt11"]},
- {"id": "af3g2k2o11", "invoice": invoice3["bolt11"]},
- ],
- },
- }
- content = json.dumps(content)
- signer = NostrSigner.keys(Keys(uri.secret()))
- encrypted_content = await signer.nip44_encrypt(uri.public_key(), content)
- request_event = (
- await EventBuilder(Kind(23194), encrypted_content)
- .tags([Tag.public_key(uri.public_key())])
- .sign(signer)
- )
- client = Client(signer)
- await client.add_relay(RelayUrl.parse(url))
- await client.connect()
-
- (responses, _res) = await fetch_event_responses(
- client, client_pubkey, 23195, client.send_event(request_event), 3
- )
-
- success_pays = []
- error_pays = []
- for response in responses:
- d_tag = response.tags().find(
- TagKind.SINGLE_LETTER(SingleLetterTag.lowercase(Alphabet.D))
- )
- content = await signer.nip44_decrypt(uri.public_key(), response.content())
- content = json.loads(content)
- assert content["result_type"] == "multi_pay_invoice"
- if "result" in content and content["result"] is not None:
- assert d_tag is not None
- assert content["result"]["preimage"] is not None
- success_pays.append(content)
- if "error" in content and content["error"] is not None:
- assert d_tag.content() == "af3g2k2o11"
- assert content["error"]["code"] == "QUOTA_EXCEEDED"
- assert content["error"]["message"] == "Payment exceeds budget!"
- error_pays.append(content)
- assert len(success_pays) == 2
- assert len(error_pays) == 1
-
-
@pytest.mark.asyncio
async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
url = nostr_relay
@@ -1408,16 +1224,14 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
Method.GET_BALANCE,
Method.GET_INFO,
Method.PAY_INVOICE,
- Method.MULTI_PAY_INVOICE,
Method.PAY_KEYSEND,
- Method.MULTI_PAY_KEYSEND,
]
info_event = await fetch_info_event(client, uri)
assert (
info_event.content()
- == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice multi_pay_invoice pay_keysend multi_pay_keysend notifications"
+ == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice pay_keysend notifications"
)
assert (
info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
@@ -1974,7 +1788,7 @@ async def test_hold_invoice(
info_event = await fetch_info_event(client, uri)
assert (
info_event.content()
- == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice multi_pay_invoice pay_keysend multi_pay_keysend make_hold_invoice cancel_hold_invoice settle_hold_invoice notifications"
+ == "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice pay_keysend make_hold_invoice cancel_hold_invoice settle_hold_invoice notifications"
)
assert (
info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
From b16db826931185890c5bd870b0b19bd951612501 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Tue, 12 May 2026 20:17:57 +0200
Subject: [PATCH 18/56] more nostr v0.45 prep
---
Cargo.lock | 83 +++++++++++++++++++++++++++-------------
Cargo.toml | 4 +-
src/nwc.rs | 32 ++++++----------
src/nwc_notifications.rs | 4 +-
4 files changed, 71 insertions(+), 52 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 696565d..81fd1eb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -69,11 +69,9 @@ dependencies = [
[[package]]
name = "async-wsocket"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c92385c7c8b3eb2de1b78aeca225212e4c9a69a78b802832759b108681a5069"
+version = "0.13.1"
+source = "git+https://github.com/shadowylab/async-wsocket?rev=0fed6c9c6aec7393ee0e9cf3933d76914ab427d3#0fed6c9c6aec7393ee0e9cf3933d76914ab427d3"
dependencies = [
- "async-utility",
"futures",
"futures-util",
"js-sys",
@@ -83,6 +81,7 @@ dependencies = [
"tokio-tungstenite",
"url",
"wasm-bindgen",
+ "wasm-bindgen-futures",
"web-sys",
]
@@ -221,6 +220,12 @@ version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
[[package]]
name = "bytes"
version = "1.11.1"
@@ -418,6 +423,16 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "faster-hex"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7223ae2d2f179b803433d9c830478527e92b8117eab39460edae7f1614d9fb73"
+dependencies = [
+ "heapless",
+ "serde",
+]
+
[[package]]
name = "fastrand"
version = "2.4.1"
@@ -622,6 +637,15 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "hash32"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
+dependencies = [
+ "byteorder",
+]
+
[[package]]
name = "hashbrown"
version = "0.15.5"
@@ -637,6 +661,16 @@ version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
+[[package]]
+name = "heapless"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
+dependencies = [
+ "hash32",
+ "stable_deref_trait",
+]
+
[[package]]
name = "heck"
version = "0.5.0"
@@ -903,15 +937,6 @@ dependencies = [
"generic-array",
]
-[[package]]
-name = "instant"
-version = "0.1.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
-dependencies = [
- "cfg-if",
-]
-
[[package]]
name = "itertools"
version = "0.14.0"
@@ -1040,7 +1065,7 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "nostr"
version = "0.44.1"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
dependencies = [
"aes",
"base64",
@@ -1050,33 +1075,30 @@ dependencies = [
"cbc",
"chacha20",
"chacha20poly1305",
- "hex",
- "instant",
- "once_cell",
+ "faster-hex",
"rand",
"scrypt",
"secp256k1",
"serde",
"serde_json",
"unicode-normalization",
+ "universal-time",
"url",
]
[[package]]
name = "nostr-database"
version = "0.44.0"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
dependencies = [
"btreecap",
- "lru",
"nostr",
- "tokio",
]
[[package]]
name = "nostr-gossip"
version = "0.44.0"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
dependencies = [
"nostr",
]
@@ -1084,12 +1106,12 @@ dependencies = [
[[package]]
name = "nostr-sdk"
version = "0.44.1"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=bf3028eb11b4e324c0c660b4e4c83348cdcc00c2#bf3028eb11b4e324c0c660b4e4c83348cdcc00c2"
+source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
dependencies = [
"async-utility",
"async-wsocket",
+ "faster-hex",
"futures",
- "hex",
"lru",
"negentropy",
"nostr",
@@ -1098,6 +1120,7 @@ dependencies = [
"tokio",
"tokio-stream",
"tracing",
+ "universal-time",
]
[[package]]
@@ -1838,9 +1861,9 @@ dependencies = [
[[package]]
name = "tokio-tungstenite"
-version = "0.26.2"
+version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
+checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857"
dependencies = [
"futures-util",
"log",
@@ -2034,9 +2057,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "tungstenite"
-version = "0.26.2"
+version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13"
+checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442"
dependencies = [
"bytes",
"data-encoding",
@@ -2094,6 +2117,12 @@ dependencies = [
"subtle",
]
+[[package]]
+name = "universal-time"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f942cacf37a673350e8f252dff4691fb8e525a5fff6e1f2c4b6c2f3b8349248d"
+
[[package]]
name = "untrusted"
version = "0.9.0"
diff --git a/Cargo.toml b/Cargo.toml
index d7be3be..a0bb620 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,8 +18,8 @@ cln-plugin = "0.6"
# cln-plugin = { path = "../lightning/plugins/", version = "^0.6" }
parking_lot = "0.12"
-nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", rev = "bf3028eb11b4e324c0c660b4e4c83348cdcc00c2" }
-nostr = { git = "https://github.com/rust-nostr/nostr.git", rev = "bf3028eb11b4e324c0c660b4e4c83348cdcc00c2", features = [
+nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", rev = "6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6" }
+nostr = { git = "https://github.com/rust-nostr/nostr.git", rev = "6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6", features = [
"nip47",
"nip04",
"nip44",
diff --git a/src/nwc.rs b/src/nwc.rs
index 16c00c8..b319853 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -1,10 +1,9 @@
-use std::{borrow::Cow, time::Duration};
+use std::time::Duration;
use anyhow::anyhow;
use cln_plugin::Plugin;
use futures::StreamExt;
use nostr::{
- Alphabet,
Event,
EventBuilder,
EventId,
@@ -13,12 +12,10 @@ use nostr::{
Kind,
PublicKey,
SecretKey,
- SignerError,
- SingleLetterTag,
Tag,
- TagKind,
Timestamp,
nips::{nip04, nip44, nip47},
+ signer::SignerError,
};
use nostr_sdk::{
client::{self, Client, ClientNotification, Error},
@@ -149,7 +146,7 @@ pub async fn run_nwc(
.await
{
log::warn!("NWC handler for `{label_clone}` had an error: {e}");
- };
+ }
}
{};
@@ -254,7 +251,7 @@ async fn nwc_request_handler(
};
if let Some(expi) = event.tags.expiration() {
- if *expi < Timestamp::now() {
+ if expi < Timestamp::now() {
return Ok(());
}
}
@@ -335,13 +332,12 @@ async fn nwc_request_handler(
}
fn check_nip44_support(event: &Event) -> bool {
- if let Some(encryption_tag) = event
- .tags
- .find(TagKind::Custom(Cow::Borrowed("encryption")))
- {
- if let Some(enc_tag_content) = encryption_tag.content() {
- if enc_tag_content.contains("nip44_v2") {
- return true;
+ for tag in event.tags.iter() {
+ if tag.kind() == "encryption" {
+ if let Some(enc_tag_content) = tag.content() {
+ if enc_tag_content.contains("nip44_v2") {
+ return true;
+ }
}
}
}
@@ -442,13 +438,7 @@ fn build_response_event(
.tag(Tag::event(event_id))
.tag(Tag::public_key(client_pubkey));
if let Some(i) = id {
- response_builder = response_builder.tag(Tag::custom(
- TagKind::SingleLetter(SingleLetterTag {
- character: Alphabet::D,
- uppercase: false,
- }),
- vec![i],
- ));
+ response_builder = response_builder.tag(Tag::identifier(i));
}
match response_builder.sign_with_keys(wallet_keys) {
Ok(o) => Ok(o),
diff --git a/src/nwc_notifications.rs b/src/nwc_notifications.rs
index 8f77a99..4527a5c 100644
--- a/src/nwc_notifications.rs
+++ b/src/nwc_notifications.rs
@@ -342,7 +342,7 @@ async fn send_notification(
let content_encrypted_nip04 = signer.nip04_encrypt(client_pubkey, notification).await?;
let event_nip04 = EventBuilder::new(Kind::from_u16(23196), content_encrypted_nip04)
.tag(Tag::public_key(*client_pubkey))
- .sign(&signer)
+ .sign_async(&signer)
.await?;
let nip04_result = client.send_event(&event_nip04).await?;
if nip04_result.success.is_empty() {
@@ -360,7 +360,7 @@ async fn send_notification(
let content_encrypted_nip44 = signer.nip44_encrypt(client_pubkey, notification).await?;
let event_nip44 = EventBuilder::new(Kind::from_u16(23197), content_encrypted_nip44)
.tag(Tag::public_key(*client_pubkey))
- .sign(&signer)
+ .sign_async(&signer)
.await?;
let nip44_result = client.send_event(&event_nip44).await?;
if nip44_result.success.is_empty() {
From af306edd3a8a0b1b080a115e48100241f3278b20 Mon Sep 17 00:00:00 2001
From: daywalker90 <8257956+daywalker90@users.noreply.github.com>
Date: Sun, 17 May 2026 19:46:22 +0200
Subject: [PATCH 19/56] use xkeysend on CLN v26.06+
---
CHANGELOG.md | 3 +
src/nwc_keysend.rs | 204 ++++++++++++++++++++++++++++++---------------
src/nwc_pay.rs | 9 +-
3 files changed, 147 insertions(+), 69 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f0fd46e..08b1dbf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,9 @@
- holdinvoice methods: ``make_hold_invoice``, ``cancel_hold_invoice``, ``settle_hold_invoice``
- holdinvoice notification: ``hold_invoice_accepted``
+### Changed
+- `pay_keysend` will use the new CLN `xkeysend` command using CLN v26.06+
+
### Removed
- ``multi_pay_invoice`` and ``multi_pay_keysend``, they were removed from the spec
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index bc49ec2..c5c5673 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -1,15 +1,15 @@
-use std::str::FromStr;
+use std::{collections::HashMap, str::FromStr};
use cln_plugin::Plugin;
use cln_rpc::{
- model::requests::KeysendRequest,
+ model::requests::{KeysendRequest, XkeysendRequest},
primitives::{Amount, PublicKey, TlvEntry, TlvStream},
};
use nostr::nips::nip47;
use crate::{
structs::PluginState,
- util::{budget_amount_check, load_nwc_store, update_nwc_store},
+ util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
};
pub async fn pay_keysend_response(
@@ -76,75 +76,147 @@ async fn pay_keysend(
message: e.to_string(),
})?;
- let mut extratlvs = TlvStream {
- entries: Vec::new(),
- };
- for tlv in params.tlv_records {
- extratlvs.entries.push(TlvEntry {
- typ: tlv.tlv_type,
- value: tlv.value.as_bytes().to_owned(),
- });
- }
- let extratlvs = if extratlvs.entries.is_empty() {
- None
- } else {
- Some(extratlvs)
- };
+ let my_cln_version = plugin.state().config.lock().my_cln_version.clone();
- match rpc
- .call_typed(&KeysendRequest {
- exemptfee: None,
- extratlvs,
- label: None,
- maxdelay: None,
- maxfee: None,
- maxfeepercent: None,
- retry_for: None,
- routehints: None,
- amount_msat: Amount::from_msat(params.amount),
- destination: pubkey,
- })
- .await
- {
- Ok(o) => {
- if let Some(ref mut bdg) = nwc_store.budget_msat {
- *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
- update_nwc_store(&mut rpc, label, nwc_store)
- .await
- .map_err(|e| nip47::NIP47Error {
+ if at_or_above_version(&my_cln_version, "26.06").map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: e.to_string(),
+ })? {
+ let mut extratlvs = HashMap::with_capacity(params.tlv_records.len());
+ for tlv in params.tlv_records {
+ extratlvs.insert(tlv.tlv_type.to_string(), tlv.value);
+ }
+ let extratlvs = if extratlvs.is_empty() {
+ None
+ } else {
+ Some(extratlvs)
+ };
+
+ match rpc
+ .call_typed(&XkeysendRequest {
+ extratlvs,
+ label: None,
+ maxdelay: None,
+ maxfee: None,
+ retry_for: None,
+ layers: None,
+ amount_msat: Amount::from_msat(params.amount),
+ destination: pubkey,
+ })
+ .await
+ {
+ Ok(o) => {
+ if let Some(ref mut bdg) = nwc_store.budget_msat {
+ *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
+ update_nwc_store(&mut rpc, label, nwc_store)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ }
+
+ let preimage = hex::encode(o.payment_preimage.to_vec());
+
+ let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
+
+ Ok(nip47::PayKeysendResponse {
+ preimage,
+ fees_paid: Some(fees_paid),
+ })
+ }
+ Err(e) => match e.code {
+ Some(c) => match c {
+ 203 | 205 | 207 | 219 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::PaymentFailed,
+ message: e.to_string(),
+ }),
+ 209 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: e.to_string(),
+ }),
+ _ => Err(nip47::NIP47Error {
code: nip47::ErrorCode::Internal,
message: e.to_string(),
- })?;
- }
-
- let preimage = hex::encode(o.payment_preimage.to_vec());
-
- let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
-
- Ok(nip47::PayKeysendResponse {
- preimage,
- fees_paid: Some(fees_paid),
- })
- }
- Err(e) => match e.code {
- Some(c) => match c {
- 203 | 205 | 210 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::PaymentFailed,
- message: e.to_string(),
- }),
- 206 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::InsufficientBalance,
- message: e.to_string(),
- }),
- _ => Err(nip47::NIP47Error {
+ }),
+ },
+ None => Err(nip47::NIP47Error {
code: nip47::ErrorCode::Internal,
message: e.to_string(),
}),
},
- None => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
+ }
+ } else {
+ let mut extratlvs = TlvStream {
+ entries: Vec::new(),
+ };
+ for tlv in params.tlv_records {
+ extratlvs.entries.push(TlvEntry {
+ typ: tlv.tlv_type,
+ value: tlv.value.as_bytes().to_owned(),
+ });
+ }
+ let extratlvs = if extratlvs.entries.is_empty() {
+ None
+ } else {
+ Some(extratlvs)
+ };
+
+ match rpc
+ .call_typed(&KeysendRequest {
+ exemptfee: None,
+ extratlvs,
+ label: None,
+ maxdelay: None,
+ maxfee: None,
+ maxfeepercent: None,
+ retry_for: None,
+ routehints: None,
+ amount_msat: Amount::from_msat(params.amount),
+ destination: pubkey,
+ })
+ .await
+ {
+ Ok(o) => {
+ if let Some(ref mut bdg) = nwc_store.budget_msat {
+ *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
+ update_nwc_store(&mut rpc, label, nwc_store)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ }
+
+ let preimage = hex::encode(o.payment_preimage.to_vec());
+
+ let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
+
+ Ok(nip47::PayKeysendResponse {
+ preimage,
+ fees_paid: Some(fees_paid),
+ })
+ }
+ Err(e) => match e.code {
+ Some(c) => match c {
+ 203 | 205 | 210 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::PaymentFailed,
+ message: e.to_string(),
+ }),
+ 206 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::InsufficientBalance,
+ message: e.to_string(),
+ }),
+ _ => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ },
+ None => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ },
+ }
}
}
diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs
index a313720..4f4e859 100644
--- a/src/nwc_pay.rs
+++ b/src/nwc_pay.rs
@@ -1,17 +1,17 @@
use cln_plugin::Plugin;
use cln_rpc::{
+ ClnRpc,
+ RpcError,
model::{
requests::{DecodeRequest, PayRequest, XpayRequest},
responses::DecodeResponse,
},
primitives::{Amount, Secret},
- ClnRpc,
- RpcError,
};
use nostr::nips::nip47;
use crate::{
- structs::{NwcStore, PluginState, NOT_INV_ERR},
+ structs::{NOT_INV_ERR, NwcStore, PluginState},
util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
};
@@ -316,6 +316,9 @@ async fn pay_with_xpay_full(
layers: None,
invstring: params.invoice,
payer_note: None,
+ dev_use_shadow: None,
+ label: None,
+ localinvreqid: None,
})
.await
.map_err(|e| map_cln_error_to_nip47(&e, id, true))?;
From fb972c5ed1133d1af953401581b7b8cba56bcf44 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 26 Jul 2026 13:14:09 +0200
Subject: [PATCH 20/56] CI: use specific python versions per CLN version
---
.github/workflows/ci.yml | 24 ++++++++++---------
.github/workflows/latest_v25.05.yml | 14 -----------
.github/workflows/latest_v25.09.yml | 6 +++--
.github/workflows/latest_v25.12.yml | 8 ++++---
.github/workflows/latest_v26.04.yml | 2 ++
.github/workflows/latest_v26.06.yml | 16 +++++++++++++
.github/workflows/master_v25.09.yml | 6 +++--
.github/workflows/master_v25.12.yml | 6 +++--
.github/workflows/master_v26.04.yml | 2 ++
.../{master_v25.05.yml => master_v26.06.yml} | 8 ++++---
.github/workflows/release.yml | 12 ----------
11 files changed, 55 insertions(+), 49 deletions(-)
delete mode 100644 .github/workflows/latest_v25.05.yml
create mode 100644 .github/workflows/latest_v26.06.yml
rename .github/workflows/{master_v25.05.yml => master_v26.06.yml} (70%)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5275ba9..b15911b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,6 +17,12 @@ on:
tagged-release:
required: true
type: boolean
+ python-version-1:
+ required: true
+ type: string
+ python-version-2:
+ required: true
+ type: string
jobs:
build:
@@ -27,7 +33,7 @@ jobs:
bitcoind-version: ["31.0"]
experimental: [1]
deprecated: [0]
- python-version: ["3.10", "3.14"]
+ python-version: [ "${{ inputs.python-version-1 }}", "${{ inputs.python-version-2 }}"]
os: ["ubuntu-latest"]
runs-on: ${{ matrix.os }}
@@ -119,25 +125,21 @@ jobs:
key: ${{ steps.cache-cln.outputs.cache-primary-key }}
- name: Set up Rust
- if: ${{ inputs.tagged-release == false}}
+ if: ${{ inputs.tagged-release == false }}
uses: dtolnay/rust-toolchain@stable
- - name: Set up protoc
- if: ${{ inputs.tagged-release == false}}
- uses: arduino/setup-protoc@v3
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
-
- name: Install cargo-binstall
- if: ${{ inputs.tagged-release == false}}
+ if: ${{ inputs.tagged-release == false }}
uses: taiki-e/install-action@cargo-binstall
- name: Install cargo-msrv
- if: ${{ inputs.tagged-release == false}}
+ if: ${{ inputs.tagged-release == false }}
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
run: cargo binstall --no-confirm cargo-msrv
- name: Verify MSRV
- if: ${{ inputs.tagged-release == false}}
+ if: ${{ inputs.tagged-release == false }}
run: cargo msrv verify
- name: Get plugin binary
diff --git a/.github/workflows/latest_v25.05.yml b/.github/workflows/latest_v25.05.yml
deleted file mode 100644
index b5502c9..0000000
--- a/.github/workflows/latest_v25.05.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: Latest release on CLN v25.05.x
-
-on:
- release:
- types: [published, edited]
- workflow_dispatch:
-
-jobs:
- call-ci:
- uses: ./.github/workflows/ci.yml
- with:
- cln-version: "v25.05"
- pyln-version: "25.5"
- tagged-release: true
\ No newline at end of file
diff --git a/.github/workflows/latest_v25.09.yml b/.github/workflows/latest_v25.09.yml
index 2926b68..d96d48d 100644
--- a/.github/workflows/latest_v25.09.yml
+++ b/.github/workflows/latest_v25.09.yml
@@ -9,6 +9,8 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.09.2"
- pyln-version: "25.9.2"
+ cln-version: "v25.09.3"
+ pyln-version: "25.9.3"
tagged-release: true
+ python-version-1: "3.10"
+ python-version-2: "3.12"
diff --git a/.github/workflows/latest_v25.12.yml b/.github/workflows/latest_v25.12.yml
index 268f5f6..3a86b18 100644
--- a/.github/workflows/latest_v25.12.yml
+++ b/.github/workflows/latest_v25.12.yml
@@ -9,6 +9,8 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.12"
- pyln-version: "25.12"
- tagged-release: true
\ No newline at end of file
+ cln-version: "v25.12.1"
+ pyln-version: "25.12.1"
+ tagged-release: true
+ python-version-1: "3.10"
+ python-version-2: "3.12"
diff --git a/.github/workflows/latest_v26.04.yml b/.github/workflows/latest_v26.04.yml
index f545ca4..a0dc3a0 100644
--- a/.github/workflows/latest_v26.04.yml
+++ b/.github/workflows/latest_v26.04.yml
@@ -12,3 +12,5 @@ jobs:
cln-version: "v26.04"
pyln-version: "26.4"
tagged-release: true
+ python-version-1: "3.10"
+ python-version-2: "3.12"
diff --git a/.github/workflows/latest_v26.06.yml b/.github/workflows/latest_v26.06.yml
new file mode 100644
index 0000000..27edc2d
--- /dev/null
+++ b/.github/workflows/latest_v26.06.yml
@@ -0,0 +1,16 @@
+name: Latest release on CLN v26.06.x
+
+on:
+ release:
+ types: [published, edited]
+ workflow_dispatch:
+
+jobs:
+ call-ci:
+ uses: ./.github/workflows/ci.yml
+ with:
+ cln-version: "v26.06.6"
+ pyln-version: "26.6.6"
+ tagged-release: true
+ python-version-1: "3.10"
+ python-version-2: "3.14"
diff --git a/.github/workflows/master_v25.09.yml b/.github/workflows/master_v25.09.yml
index 7b62c39..1a73ecd 100644
--- a/.github/workflows/master_v25.09.yml
+++ b/.github/workflows/master_v25.09.yml
@@ -19,6 +19,8 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.09.2"
- pyln-version: "25.9.2"
+ cln-version: "v25.09.3"
+ pyln-version: "25.9.3"
tagged-release: false
+ python-version-1: "3.10"
+ python-version-2: "3.12"
diff --git a/.github/workflows/master_v25.12.yml b/.github/workflows/master_v25.12.yml
index 5df85d3..7e0ae62 100644
--- a/.github/workflows/master_v25.12.yml
+++ b/.github/workflows/master_v25.12.yml
@@ -19,6 +19,8 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.12"
- pyln-version: "25.12"
+ cln-version: "v25.12.1"
+ pyln-version: "25.12.1"
tagged-release: false
+ python-version-1: "3.10"
+ python-version-2: "3.12"
diff --git a/.github/workflows/master_v26.04.yml b/.github/workflows/master_v26.04.yml
index 5fcd616..82715be 100644
--- a/.github/workflows/master_v26.04.yml
+++ b/.github/workflows/master_v26.04.yml
@@ -22,3 +22,5 @@ jobs:
cln-version: "v26.04"
pyln-version: "26.4"
tagged-release: false
+ python-version-1: "3.10"
+ python-version-2: "3.12"
diff --git a/.github/workflows/master_v25.05.yml b/.github/workflows/master_v26.06.yml
similarity index 70%
rename from .github/workflows/master_v25.05.yml
rename to .github/workflows/master_v26.06.yml
index dfd753c..25fe3a8 100644
--- a/.github/workflows/master_v25.05.yml
+++ b/.github/workflows/master_v26.06.yml
@@ -1,4 +1,4 @@
-name: master on CLN v25.05.x
+name: master on CLN v26.06.x
on:
push:
@@ -19,6 +19,8 @@ jobs:
call-ci:
uses: ./.github/workflows/ci.yml
with:
- cln-version: "v25.05"
- pyln-version: "25.5"
+ cln-version: "v26.06.6"
+ pyln-version: "26.6.6"
tagged-release: false
+ python-version-1: "3.10"
+ python-version-2: "3.14"
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 56b76c8..6fef945 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -25,12 +25,6 @@ jobs:
sudo apt update
sudo apt install -y gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf
- - name: Install Protoc
- uses: arduino/setup-protoc@v3
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- version: "21.12"
-
- name: Build Linux binaries (release)
run: |
cargo build --profile optimized --locked --target x86_64-unknown-linux-gnu
@@ -70,12 +64,6 @@ jobs:
with:
targets: x86_64-apple-darwin, aarch64-apple-darwin
- - name: Install Protoc
- uses: arduino/setup-protoc@v3
- with:
- repo-token: ${{ secrets.GITHUB_TOKEN }}
- version: "21.12"
-
- name: Build macOS universal (release)
id: build
env:
From f85b2efcb39c3213f2a369f703c051eb7c2ac5cb Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 26 Jul 2026 13:15:02 +0200
Subject: [PATCH 21/56] update dependencies, upgrade nostr and cln dependencies
---
Cargo.lock | 592 +++++++++++++++------------------------
Cargo.toml | 20 +-
build.rs | 2 +
src/main.rs | 2 +-
src/nwc.rs | 36 +--
src/nwc_notifications.rs | 44 ++-
src/structs.rs | 3 +-
7 files changed, 287 insertions(+), 412 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 81fd1eb..b9dd79f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -40,9 +40,9 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "arrayvec"
-version = "0.7.6"
+version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe"
[[package]]
name = "async-trait"
@@ -69,13 +69,15 @@ dependencies = [
[[package]]
name = "async-wsocket"
-version = "0.13.1"
-source = "git+https://github.com/shadowylab/async-wsocket?rev=0fed6c9c6aec7393ee0e9cf3933d76914ab427d3#0fed6c9c6aec7393ee0e9cf3933d76914ab427d3"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c69f24cf7a798027c6b0801de5bfd05d01fe343e87a8329f7c8b46a6d3bc4a79"
dependencies = [
"futures",
"futures-util",
"js-sys",
"tokio",
+ "tokio-happy-eyeballs",
"tokio-rustls",
"tokio-socks",
"tokio-tungstenite",
@@ -93,11 +95,10 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "base58ck"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f"
+checksum = "8f1cba749a07c1efb1f4d87518f39cea4aec25d0991fb97e80459c057238f0d2"
dependencies = [
- "bitcoin-internals",
"bitcoin_hashes",
]
@@ -107,12 +108,6 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-[[package]]
-name = "base64ct"
-version = "1.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
-
[[package]]
name = "bech32"
version = "0.11.1"
@@ -132,13 +127,12 @@ dependencies = [
[[package]]
name = "bitcoin"
-version = "0.32.9"
+version = "0.32.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf93e61f2dbc3e3c41234ca26a65e2c0b0975c52e0f069ab9893ebbede584d3"
+checksum = "a1a121ccf1177a09084bd6ce97c52119919aac08ea3649967958eae41beceebf"
dependencies = [
"base58ck",
"bech32",
- "bitcoin-internals",
"bitcoin-io",
"bitcoin-units",
"bitcoin_hashes",
@@ -148,15 +142,6 @@ dependencies = [
"serde",
]
-[[package]]
-name = "bitcoin-internals"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2"
-dependencies = [
- "serde",
-]
-
[[package]]
name = "bitcoin-io"
version = "0.1.4"
@@ -165,19 +150,18 @@ checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953"
[[package]]
name = "bitcoin-units"
-version = "0.1.3"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "346568ebaab2918487cea76dd55dae13c27bb618cdb737c952e69eb2017c4118"
+checksum = "c202276cab20ab02cf6cc9d4df0d4284f7c784031619d3842236de8bc2bd5c6c"
dependencies = [
- "bitcoin-internals",
"serde",
]
[[package]]
name = "bitcoin_hashes"
-version = "0.14.1"
+version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b"
+checksum = "4ed83caece3afc59919481b33b472e1432d1abc4641ed9100be142ef5110b406"
dependencies = [
"bitcoin-io",
"hex-conservative",
@@ -186,9 +170,9 @@ dependencies = [
[[package]]
name = "bitflags"
-version = "2.11.1"
+version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]]
name = "block-buffer"
@@ -216,9 +200,9 @@ checksum = "6160c957d8aa33d0a8ba1dbab98e3cb57023ad9374c501441e88559f99e6c4c9"
[[package]]
name = "bumpalo"
-version = "3.20.2"
+version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
+checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "byteorder"
@@ -228,9 +212,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.11.1"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
+checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
[[package]]
name = "cbc"
@@ -243,9 +227,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.62"
+version = "1.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
+checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -307,6 +291,7 @@ dependencies = [
"nostr-sdk",
"parking_lot",
"prost",
+ "protoc-bin-vendored",
"regex",
"serde",
"serde_json",
@@ -319,9 +304,9 @@ dependencies = [
[[package]]
name = "cln-plugin"
-version = "0.6.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c340e01d74b553f761dd5636b8238cb92cacdf7d9d27a8820dad42da76ce0cb5"
+checksum = "b9a4bb9c7335040d49c51900305b91155303539e9f54839bb194e915277bf882"
dependencies = [
"anyhow",
"bytes",
@@ -338,9 +323,9 @@ dependencies = [
[[package]]
name = "cln-rpc"
-version = "0.6.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8c63eb175d58f0212e35e427237cf3e4f856f47ec7b8ad95110484d292fc819"
+checksum = "5d9f5e26f0a2713ea1393eb3117c148295fa4c5f7db529713b20323ca7cc37aa"
dependencies = [
"anyhow",
"bitcoin",
@@ -387,14 +372,13 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
- "subtle",
]
[[package]]
name = "displaydoc"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
dependencies = [
"proc-macro2",
"quote",
@@ -403,9 +387,9 @@ dependencies = [
[[package]]
name = "either"
-version = "1.15.0"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]]
name = "equivalent"
@@ -595,15 +579,14 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
+checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
dependencies = [
"cfg-if",
"libc",
"r-efi 6.0.0",
- "wasip2",
- "wasip3",
+ "rand_core 0.10.1",
]
[[package]]
@@ -620,9 +603,9 @@ dependencies = [
[[package]]
name = "h2"
-version = "0.4.14"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733"
+checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155"
dependencies = [
"atomic-waker",
"bytes",
@@ -698,20 +681,11 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
-[[package]]
-name = "hmac"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
-dependencies = [
- "digest",
-]
-
[[package]]
name = "http"
-version = "1.4.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
+checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
dependencies = [
"bytes",
"itoa",
@@ -754,9 +728,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
-version = "1.9.0"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
+checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
dependencies = [
"atomic-waker",
"bytes",
@@ -888,12 +862,6 @@ dependencies = [
"zerovec",
]
-[[package]]
-name = "id-arena"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
-
[[package]]
name = "idna"
version = "1.1.0"
@@ -923,8 +891,6 @@ checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown 0.17.1",
- "serde",
- "serde_core",
]
[[package]]
@@ -954,13 +920,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
-version = "0.3.98"
+version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08"
+checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
dependencies = [
"cfg-if",
"futures-util",
- "once_cell",
"wasm-bindgen",
]
@@ -970,12 +935,6 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-[[package]]
-name = "leb128fmt"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
-
[[package]]
name = "libc"
version = "0.2.186"
@@ -1005,9 +964,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.29"
+version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
+checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad"
[[package]]
name = "log-panics"
@@ -1020,9 +979,9 @@ dependencies = [
[[package]]
name = "lru"
-version = "0.16.4"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
+checksum = "0b6180140927ee907000b0aa540091f6ea512ead4447c92b8fc35bc72788a5a6"
[[package]]
name = "matchers"
@@ -1035,15 +994,15 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.8.0"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "mio"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
+checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
dependencies = [
"libc",
"wasi",
@@ -1064,8 +1023,9 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "nostr"
-version = "0.44.1"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
+version = "0.45.0-alpha.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e729c14441b72fca67727523e06242a5e173410d62118288de6fa308c199cceb"
dependencies = [
"aes",
"base64",
@@ -1076,8 +1036,8 @@ dependencies = [
"chacha20",
"chacha20poly1305",
"faster-hex",
- "rand",
- "scrypt",
+ "opaquerr",
+ "rand 0.10.1",
"secp256k1",
"serde",
"serde_json",
@@ -1088,25 +1048,30 @@ dependencies = [
[[package]]
name = "nostr-database"
-version = "0.44.0"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
+version = "0.45.0-alpha.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "944c4b23b12e1e138e48557dd7628dfea5a7e48f306b31438dc2a5161fb0635c"
dependencies = [
"btreecap",
"nostr",
+ "opaquerr",
]
[[package]]
name = "nostr-gossip"
-version = "0.44.0"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
+version = "0.45.0-alpha.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bc19bd1f8cbd5b3a2e2b48cf8758dd34ead48535beb514e26c919afbd35e9d"
dependencies = [
"nostr",
+ "opaquerr",
]
[[package]]
name = "nostr-sdk"
-version = "0.44.1"
-source = "git+https://github.com/rust-nostr/nostr.git?rev=6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6#6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6"
+version = "0.45.0-alpha.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f60df0948bd33d1853cb977782045ea083c0aaf140353cc7f52a8ce0a2c9f42d"
dependencies = [
"async-utility",
"async-wsocket",
@@ -1117,6 +1082,7 @@ dependencies = [
"nostr",
"nostr-database",
"nostr-gossip",
+ "opaquerr",
"tokio",
"tokio-stream",
"tracing",
@@ -1144,6 +1110,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
+[[package]]
+name = "opaquerr"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e55a7b7f0accc9fdd8e514f122a697adf824d55de481ca26c31ff8f9a8e813c5"
+
[[package]]
name = "parking_lot"
version = "0.12.5"
@@ -1167,27 +1139,6 @@ dependencies = [
"windows-link",
]
-[[package]]
-name = "password-hash"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
-dependencies = [
- "base64ct",
- "rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "pbkdf2"
-version = "0.12.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
-dependencies = [
- "digest",
- "hmac",
-]
-
[[package]]
name = "percent-encoding"
version = "2.3.2"
@@ -1207,18 +1158,18 @@ dependencies = [
[[package]]
name = "pin-project"
-version = "1.1.12"
+version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9"
+checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.1.12"
+version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389"
+checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
@@ -1281,9 +1232,9 @@ dependencies = [
[[package]]
name = "prost"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
+checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1"
dependencies = [
"bytes",
"prost-derive",
@@ -1291,9 +1242,9 @@ dependencies = [
[[package]]
name = "prost-build"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7"
+checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042"
dependencies = [
"heck",
"itertools",
@@ -1312,9 +1263,9 @@ dependencies = [
[[package]]
name = "prost-derive"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
+checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
dependencies = [
"anyhow",
"itertools",
@@ -1325,18 +1276,82 @@ dependencies = [
[[package]]
name = "prost-types"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7"
+checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a"
dependencies = [
"prost",
]
[[package]]
-name = "pulldown-cmark"
-version = "0.13.3"
+name = "protoc-bin-vendored"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad"
+checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa"
+dependencies = [
+ "protoc-bin-vendored-linux-aarch_64",
+ "protoc-bin-vendored-linux-ppcle_64",
+ "protoc-bin-vendored-linux-s390_64",
+ "protoc-bin-vendored-linux-x86_32",
+ "protoc-bin-vendored-linux-x86_64",
+ "protoc-bin-vendored-macos-aarch_64",
+ "protoc-bin-vendored-macos-x86_64",
+ "protoc-bin-vendored-win32",
+]
+
+[[package]]
+name = "protoc-bin-vendored-linux-aarch_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c"
+
+[[package]]
+name = "protoc-bin-vendored-linux-ppcle_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c"
+
+[[package]]
+name = "protoc-bin-vendored-linux-s390_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0"
+
+[[package]]
+name = "protoc-bin-vendored-linux-x86_32"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5"
+
+[[package]]
+name = "protoc-bin-vendored-linux-x86_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78"
+
+[[package]]
+name = "protoc-bin-vendored-macos-aarch_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092"
+
+[[package]]
+name = "protoc-bin-vendored-macos-x86_64"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756"
+
+[[package]]
+name = "protoc-bin-vendored-win32"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3"
+
+[[package]]
+name = "pulldown-cmark"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e"
dependencies = [
"bitflags",
"memchr",
@@ -1383,6 +1398,16 @@ dependencies = [
"rand_core 0.9.5",
]
+[[package]]
+name = "rand"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
+dependencies = [
+ "getrandom 0.4.3",
+ "rand_core 0.10.1",
+]
+
[[package]]
name = "rand_chacha"
version = "0.9.0"
@@ -1393,15 +1418,6 @@ dependencies = [
"rand_core 0.9.5",
]
-[[package]]
-name = "rand_core"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
-dependencies = [
- "getrandom 0.2.17",
-]
-
[[package]]
name = "rand_core"
version = "0.9.5"
@@ -1411,6 +1427,12 @@ dependencies = [
"getrandom 0.3.4",
]
+[[package]]
+name = "rand_core"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+
[[package]]
name = "redox_syscall"
version = "0.5.18"
@@ -1422,9 +1444,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.12.3"
+version = "1.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
+checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
dependencies = [
"aho-corasick",
"memchr",
@@ -1445,9 +1467,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.10"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
+checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
[[package]]
name = "ring"
@@ -1517,33 +1539,12 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
-[[package]]
-name = "salsa20"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213"
-dependencies = [
- "cipher",
-]
-
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-[[package]]
-name = "scrypt"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f"
-dependencies = [
- "password-hash",
- "pbkdf2",
- "salsa20",
- "sha2",
-]
-
[[package]]
name = "secp256k1"
version = "0.29.1"
@@ -1564,12 +1565,6 @@ dependencies = [
"cc",
]
-[[package]]
-name = "semver"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
-
[[package]]
name = "serde"
version = "1.0.228"
@@ -1602,9 +1597,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.149"
+version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
@@ -1624,17 +1619,6 @@ dependencies = [
"digest",
]
-[[package]]
-name = "sha2"
-version = "0.10.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
-dependencies = [
- "cfg-if",
- "cpufeatures",
- "digest",
-]
-
[[package]]
name = "sharded-slab"
version = "0.1.7"
@@ -1646,9 +1630,9 @@ dependencies = [
[[package]]
name = "shlex"
-version = "1.3.0"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "slab"
@@ -1658,15 +1642,15 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "smallvec"
-version = "1.15.1"
+version = "1.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
[[package]]
name = "socket2"
-version = "0.6.3"
+version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
+checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
dependencies = [
"libc",
"windows-sys 0.61.2",
@@ -1686,9 +1670,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.117"
+version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
+checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
@@ -1719,7 +1703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
- "getrandom 0.4.2",
+ "getrandom 0.4.3",
"once_cell",
"rustix",
"windows-sys 0.61.2",
@@ -1814,6 +1798,15 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "tokio-happy-eyeballs"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8564c32dfb6f4257f8bc6edfc178a34af97520e0b7b9815500c55eb3d092f29f"
+dependencies = [
+ "tokio",
+]
+
[[package]]
name = "tokio-macros"
version = "2.7.0"
@@ -1837,9 +1830,9 @@ dependencies = [
[[package]]
name = "tokio-socks"
-version = "0.5.2"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f"
+checksum = "a7e2948f60dbe26b35f2c7fb74ac2854c1fddded0fe9d7548fcc674a246f7615"
dependencies = [
"either",
"futures-util",
@@ -2066,7 +2059,7 @@ dependencies = [
"http",
"httparse",
"log",
- "rand",
+ "rand 0.9.4",
"rustls",
"rustls-pki-types",
"sha1",
@@ -2076,9 +2069,9 @@ dependencies = [
[[package]]
name = "typenum"
-version = "1.20.0"
+version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
+checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]]
name = "unicase"
@@ -2101,12 +2094,6 @@ dependencies = [
"tinyvec",
]
-[[package]]
-name = "unicode-xid"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
-
[[package]]
name = "universal-hash"
version = "0.5.1"
@@ -2156,11 +2143,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
-version = "1.23.1"
+version = "1.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
+checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
dependencies = [
- "getrandom 0.4.2",
+ "getrandom 0.4.3",
"js-sys",
"wasm-bindgen",
]
@@ -2198,23 +2185,14 @@ version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
- "wit-bindgen 0.46.0",
-]
-
-[[package]]
-name = "wasip3"
-version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
-dependencies = [
- "wit-bindgen 0.51.0",
+ "wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
-version = "0.2.121"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790"
+checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
dependencies = [
"cfg-if",
"once_cell",
@@ -2225,9 +2203,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.71"
+version = "0.4.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8"
+checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2235,9 +2213,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.121"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578"
+checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2245,9 +2223,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.121"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2"
+checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
dependencies = [
"bumpalo",
"proc-macro2",
@@ -2258,52 +2236,18 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.121"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441"
+checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
dependencies = [
"unicode-ident",
]
-[[package]]
-name = "wasm-encoder"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
-dependencies = [
- "leb128fmt",
- "wasmparser",
-]
-
-[[package]]
-name = "wasm-metadata"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
-dependencies = [
- "anyhow",
- "indexmap",
- "wasm-encoder",
- "wasmparser",
-]
-
-[[package]]
-name = "wasmparser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
-dependencies = [
- "bitflags",
- "hashbrown 0.15.5",
- "indexmap",
- "semver",
-]
-
[[package]]
name = "web-sys"
-version = "0.3.98"
+version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa"
+checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2315,14 +2259,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
- "webpki-roots 1.0.7",
+ "webpki-roots 1.0.8",
]
[[package]]
name = "webpki-roots"
-version = "1.0.7"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d"
+checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
dependencies = [
"rustls-pki-types",
]
@@ -2421,94 +2365,6 @@ version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
-[[package]]
-name = "wit-bindgen"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
-dependencies = [
- "wit-bindgen-rust-macro",
-]
-
-[[package]]
-name = "wit-bindgen-core"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
-dependencies = [
- "anyhow",
- "heck",
- "wit-parser",
-]
-
-[[package]]
-name = "wit-bindgen-rust"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
-dependencies = [
- "anyhow",
- "heck",
- "indexmap",
- "prettyplease",
- "syn",
- "wasm-metadata",
- "wit-bindgen-core",
- "wit-component",
-]
-
-[[package]]
-name = "wit-bindgen-rust-macro"
-version = "0.51.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
-dependencies = [
- "anyhow",
- "prettyplease",
- "proc-macro2",
- "quote",
- "syn",
- "wit-bindgen-core",
- "wit-bindgen-rust",
-]
-
-[[package]]
-name = "wit-component"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
-dependencies = [
- "anyhow",
- "bitflags",
- "indexmap",
- "log",
- "serde",
- "serde_derive",
- "serde_json",
- "wasm-encoder",
- "wasm-metadata",
- "wasmparser",
- "wit-parser",
-]
-
-[[package]]
-name = "wit-parser"
-version = "0.244.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
-dependencies = [
- "anyhow",
- "id-arena",
- "indexmap",
- "log",
- "semver",
- "serde",
- "serde_derive",
- "serde_json",
- "unicode-xid",
- "wasmparser",
-]
-
[[package]]
name = "writeable"
version = "0.6.3"
@@ -2517,9 +2373,9 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
[[package]]
name = "yoke"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
+checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
dependencies = [
"stable_deref_trait",
"yoke-derive",
@@ -2540,18 +2396,18 @@ dependencies = [
[[package]]
name = "zerocopy"
-version = "0.8.48"
+version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
+checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.48"
+version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
+checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
dependencies = [
"proc-macro2",
"quote",
@@ -2581,9 +2437,9 @@ dependencies = [
[[package]]
name = "zeroize"
-version = "1.8.2"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
[[package]]
name = "zerotrie"
diff --git a/Cargo.toml b/Cargo.toml
index a0bb620..484d61b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,19 +12,20 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
tokio = { version = "1", features = ["fs", "sync", "rt-multi-thread"] }
-cln-rpc = "0.6"
+cln-rpc = "0.7"
# cln-rpc = { path = "../lightning/cln-rpc/", version = "^0.6" }
-cln-plugin = "0.6"
+cln-plugin = "0.7"
# cln-plugin = { path = "../lightning/plugins/", version = "^0.6" }
parking_lot = "0.12"
-nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", rev = "6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6" }
-nostr = { git = "https://github.com/rust-nostr/nostr.git", rev = "6eb03213c7d3d9eaaa9b74c142f2b8eb79445af6", features = [
- "nip47",
- "nip04",
- "nip44",
-] }
-# nostr-sdk = { version = "0.44", features = ["nip47", "nip04", "nip44"] }
+# # nostr-sdk = { git = "https://github.com/rust-nostr/nostr.git", rev = "ff5be7d1416ea201887a02f648795010a3cbdf49" }
+# nostr = { git = "https://github.com/rust-nostr/nostr.git", rev = "ff5be7d1416ea201887a02f648795010a3cbdf49", features = [
+# "nip47",
+# "nip04",
+# "nip44",
+# ] }
+nostr = { version = "0.45.0-alpha.4", features = ["nip47", "nip04", "nip44"] }
+nostr-sdk = { version = "0.45.0-alpha.4" }
futures = "0.3"
@@ -44,6 +45,7 @@ tonic-prost = "0.14"
[build-dependencies]
tonic-prost-build = "0.14"
+protoc-bin-vendored = "3"
[profile.optimized]
diff --git a/build.rs b/build.rs
index 3e87891..04c8cef 100644
--- a/build.rs
+++ b/build.rs
@@ -1,4 +1,6 @@
fn main() {
+ let protoc = protoc_bin_vendored::protoc_bin_path().unwrap();
+ unsafe { std::env::set_var("PROTOC", protoc) };
tonic_prost_build::configure()
.protoc_arg("--experimental_allow_proto3_optional")
.compile_protos(&["protos/hold.proto"], &["protos"])
diff --git a/src/main.rs b/src/main.rs
index dd70aad..a0e8a8b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -165,7 +165,7 @@ async fn shutdown_handler(
_args: serde_json::Value,
) -> Result<(), anyhow::Error> {
let mut locked_handles = plugin.state().handles.lock().await;
- for (_x, (client, _client_pubkey)) in locked_handles.drain() {
+ for (_x, (client, _client_pubkey, _wallet_keys)) in locked_handles.drain() {
client.shutdown().await;
}
std::process::exit(0)
diff --git a/src/nwc.rs b/src/nwc.rs
index b319853..3bcc1e7 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -14,11 +14,12 @@ use nostr::{
SecretKey,
Tag,
Timestamp,
+ event::FinalizeEventAsync,
nips::{nip04, nip44, nip47},
- signer::SignerError,
};
use nostr_sdk::{
- client::{self, Client, ClientNotification, Error},
+ client::{self, Client, ClientNotification},
+ error::Error,
relay::RelayStatus,
};
use tokio::{sync::oneshot, time};
@@ -49,13 +50,10 @@ pub async fn run_nwc(
) -> Result<(), Error> {
let (method_capabilities, _) = build_capabilities(is_read_only_nwc(&nwc_store), &plugin);
- let wallet_keys = Keys::new(
- SecretKey::from_hex(&nwc_store.walletkey)
- .map_err(|e| Error::Signer(SignerError::backend(e)))?,
- );
- let client_pubkey = Keys::new(nwc_store.uri.secret.clone()).public_key();
+ let wallet_keys = Keys::new(SecretKey::from_hex(&nwc_store.walletkey)?);
+ let client_keys = Keys::new(nwc_store.uri.secret.clone());
- let nostr_client = Client::builder().signer(wallet_keys.clone()).build();
+ let nostr_client = Client::new();
log::debug!("relay_count:{}", nwc_store.uri.relays.len());
@@ -71,6 +69,8 @@ pub async fn run_nwc(
let nostr_client_clone = nostr_client.clone();
let plugin_clone = plugin.clone();
let label_clone = label.clone();
+ let client_keys_clone = client_keys.clone();
+ let wallet_keys_clone = wallet_keys.clone();
tokio::spawn(async move {
loop {
nostr_client_clone
@@ -100,7 +100,7 @@ pub async fn run_nwc(
plugin_clone.clone(),
nostr_client_clone.clone(),
method_capabilities.clone(),
- wallet_keys.clone(),
+ wallet_keys_clone.clone(),
)
.await
{
@@ -112,7 +112,7 @@ pub async fn run_nwc(
let filter = Filter::new()
.kind(Kind::WalletConnectRequest)
- .author(client_pubkey)
+ .author(client_keys_clone.public_key())
.since(Timestamp::now() - STARTUP_DELAY - 1);
let mut notifications = nostr_client_clone.notifications();
@@ -140,8 +140,8 @@ pub async fn run_nwc(
&nostr_client_clone,
&plugin_clone,
&label_clone,
- &wallet_keys,
- client_pubkey,
+ &wallet_keys_clone,
+ client_keys_clone.public_key(),
)
.await
{
@@ -156,7 +156,7 @@ pub async fn run_nwc(
let mut locked_handles = plugin.state().handles.lock().await;
locked_handles.insert(
label.clone(),
- (nostr_client, Keys::new(nwc_store.uri.secret).public_key()),
+ (nostr_client, client_keys.public_key(), wallet_keys),
);
Ok(())
}
@@ -180,7 +180,7 @@ pub async fn send_nwc_info_event(
.tag(Tag::parse(vec!["notifications", ¬ification_capabilities]).unwrap());
}
- let info_event = match info_event_builder.sign_with_keys(&wallet_keys) {
+ let info_event = match info_event_builder.finalize_async(&wallet_keys).await {
Ok(o) => o,
Err(e) => {
return Err(anyhow!("Could not sign info_event! {e}"));
@@ -208,7 +208,7 @@ pub async fn send_nwc_info_event(
pub async fn stop_nwc(plugin: Plugin, label: &String) {
let mut locked_handles = plugin.state().handles.lock().await;
- if let Some((client, _client_pubkey)) = locked_handles.remove(label) {
+ if let Some((client, _client_pubkey, _wallet_secret)) = locked_handles.remove(label) {
client.shutdown().await;
}
@@ -299,7 +299,7 @@ async fn nwc_request_handler(
};
let response_event =
- match build_response_event(event.id, content, wallet_keys, client_pubkey, id) {
+ match build_response_event(event.id, content, wallet_keys, client_pubkey, id).await {
Ok(o) => o,
Err(e) => {
log::warn!("Error signing reponse event! {e}");
@@ -427,7 +427,7 @@ fn encrypt_response_content(
}
}
-fn build_response_event(
+async fn build_response_event(
event_id: EventId,
content: String,
wallet_keys: &Keys,
@@ -440,7 +440,7 @@ fn build_response_event(
if let Some(i) = id {
response_builder = response_builder.tag(Tag::identifier(i));
}
- match response_builder.sign_with_keys(wallet_keys) {
+ match response_builder.finalize_async(wallet_keys).await {
Ok(o) => Ok(o),
Err(e) => Err(e.into()),
}
diff --git a/src/nwc_notifications.rs b/src/nwc_notifications.rs
index 4527a5c..34d2ca5 100644
--- a/src/nwc_notifications.rs
+++ b/src/nwc_notifications.rs
@@ -16,7 +16,15 @@ use cln_rpc::{
},
primitives::Sha256,
};
-use nostr::{EventBuilder, Kind, Tag, Timestamp, key::PublicKey, nips::nip47};
+use nostr::{
+ EventBuilder,
+ Kind,
+ Tag,
+ Timestamp,
+ event::FinalizeEventAsync,
+ key::{Keys, PublicKey, SecretKey},
+ nips::{nip04, nip44, nip47},
+};
use nostr_sdk::client::Client;
use crate::{
@@ -75,8 +83,8 @@ pub async fn payment_received_handler(
let clients = plugin.state().handles.lock().await;
- for (client, client_pubkey) in clients.values() {
- send_notification(¬ification, client, client_pubkey).await?;
+ for (client, client_pubkey, wallet_secret) in clients.values() {
+ send_notification(¬ification, client, client_pubkey.clone(), wallet_secret).await?;
}
Ok(())
@@ -212,8 +220,8 @@ pub async fn payment_sent_handler(
let clients = plugin.state().handles.lock().await;
- for (client, client_pubkey) in clients.values() {
- send_notification(¬ification, client, client_pubkey).await?;
+ for (client, client_pubkey, wallet_secret) in clients.values() {
+ send_notification(¬ification, client, client_pubkey.clone(), wallet_secret).await?;
}
Ok(())
@@ -335,14 +343,15 @@ async fn make_payment_sent_from_listpays(
async fn send_notification(
notification: &String,
client: &Client,
- client_pubkey: &PublicKey,
+ client_pubkey: PublicKey,
+ wallet_secret: &Keys,
) -> Result<(), anyhow::Error> {
- let signer = client.signer().unwrap().clone();
log::debug!("NOTIFICATION: {notification}");
- let content_encrypted_nip04 = signer.nip04_encrypt(client_pubkey, notification).await?;
+ let content_encrypted_nip04 =
+ nip04::encrypt(wallet_secret.secret_key(), &client_pubkey, notification)?;
let event_nip04 = EventBuilder::new(Kind::from_u16(23196), content_encrypted_nip04)
- .tag(Tag::public_key(*client_pubkey))
- .sign_async(&signer)
+ .tag(Tag::public_key(client_pubkey))
+ .finalize_async(wallet_secret)
.await?;
let nip04_result = client.send_event(&event_nip04).await?;
if nip04_result.success.is_empty() {
@@ -357,10 +366,15 @@ async fn send_notification(
}
log::debug!("NIP04 NOTIFICATION SENT: {event_nip04:?}");
- let content_encrypted_nip44 = signer.nip44_encrypt(client_pubkey, notification).await?;
+ let content_encrypted_nip44 = nip44::encrypt(
+ wallet_secret.secret_key(),
+ &client_pubkey,
+ notification,
+ nip44::Version::V2,
+ )?;
let event_nip44 = EventBuilder::new(Kind::from_u16(23197), content_encrypted_nip44)
- .tag(Tag::public_key(*client_pubkey))
- .sign_async(&signer)
+ .tag(Tag::public_key(client_pubkey))
+ .finalize_async(wallet_secret)
.await?;
let nip44_result = client.send_event(&event_nip44).await?;
if nip44_result.success.is_empty() {
@@ -500,8 +514,8 @@ pub async fn holdinvoice_accepted_handler(
};
let notification = serde_json::to_string(&content).unwrap();
- for (client, client_pubkey) in clients.values() {
- send_notification(¬ification, client, client_pubkey).await?;
+ for (client, client_pubkey, wallet_secret) in clients.values() {
+ send_notification(¬ification, client, client_pubkey.clone(), wallet_secret).await?;
}
Ok(())
}
diff --git a/src/structs.rs b/src/structs.rs
index e7eea09..22c166b 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -15,7 +15,8 @@ pub const NOT_INV_ERR: &str = "Not an invoice or invalid invoice";
#[derive(Clone)]
pub struct PluginState {
pub config: Arc>,
- pub handles: Arc>>,
+ pub handles:
+ Arc>>,
pub rpc_lock: Arc>,
pub budget_jobs: Arc>>>,
pub hold_client: Arc>>>,
From f6517cab7e896ade45845439a349a5e9c2ed22d9 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 26 Jul 2026 13:15:41 +0200
Subject: [PATCH 22/56] update dependencies
---
Cargo.lock | 370 +++++++++++++++++++++++++++++------------------------
1 file changed, 206 insertions(+), 164 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index b9dd79f..c693f75 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -34,25 +34,25 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.102"
+version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "arrayvec"
-version = "0.7.7"
+version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe"
+checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
[[package]]
name = "async-trait"
-version = "0.1.89"
+version = "0.1.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
+checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
@@ -95,9 +95,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "base58ck"
-version = "0.1.1"
+version = "0.1.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1cba749a07c1efb1f4d87518f39cea4aec25d0991fb97e80459c057238f0d2"
+checksum = "365c0acd5b2e8dd0111a46c4faea83fb3cfb6e39a49a7c73a06e090db7b2eff0"
dependencies = [
"bitcoin_hashes",
]
@@ -127,52 +127,73 @@ dependencies = [
[[package]]
name = "bitcoin"
-version = "0.32.10"
+version = "0.32.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a121ccf1177a09084bd6ce97c52119919aac08ea3649967958eae41beceebf"
+checksum = "bb0ce8bd5baaa0d303a19915a6d93afed161f528654e42da2a7a97d05c59499a"
dependencies = [
"base58ck",
"bech32",
"bitcoin-io",
"bitcoin-units",
"bitcoin_hashes",
- "hex-conservative",
+ "hex-conservative 0.2.2",
"hex_lit",
"secp256k1",
"serde",
]
[[package]]
-name = "bitcoin-io"
-version = "0.1.4"
+name = "bitcoin-consensus-encoding"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953"
+checksum = "207311705279250ba465076a1bac4b1ac982855fff73fc5f67e22158ac58cdc9"
+dependencies = [
+ "bitcoin-internals",
+ "hex-conservative 1.2.0",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin-internals"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d573f4cf32996a8dce612e4348cece65a241f1882ed594047c9ba348e8869fa5"
+
+[[package]]
+name = "bitcoin-io"
+version = "0.1.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78"
+dependencies = [
+ "bitcoin-consensus-encoding",
+]
[[package]]
name = "bitcoin-units"
-version = "0.1.4"
+version = "0.1.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c202276cab20ab02cf6cc9d4df0d4284f7c784031619d3842236de8bc2bd5c6c"
+checksum = "9cb95693f371d089a4b5b6fc41c6f3ea6e01ee8c15388335dfac8ea685173b51"
dependencies = [
+ "bitcoin-consensus-encoding",
"serde",
]
[[package]]
name = "bitcoin_hashes"
-version = "0.14.2"
+version = "0.14.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ed83caece3afc59919481b33b472e1432d1abc4641ed9100be142ef5110b406"
+checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2"
dependencies = [
"bitcoin-io",
- "hex-conservative",
+ "hex-conservative 0.2.2",
"serde",
]
[[package]]
name = "bitflags"
-version = "2.13.0"
+version = "2.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
[[package]]
name = "block-buffer"
@@ -212,9 +233,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.12.0"
+version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
+checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]]
name = "cbc"
@@ -227,9 +248,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.65"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
+checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -382,14 +403,14 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "either"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
[[package]]
name = "equivalent"
@@ -419,9 +440,9 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.4.1"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
+checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
[[package]]
name = "find-msvc-tools"
@@ -458,9 +479,9 @@ dependencies = [
[[package]]
name = "futures"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
+checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218"
dependencies = [
"futures-channel",
"futures-core",
@@ -473,9 +494,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
+checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae"
dependencies = [
"futures-core",
"futures-sink",
@@ -483,15 +504,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
+checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
[[package]]
name = "futures-executor"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
+checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458"
dependencies = [
"futures-core",
"futures-task",
@@ -500,38 +521,38 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
+checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"
[[package]]
name = "futures-macro"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
+checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "futures-sink"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
+checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307"
[[package]]
name = "futures-task"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
+checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
[[package]]
name = "futures-util"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
+checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
dependencies = [
"futures-channel",
"futures-core",
@@ -675,6 +696,15 @@ dependencies = [
"arrayvec",
]
+[[package]]
+name = "hex-conservative"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35431185f361ccf3ffc58254628af5f1f5d5f28531da2e02e5d6c82bbc282a10"
+dependencies = [
+ "arrayvec",
+]
+
[[package]]
name = "hex_lit"
version = "0.1.1"
@@ -693,9 +723,9 @@ dependencies = [
[[package]]
name = "http-body"
-version = "1.0.1"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
dependencies = [
"bytes",
"http",
@@ -703,9 +733,9 @@ dependencies = [
[[package]]
name = "http-body-util"
-version = "0.1.3"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2"
dependencies = [
"bytes",
"futures-core",
@@ -728,9 +758,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
-version = "1.10.1"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
+checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72"
dependencies = [
"atomic-waker",
"bytes",
@@ -920,9 +950,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
-version = "0.3.102"
+version = "0.3.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
+checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
dependencies = [
"cfg-if",
"futures-util",
@@ -937,9 +967,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
-version = "0.2.186"
+version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "linux-raw-sys"
@@ -994,15 +1024,15 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.8.2"
+version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "mio"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
+checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
dependencies = [
"libc",
"wasi",
@@ -1023,9 +1053,9 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "nostr"
-version = "0.45.0-alpha.4"
+version = "0.45.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e729c14441b72fca67727523e06242a5e173410d62118288de6fa308c199cceb"
+checksum = "5e90ba68fc04b87254ef574e10aef1fe92d44839043f42e37a7c4c4a1e7e4c82"
dependencies = [
"aes",
"base64",
@@ -1037,7 +1067,7 @@ dependencies = [
"chacha20poly1305",
"faster-hex",
"opaquerr",
- "rand 0.10.1",
+ "rand 0.10.2",
"secp256k1",
"serde",
"serde_json",
@@ -1048,9 +1078,9 @@ dependencies = [
[[package]]
name = "nostr-database"
-version = "0.45.0-alpha.4"
+version = "0.45.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "944c4b23b12e1e138e48557dd7628dfea5a7e48f306b31438dc2a5161fb0635c"
+checksum = "77c37167c3f289fea43e82f8bb24bb2006a2fb803abaaa908b25f1d3ca0b2bcc"
dependencies = [
"btreecap",
"nostr",
@@ -1059,9 +1089,9 @@ dependencies = [
[[package]]
name = "nostr-gossip"
-version = "0.45.0-alpha.4"
+version = "0.45.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bc19bd1f8cbd5b3a2e2b48cf8758dd34ead48535beb514e26c919afbd35e9d"
+checksum = "bb24a1f82e3fe9e3e9b4549e916ec168d4c21c2e55c61fa6be9f98218872cd37"
dependencies = [
"nostr",
"opaquerr",
@@ -1069,9 +1099,9 @@ dependencies = [
[[package]]
name = "nostr-sdk"
-version = "0.45.0-alpha.4"
+version = "0.45.0-alpha.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f60df0948bd33d1853cb977782045ea083c0aaf140353cc7f52a8ce0a2c9f42d"
+checksum = "5b197627792d5f02ab257c1bff30d4475e0ebc85229a82515b05d6717c6a4fbc"
dependencies = [
"async-utility",
"async-wsocket",
@@ -1173,7 +1203,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1218,14 +1248,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "proc-macro2"
-version = "1.0.106"
+version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
@@ -1257,7 +1287,7 @@ dependencies = [
"pulldown-cmark",
"pulldown-cmark-to-cmark",
"regex",
- "syn",
+ "syn 2.0.119",
"tempfile",
]
@@ -1271,7 +1301,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1369,9 +1399,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.45"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
@@ -1390,9 +1420,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
-version = "0.9.4"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
+checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
dependencies = [
"rand_chacha",
"rand_core 0.9.5",
@@ -1400,9 +1430,9 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.10.1"
+version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
+checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
dependencies = [
"getrandom 0.4.3",
"rand_core 0.10.1",
@@ -1444,9 +1474,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.12.4"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
+checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
dependencies = [
"aho-corasick",
"memchr",
@@ -1456,9 +1486,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.14"
+version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
dependencies = [
"aho-corasick",
"memchr",
@@ -1500,9 +1530,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.40"
+version = "0.23.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
+checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138"
dependencies = [
"log",
"once_cell",
@@ -1515,9 +1545,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.14.1"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
+checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
dependencies = [
"zeroize",
]
@@ -1535,9 +1565,9 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.22"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
[[package]]
name = "scopeguard"
@@ -1567,9 +1597,9 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.228"
+version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
"serde_core",
"serde_derive",
@@ -1577,29 +1607,29 @@ dependencies = [
[[package]]
name = "serde_core"
-version = "1.0.228"
+version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.228"
+version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
name = "serde_json"
-version = "1.0.150"
+version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"itoa",
"memchr",
@@ -1610,9 +1640,9 @@ dependencies = [
[[package]]
name = "sha1"
-version = "0.10.6"
+version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -1648,9 +1678,9 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
[[package]]
name = "socket2"
-version = "0.6.4"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
+checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
dependencies = [
"libc",
"windows-sys 0.61.2",
@@ -1670,9 +1700,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.118"
+version = "2.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
+checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [
"proc-macro2",
"quote",
@@ -1693,7 +1734,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1720,11 +1761,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.18"
+version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
+checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
dependencies = [
- "thiserror-impl 2.0.18",
+ "thiserror-impl 2.0.19",
]
[[package]]
@@ -1735,25 +1776,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "thiserror-impl"
-version = "2.0.18"
+version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
name = "thread_local"
-version = "1.1.9"
+version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
+checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070"
dependencies = [
"cfg-if",
]
@@ -1770,9 +1811,9 @@ dependencies = [
[[package]]
name = "tinyvec"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
+checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
dependencies = [
"tinyvec_macros",
]
@@ -1785,9 +1826,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.52.3"
+version = "1.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
+checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
dependencies = [
"bytes",
"libc",
@@ -1809,13 +1850,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.7.0"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
+checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1842,9 +1883,9 @@ dependencies = [
[[package]]
name = "tokio-stream"
-version = "0.1.18"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
+checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -1870,13 +1911,14 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.18"
+version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
+checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
+ "libc",
"pin-project-lite",
"tokio",
]
@@ -1919,7 +1961,7 @@ dependencies = [
"prettyplease",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1944,7 +1986,7 @@ dependencies = [
"prost-build",
"prost-types",
"quote",
- "syn",
+ "syn 2.0.119",
"tempfile",
"tonic-build",
]
@@ -2000,7 +2042,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -2059,11 +2101,11 @@ dependencies = [
"http",
"httparse",
"log",
- "rand 0.9.4",
+ "rand 0.9.5",
"rustls",
"rustls-pki-types",
"sha1",
- "thiserror 2.0.18",
+ "thiserror 2.0.19",
"utf-8",
]
@@ -2143,9 +2185,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
-version = "1.23.3"
+version = "1.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
+checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
dependencies = [
"getrandom 0.4.3",
"js-sys",
@@ -2190,9 +2232,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen"
-version = "0.2.125"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
+checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
dependencies = [
"cfg-if",
"once_cell",
@@ -2203,9 +2245,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.75"
+version = "0.4.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
+checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2213,9 +2255,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.125"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
+checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2223,31 +2265,31 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.125"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
+checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.125"
+version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
+checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
-version = "0.3.102"
+version = "0.3.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
+checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2259,14 +2301,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
- "webpki-roots 1.0.8",
+ "webpki-roots 1.0.9",
]
[[package]]
name = "webpki-roots"
-version = "1.0.8"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
+checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
dependencies = [
"rustls-pki-types",
]
@@ -2390,28 +2432,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
"synstructure",
]
[[package]]
name = "zerocopy"
-version = "0.8.52"
+version = "0.8.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
+checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.52"
+version = "0.8.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
+checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -2431,7 +2473,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
"synstructure",
]
@@ -2471,11 +2513,11 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "zmij"
-version = "1.0.21"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
From 61c07f6079c05716c745020d357946125c35c209 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 26 Jul 2026 14:48:42 +0200
Subject: [PATCH 23/56] refactor, clippy and ruff fixes
---
src/main.rs | 6 +-
src/nwc.rs | 17 +-
src/nwc_keysend.rs | 297 ++++++------
src/nwc_lookups.rs | 613 +++++++++++++------------
src/nwc_notifications.rs | 58 +--
src/rpc.rs | 2 +-
src/structs.rs | 9 +-
tests/pyproject.toml | 8 +-
tests/test_cln-nip47.py | 109 ++---
tests/uv.lock | 949 ++++++++++++++++++++++-----------------
10 files changed, 1134 insertions(+), 934 deletions(-)
mode change 100755 => 100644 tests/test_cln-nip47.py
diff --git a/src/main.rs b/src/main.rs
index a0e8a8b..f80d21a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -165,8 +165,8 @@ async fn shutdown_handler(
_args: serde_json::Value,
) -> Result<(), anyhow::Error> {
let mut locked_handles = plugin.state().handles.lock().await;
- for (_x, (client, _client_pubkey, _wallet_keys)) in locked_handles.drain() {
- client.shutdown().await;
+ for (_x, wallet_service) in locked_handles.drain() {
+ wallet_service.client.shutdown().await;
}
std::process::exit(0)
}
@@ -299,6 +299,6 @@ fn do_certificates_exist(cert_dir: &Path) -> bool {
required_files.iter().all(|file| {
let path = cert_dir.join(file);
- path.exists() && path.metadata().map(|m| m.len() > 0).unwrap_or(false)
+ path.exists() && path.metadata().is_ok_and(|m| m.len() > 0)
})
}
diff --git a/src/nwc.rs b/src/nwc.rs
index 3bcc1e7..c381f94 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -38,11 +38,12 @@ use crate::{
nwc_keysend::pay_keysend_response,
nwc_lookups::{list_transactions_response, lookup_invoice_response},
nwc_pay::pay_invoice_response,
- structs::{NwcStore, PluginState},
+ structs::{NwcStore, PluginState, WalletService},
tasks::budget_task,
util::{build_capabilities, build_notifications_vec, is_read_only_nwc},
};
+#[allow(clippy::too_many_lines)]
pub async fn run_nwc(
plugin: Plugin,
label: String,
@@ -154,10 +155,12 @@ pub async fn run_nwc(
});
let mut locked_handles = plugin.state().handles.lock().await;
- locked_handles.insert(
- label.clone(),
- (nostr_client, client_keys.public_key(), wallet_keys),
- );
+ let wallet_service = WalletService {
+ client: nostr_client,
+ client_pubkey: client_keys.public_key(),
+ wallet_secret: wallet_keys,
+ };
+ locked_handles.insert(label.clone(), wallet_service);
Ok(())
}
@@ -208,8 +211,8 @@ pub async fn send_nwc_info_event(
pub async fn stop_nwc(plugin: Plugin, label: &String) {
let mut locked_handles = plugin.state().handles.lock().await;
- if let Some((client, _client_pubkey, _wallet_secret)) = locked_handles.remove(label) {
- client.shutdown().await;
+ if let Some(wallet_service) = locked_handles.remove(label) {
+ wallet_service.client.shutdown().await;
}
stop_nwc_budget_job(&plugin, label);
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index c5c5673..dc1ee5e 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -2,13 +2,14 @@ use std::{collections::HashMap, str::FromStr};
use cln_plugin::Plugin;
use cln_rpc::{
+ ClnRpc,
model::requests::{KeysendRequest, XkeysendRequest},
primitives::{Amount, PublicKey, TlvEntry, TlvStream},
};
-use nostr::nips::nip47;
+use nostr::nips::nip47::{self};
use crate::{
- structs::PluginState,
+ structs::{NwcStore, PluginState},
util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
};
@@ -57,7 +58,7 @@ async fn pay_keysend(
});
}
- let mut nwc_store = load_nwc_store(&mut rpc, label)
+ let nwc_store = load_nwc_store(&mut rpc, label)
.await
.map_err(|e| nip47::NIP47Error {
code: nip47::ErrorCode::Internal,
@@ -82,141 +83,161 @@ async fn pay_keysend(
code: nip47::ErrorCode::Other,
message: e.to_string(),
})? {
- let mut extratlvs = HashMap::with_capacity(params.tlv_records.len());
- for tlv in params.tlv_records {
- extratlvs.insert(tlv.tlv_type.to_string(), tlv.value);
- }
- let extratlvs = if extratlvs.is_empty() {
- None
- } else {
- Some(extratlvs)
- };
-
- match rpc
- .call_typed(&XkeysendRequest {
- extratlvs,
- label: None,
- maxdelay: None,
- maxfee: None,
- retry_for: None,
- layers: None,
- amount_msat: Amount::from_msat(params.amount),
- destination: pubkey,
- })
- .await
- {
- Ok(o) => {
- if let Some(ref mut bdg) = nwc_store.budget_msat {
- *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
- update_nwc_store(&mut rpc, label, nwc_store)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
- }
-
- let preimage = hex::encode(o.payment_preimage.to_vec());
-
- let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
-
- Ok(nip47::PayKeysendResponse {
- preimage,
- fees_paid: Some(fees_paid),
- })
- }
- Err(e) => match e.code {
- Some(c) => match c {
- 203 | 205 | 207 | 219 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::PaymentFailed,
- message: e.to_string(),
- }),
- 209 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: e.to_string(),
- }),
- _ => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- None => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- }
+ xkeysend(&mut rpc, params, pubkey, nwc_store, label).await
} else {
- let mut extratlvs = TlvStream {
- entries: Vec::new(),
- };
- for tlv in params.tlv_records {
- extratlvs.entries.push(TlvEntry {
- typ: tlv.tlv_type,
- value: tlv.value.as_bytes().to_owned(),
- });
- }
- let extratlvs = if extratlvs.entries.is_empty() {
- None
- } else {
- Some(extratlvs)
- };
-
- match rpc
- .call_typed(&KeysendRequest {
- exemptfee: None,
- extratlvs,
- label: None,
- maxdelay: None,
- maxfee: None,
- maxfeepercent: None,
- retry_for: None,
- routehints: None,
- amount_msat: Amount::from_msat(params.amount),
- destination: pubkey,
- })
- .await
- {
- Ok(o) => {
- if let Some(ref mut bdg) = nwc_store.budget_msat {
- *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
- update_nwc_store(&mut rpc, label, nwc_store)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
- }
-
- let preimage = hex::encode(o.payment_preimage.to_vec());
-
- let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
-
- Ok(nip47::PayKeysendResponse {
- preimage,
- fees_paid: Some(fees_paid),
- })
- }
- Err(e) => match e.code {
- Some(c) => match c {
- 203 | 205 | 210 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::PaymentFailed,
- message: e.to_string(),
- }),
- 206 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::InsufficientBalance,
- message: e.to_string(),
- }),
- _ => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- None => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- }
+ keysend(&mut rpc, params, pubkey, nwc_store, label).await
+ }
+}
+
+async fn xkeysend(
+ rpc: &mut ClnRpc,
+ params: nip47::PayKeysendRequest,
+ pubkey: PublicKey,
+ mut nwc_store: NwcStore,
+ label: &str,
+) -> Result {
+ let mut extratlvs = HashMap::with_capacity(params.tlv_records.len());
+ for tlv in params.tlv_records {
+ extratlvs.insert(tlv.tlv_type.to_string(), tlv.value);
+ }
+ let extratlvs = if extratlvs.is_empty() {
+ None
+ } else {
+ Some(extratlvs)
+ };
+
+ match rpc
+ .call_typed(&XkeysendRequest {
+ extratlvs,
+ label: None,
+ maxdelay: None,
+ maxfee: None,
+ retry_for: None,
+ layers: None,
+ amount_msat: Amount::from_msat(params.amount),
+ destination: pubkey,
+ })
+ .await
+ {
+ Ok(o) => {
+ if let Some(ref mut bdg) = nwc_store.budget_msat {
+ *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
+ update_nwc_store(rpc, label, nwc_store)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ }
+
+ let preimage = hex::encode(o.payment_preimage.to_vec());
+
+ let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
+
+ Ok(nip47::PayKeysendResponse {
+ preimage,
+ fees_paid: Some(fees_paid),
+ })
+ }
+ Err(e) => match e.code {
+ Some(c) => match c {
+ 203 | 205 | 207 | 219 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::PaymentFailed,
+ message: e.to_string(),
+ }),
+ 209 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: e.to_string(),
+ }),
+ _ => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ },
+ None => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ },
+ }
+}
+
+async fn keysend(
+ rpc: &mut ClnRpc,
+ params: nip47::PayKeysendRequest,
+ pubkey: PublicKey,
+ mut nwc_store: NwcStore,
+ label: &str,
+) -> Result {
+ let mut extratlvs = TlvStream {
+ entries: Vec::new(),
+ };
+ for tlv in params.tlv_records {
+ extratlvs.entries.push(TlvEntry {
+ typ: tlv.tlv_type,
+ value: tlv.value.as_bytes().to_owned(),
+ });
+ }
+ let extratlvs = if extratlvs.entries.is_empty() {
+ None
+ } else {
+ Some(extratlvs)
+ };
+
+ match rpc
+ .call_typed(&KeysendRequest {
+ exemptfee: None,
+ extratlvs,
+ label: None,
+ maxdelay: None,
+ maxfee: None,
+ maxfeepercent: None,
+ retry_for: None,
+ routehints: None,
+ amount_msat: Amount::from_msat(params.amount),
+ destination: pubkey,
+ })
+ .await
+ {
+ Ok(o) => {
+ if let Some(ref mut bdg) = nwc_store.budget_msat {
+ *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
+ update_nwc_store(rpc, label, nwc_store)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ }
+
+ let preimage = hex::encode(o.payment_preimage.to_vec());
+
+ let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
+
+ Ok(nip47::PayKeysendResponse {
+ preimage,
+ fees_paid: Some(fees_paid),
+ })
+ }
+ Err(e) => match e.code {
+ Some(c) => match c {
+ 203 | 205 | 210 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::PaymentFailed,
+ message: e.to_string(),
+ }),
+ 206 => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::InsufficientBalance,
+ message: e.to_string(),
+ }),
+ _ => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ },
+ None => Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ }),
+ },
}
}
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index 5b5090c..c75c079 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -2,9 +2,11 @@ use std::{cmp::Reverse, str::FromStr};
use cln_plugin::Plugin;
use cln_rpc::{
+ ClnRpc,
model::{
requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest},
responses::{
+ DecodeResponse,
DecodeType,
ListinvoicesInvoices,
ListinvoicesInvoicesStatus,
@@ -13,13 +15,13 @@ use cln_rpc::{
},
},
primitives::Sha256,
- ClnRpc,
};
-use nostr::{nips::nip47, Timestamp};
+use nostr::{Timestamp, nips::nip47};
+use tonic::transport::Channel;
use crate::{
- hold::{self, list_request::Constraint, ListRequest},
- structs::{PluginState, NOT_INV_ERR},
+ hold::{self, ListRequest, hold_client::HoldClient, list_request::Constraint},
+ structs::{NOT_INV_ERR, PluginState},
};
pub async fn lookup_invoice_response(
@@ -127,186 +129,7 @@ async fn lookup_invoice(
if holdinvoice_support {
let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
-
- let (hold_invoice, invoice_decoded) = if let Some(ph) = ¶ms.payment_hash {
- let payment_hash_hash = match hex::decode(ph) {
- Ok(p) => p,
- Err(_e) => {
- return Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: "Invalid payment hash".to_owned(),
- })
- }
- };
- let list_request = ListRequest {
- constraint: Some(Constraint::PaymentHash(payment_hash_hash)),
- };
- let hold_lookup = hold_client
- .list(list_request)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: format!("Could not fetch hold invoice: {e}"),
- })?
- .into_inner();
-
- if hold_lookup.invoices.len() != 1 {
- return Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: "Transaction not found".to_owned(),
- });
- }
-
- let hold_invoice = hold_lookup.invoices.into_iter().next().unwrap();
- let invoice_decoded = rpc
- .call_typed(&DecodeRequest {
- string: hold_invoice.invoice.clone(),
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
-
- (hold_invoice, invoice_decoded)
- } else {
- let invoice_decoded = rpc
- .call_typed(&DecodeRequest {
- string: params.invoice.unwrap(),
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
- let ph = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_payment_hash.unwrap(),
- DecodeType::BOLT11_INVOICE => invoice_decoded.payment_hash.unwrap().to_string(),
- _ => todo!(),
- };
- let payment_hash_hash = match hex::decode(&ph) {
- Ok(p) => p,
- Err(_e) => {
- return Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: "Invalid payment hash in invoice".to_owned(),
- })
- }
- };
-
- let list_request = ListRequest {
- constraint: Some(Constraint::PaymentHash(payment_hash_hash)),
- };
-
- let hold_lookup = hold_client
- .list(list_request)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: format!("Could not fetch hold invoice: {e}"),
- })?
- .into_inner();
-
- if hold_lookup.invoices.len() != 1 {
- return Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: "Transaction not found".to_owned(),
- });
- }
-
- let hold_invoice = hold_lookup.invoices.into_iter().next().unwrap();
- let invoice_decoded = rpc
- .call_typed(&DecodeRequest {
- string: hold_invoice.invoice.clone(),
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
- (hold_invoice, invoice_decoded)
- };
- let not_invoice_err = Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: NOT_INV_ERR.to_owned(),
- });
-
- let description = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
- DecodeType::BOLT11_INVOICE => invoice_decoded.description,
- _ => return not_invoice_err,
- };
- let description_hash = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => None,
- DecodeType::BOLT11_INVOICE => invoice_decoded.description_hash.map(|h| h.to_string()),
- _ => return not_invoice_err,
- };
-
- let created_at = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => {
- Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
- }
- DecodeType::BOLT11_INVOICE => Timestamp::from_secs(invoice_decoded.created_at.unwrap()),
- _ => return not_invoice_err,
- };
-
- let amount = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_amount_msat.unwrap().msat(),
- DecodeType::BOLT11_INVOICE => {
- if let Some(amt) = invoice_decoded.amount_msat {
- amt.msat()
- } else {
- // amount: `any` but have to put a value...
- 0
- }
- }
- _ => return not_invoice_err,
- };
-
- let expires_at = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => invoice_decoded
- .invoice_relative_expiry
- .map(|e_at| created_at + Timestamp::from_secs(u64::from(e_at))),
- DecodeType::BOLT11_INVOICE => invoice_decoded
- .expiry
- .map(|e_at| created_at + Timestamp::from_secs(e_at)),
- _ => return not_invoice_err,
- };
-
- let state = match hold_invoice.state() {
- hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
- hold::InvoiceState::Accepted => nip47::TransactionState::Accepted,
- hold::InvoiceState::Paid => nip47::TransactionState::Settled,
- hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
- };
-
- let settled_at = if hold_invoice.settled_at() != 0 {
- Some(Timestamp::from_secs(hold_invoice.settled_at()))
- } else {
- None
- };
-
- let preimage = if hold_invoice.state() == hold::InvoiceState::Paid {
- Some(hex::encode(hold_invoice.preimage()))
- } else {
- None
- };
-
- return Ok(nip47::LookupInvoiceResponse {
- transaction_type: Some(nip47::TransactionType::Incoming),
- invoice: Some(hold_invoice.invoice.clone()),
- description,
- description_hash,
- preimage,
- payment_hash: hex::encode(hold_invoice.payment_hash),
- amount,
- fees_paid: 0,
- created_at,
- expires_at,
- settled_at,
- metadata: None,
- state: Some(state),
- });
+ return lookup_holdinvoice(&mut hold_client, &mut rpc, params).await;
}
Err(nip47::NIP47Error {
@@ -315,6 +138,202 @@ async fn lookup_invoice(
})
}
+async fn lookup_holdinvoice(
+ hold_client: &mut HoldClient,
+ rpc: &mut ClnRpc,
+ params: nip47::LookupInvoiceRequest,
+) -> Result {
+ log::debug!("Looking up hold invoice for params {params:#?}");
+ let (hold_invoice, invoice_decoded) =
+ get_and_decode_holdinvoice(rpc, hold_client, params).await?;
+ let not_invoice_err = Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: NOT_INV_ERR.to_owned(),
+ });
+
+ let description = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description,
+ _ => return not_invoice_err,
+ };
+ let description_hash = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => None,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description_hash.map(|h| h.to_string()),
+ _ => return not_invoice_err,
+ };
+
+ let created_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
+ }
+ DecodeType::BOLT11_INVOICE => Timestamp::from_secs(invoice_decoded.created_at.unwrap()),
+ _ => return not_invoice_err,
+ };
+
+ let amount = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_amount_msat.unwrap().msat(),
+ DecodeType::BOLT11_INVOICE => {
+ if let Some(amt) = invoice_decoded.amount_msat {
+ amt.msat()
+ } else {
+ // amount: `any` but have to put a value...
+ 0
+ }
+ }
+ _ => return not_invoice_err,
+ };
+
+ let expires_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded
+ .invoice_relative_expiry
+ .map(|e_at| created_at + Timestamp::from_secs(u64::from(e_at))),
+ DecodeType::BOLT11_INVOICE => invoice_decoded
+ .expiry
+ .map(|e_at| created_at + Timestamp::from_secs(e_at)),
+ _ => return not_invoice_err,
+ };
+
+ let state = match hold_invoice.state() {
+ hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
+ hold::InvoiceState::Accepted => nip47::TransactionState::Accepted,
+ hold::InvoiceState::Paid => nip47::TransactionState::Settled,
+ hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
+ };
+
+ let settled_at = if hold_invoice.settled_at() != 0 {
+ Some(Timestamp::from_secs(hold_invoice.settled_at()))
+ } else {
+ None
+ };
+
+ let preimage = if hold_invoice.state() == hold::InvoiceState::Paid {
+ Some(hex::encode(hold_invoice.preimage()))
+ } else {
+ None
+ };
+
+ Ok(nip47::LookupInvoiceResponse {
+ transaction_type: Some(nip47::TransactionType::Incoming),
+ invoice: Some(hold_invoice.invoice.clone()),
+ description,
+ description_hash,
+ preimage,
+ payment_hash: hex::encode(hold_invoice.payment_hash),
+ amount,
+ fees_paid: 0,
+ created_at,
+ expires_at,
+ settled_at,
+ metadata: None,
+ state: Some(state),
+ })
+}
+
+async fn get_and_decode_holdinvoice(
+ rpc: &mut ClnRpc,
+ hold_client: &mut HoldClient,
+ params: nip47::LookupInvoiceRequest,
+) -> Result<(hold::Invoice, DecodeResponse), nip47::NIP47Error> {
+ if let Some(ph) = ¶ms.payment_hash {
+ let payment_hash_hash = match hex::decode(ph) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid payment hash".to_owned(),
+ });
+ }
+ };
+ let list_request = ListRequest {
+ constraint: Some(Constraint::PaymentHash(payment_hash_hash)),
+ };
+ let hold_lookup = hold_client
+ .list(list_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Could not fetch hold invoice: {e}"),
+ })?
+ .into_inner();
+
+ if hold_lookup.invoices.len() != 1 {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Transaction not found".to_owned(),
+ });
+ }
+
+ let hold_invoice = hold_lookup.invoices.into_iter().next().unwrap();
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+
+ Ok((hold_invoice, invoice_decoded))
+ } else {
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: params.invoice.unwrap(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ let ph = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_payment_hash.unwrap(),
+ DecodeType::BOLT11_INVOICE => invoice_decoded.payment_hash.unwrap().to_string(),
+ _ => todo!(),
+ };
+ let payment_hash_hash = match hex::decode(&ph) {
+ Ok(p) => p,
+ Err(_e) => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Invalid payment hash in invoice".to_owned(),
+ });
+ }
+ };
+
+ let list_request = ListRequest {
+ constraint: Some(Constraint::PaymentHash(payment_hash_hash)),
+ };
+
+ let hold_lookup = hold_client
+ .list(list_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Could not fetch hold invoice: {e}"),
+ })?
+ .into_inner();
+
+ if hold_lookup.invoices.len() != 1 {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Transaction not found".to_owned(),
+ });
+ }
+
+ let hold_invoice = hold_lookup.invoices.into_iter().next().unwrap();
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+ Ok((hold_invoice, invoice_decoded))
+ }
+}
+
pub async fn list_transactions_response(
plugin: Plugin,
params: nip47::ListTransactionsRequest,
@@ -389,112 +408,8 @@ async fn list_transactions(
if holdinvoice_support {
let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
-
- let lookup_request = ListRequest { constraint: None };
-
- let hold_lookup = hold_client
- .list(lookup_request)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: format!("Could not fetch hold invoices: {e}"),
- })?
- .into_inner();
-
- for hold_invoice in hold_lookup.invoices {
- let invoice_decoded = rpc
- .call_typed(&DecodeRequest {
- string: hold_invoice.invoice.clone(),
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
-
- let description = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
- DecodeType::BOLT11_INVOICE => invoice_decoded.description,
- _ => continue,
- };
- let description_hash = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => None,
- DecodeType::BOLT11_INVOICE => {
- invoice_decoded.description_hash.map(|h| h.to_string())
- }
- _ => continue,
- };
-
- let created_at = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => {
- Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
- }
- DecodeType::BOLT11_INVOICE => {
- Timestamp::from_secs(invoice_decoded.created_at.unwrap())
- }
- _ => continue,
- };
-
- let amount = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => {
- invoice_decoded.invoice_amount_msat.unwrap().msat()
- }
- DecodeType::BOLT11_INVOICE => {
- if let Some(amt) = invoice_decoded.amount_msat {
- amt.msat()
- } else {
- // amount: `any` but have to put a value...
- 0
- }
- }
- _ => continue,
- };
-
- let expires_at = match invoice_decoded.item_type {
- DecodeType::BOLT12_INVOICE => invoice_decoded
- .invoice_relative_expiry
- .map(|e_at| created_at + Timestamp::from_secs(u64::from(e_at))),
- DecodeType::BOLT11_INVOICE => invoice_decoded
- .expiry
- .map(|e_at| created_at + Timestamp::from_secs(e_at)),
- _ => continue,
- };
-
- let state = match hold_invoice.state() {
- hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
- hold::InvoiceState::Accepted => nip47::TransactionState::Accepted,
- hold::InvoiceState::Paid => nip47::TransactionState::Settled,
- hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
- };
-
- let settled_at = if hold_invoice.settled_at() != 0 {
- Some(Timestamp::from_secs(hold_invoice.settled_at()))
- } else {
- None
- };
-
- let preimage = if hold_invoice.state() == hold::InvoiceState::Paid {
- Some(hex::encode(hold_invoice.preimage()))
- } else {
- None
- };
-
- transactions.push(nip47::LookupInvoiceResponse {
- transaction_type: Some(nip47::TransactionType::Incoming),
- invoice: Some(hold_invoice.invoice.clone()),
- description,
- description_hash,
- preimage,
- payment_hash: hex::encode(hold_invoice.payment_hash),
- amount,
- fees_paid: 0,
- created_at,
- expires_at,
- settled_at,
- metadata: None,
- state: Some(state),
- });
- }
+ list_holdinvoices_to_transactions(&mut hold_client, &mut rpc, &mut transactions)
+ .await?;
}
}
@@ -548,6 +463,114 @@ async fn list_transactions(
Ok(transactions)
}
+async fn list_holdinvoices_to_transactions(
+ hold_client: &mut HoldClient,
+ rpc: &mut ClnRpc,
+ transactions: &mut Vec,
+) -> Result<(), nip47::NIP47Error> {
+ let lookup_request = ListRequest { constraint: None };
+
+ let hold_lookup = hold_client
+ .list(lookup_request)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: format!("Could not fetch hold invoices: {e}"),
+ })?
+ .into_inner();
+
+ for hold_invoice in hold_lookup.invoices {
+ let invoice_decoded = rpc
+ .call_typed(&DecodeRequest {
+ string: hold_invoice.invoice.clone(),
+ })
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+
+ let description = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description,
+ _ => continue,
+ };
+ let description_hash = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => None,
+ DecodeType::BOLT11_INVOICE => invoice_decoded.description_hash.map(|h| h.to_string()),
+ _ => continue,
+ };
+
+ let created_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => {
+ Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
+ }
+ DecodeType::BOLT11_INVOICE => Timestamp::from_secs(invoice_decoded.created_at.unwrap()),
+ _ => continue,
+ };
+
+ let amount = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_amount_msat.unwrap().msat(),
+ DecodeType::BOLT11_INVOICE => {
+ if let Some(amt) = invoice_decoded.amount_msat {
+ amt.msat()
+ } else {
+ // amount: `any` but have to put a value...
+ 0
+ }
+ }
+ _ => continue,
+ };
+
+ let expires_at = match invoice_decoded.item_type {
+ DecodeType::BOLT12_INVOICE => invoice_decoded
+ .invoice_relative_expiry
+ .map(|e_at| created_at + Timestamp::from_secs(u64::from(e_at))),
+ DecodeType::BOLT11_INVOICE => invoice_decoded
+ .expiry
+ .map(|e_at| created_at + Timestamp::from_secs(e_at)),
+ _ => continue,
+ };
+
+ let state = match hold_invoice.state() {
+ hold::InvoiceState::Unpaid => nip47::TransactionState::Pending,
+ hold::InvoiceState::Accepted => nip47::TransactionState::Accepted,
+ hold::InvoiceState::Paid => nip47::TransactionState::Settled,
+ hold::InvoiceState::Cancelled => nip47::TransactionState::Expired,
+ };
+
+ let settled_at = if hold_invoice.settled_at() != 0 {
+ Some(Timestamp::from_secs(hold_invoice.settled_at()))
+ } else {
+ None
+ };
+
+ let preimage = if hold_invoice.state() == hold::InvoiceState::Paid {
+ Some(hex::encode(hold_invoice.preimage()))
+ } else {
+ None
+ };
+
+ transactions.push(nip47::LookupInvoiceResponse {
+ transaction_type: Some(nip47::TransactionType::Incoming),
+ invoice: Some(hold_invoice.invoice.clone()),
+ description,
+ description_hash,
+ preimage,
+ payment_hash: hex::encode(hold_invoice.payment_hash),
+ amount,
+ fees_paid: 0,
+ created_at,
+ expires_at,
+ settled_at,
+ metadata: None,
+ state: Some(state),
+ });
+ }
+
+ Ok(())
+}
+
async fn make_lookup_response_from_listinvoices(
rpc: &mut ClnRpc,
list_invoice: ListinvoicesInvoices,
@@ -557,10 +580,12 @@ async fn make_lookup_response_from_listinvoices(
message: NOT_INV_ERR.to_owned(),
});
- let invstring = if list_invoice.bolt11.is_some() {
- list_invoice.bolt11.as_ref().unwrap()
+ let invstring = if let Some(bolt11) = list_invoice.bolt11 {
+ bolt11
+ } else if let Some(bolt12) = list_invoice.bolt12 {
+ bolt12
} else {
- list_invoice.bolt12.as_ref().unwrap()
+ return not_invoice_err;
};
let invoice_decoded = rpc
.call_typed(&DecodeRequest {
@@ -628,7 +653,7 @@ async fn make_lookup_response_from_listinvoices(
Ok(nip47::LookupInvoiceResponse {
transaction_type: Some(nip47::TransactionType::Incoming),
- invoice: Some(invstring.to_owned()),
+ invoice: Some(invstring),
description,
description_hash,
preimage,
diff --git a/src/nwc_notifications.rs b/src/nwc_notifications.rs
index 34d2ca5..164e246 100644
--- a/src/nwc_notifications.rs
+++ b/src/nwc_notifications.rs
@@ -22,15 +22,13 @@ use nostr::{
Tag,
Timestamp,
event::FinalizeEventAsync,
- key::{Keys, PublicKey, SecretKey},
nips::{nip04, nip44, nip47},
};
-use nostr_sdk::client::Client;
use crate::{
OPT_NOTIFICATIONS,
hold::{InvoiceState, ListRequest, TrackRequest, list_request::Constraint},
- structs::{NOT_INV_ERR, PluginState},
+ structs::{NOT_INV_ERR, PluginState, WalletService},
};
pub async fn payment_received_handler(
@@ -66,10 +64,14 @@ pub async fn payment_received_handler(
let invoice = invoice_resp
.first()
.ok_or_else(|| anyhow!("invoice not found"))?;
- let invstring = if invoice.bolt11.is_some() {
- invoice.bolt11.as_ref().unwrap()
+ let invstring = if let Some(bolt11) = &invoice.bolt11 {
+ bolt11.clone()
+ } else if let Some(bolt12) = &invoice.bolt12 {
+ bolt12.clone()
} else {
- invoice.bolt12.as_ref().unwrap()
+ return Err(anyhow!(
+ "Listinvoices has neither returned bolt11 or bolt12 field"
+ ));
};
let invoice_decoded = rpc
@@ -83,8 +85,8 @@ pub async fn payment_received_handler(
let clients = plugin.state().handles.lock().await;
- for (client, client_pubkey, wallet_secret) in clients.values() {
- send_notification(¬ification, client, client_pubkey.clone(), wallet_secret).await?;
+ for wallet_service in clients.values() {
+ send_notification(¬ification, wallet_service).await?;
}
Ok(())
@@ -92,7 +94,7 @@ pub async fn payment_received_handler(
fn make_payment_received_from_listinvoices(
invoice: &ListinvoicesInvoices,
- invstring: &str,
+ invstring: String,
invoice_decoded: DecodeResponse,
) -> Result {
let not_invoice_err = Err(anyhow!(NOT_INV_ERR.to_owned()));
@@ -160,7 +162,7 @@ fn make_payment_received_from_listinvoices(
notification_type: nip47::NotificationType::PaymentReceived,
notification: nip47::NotificationResult::PaymentReceived(nip47::PaymentNotification {
transaction_type: Some(nip47::TransactionType::Incoming),
- invoice: invstring.to_owned(),
+ invoice: invstring,
description: description.clone(),
description_hash: description_hash.clone(),
preimage: preimage.clone(),
@@ -220,8 +222,8 @@ pub async fn payment_sent_handler(
let clients = plugin.state().handles.lock().await;
- for (client, client_pubkey, wallet_secret) in clients.values() {
- send_notification(¬ification, client, client_pubkey.clone(), wallet_secret).await?;
+ for wallet_service in clients.values() {
+ send_notification(¬ification, wallet_service).await?;
}
Ok(())
@@ -342,18 +344,19 @@ async fn make_payment_sent_from_listpays(
async fn send_notification(
notification: &String,
- client: &Client,
- client_pubkey: PublicKey,
- wallet_secret: &Keys,
+ wallet_service: &WalletService,
) -> Result<(), anyhow::Error> {
log::debug!("NOTIFICATION: {notification}");
- let content_encrypted_nip04 =
- nip04::encrypt(wallet_secret.secret_key(), &client_pubkey, notification)?;
+ let content_encrypted_nip04 = nip04::encrypt(
+ wallet_service.wallet_secret.secret_key(),
+ &wallet_service.client_pubkey,
+ notification,
+ )?;
let event_nip04 = EventBuilder::new(Kind::from_u16(23196), content_encrypted_nip04)
- .tag(Tag::public_key(client_pubkey))
- .finalize_async(wallet_secret)
+ .tag(Tag::public_key(wallet_service.client_pubkey))
+ .finalize_async(&wallet_service.wallet_secret)
.await?;
- let nip04_result = client.send_event(&event_nip04).await?;
+ let nip04_result = wallet_service.client.send_event(&event_nip04).await?;
if nip04_result.success.is_empty() {
log::warn!(
"None of the relays accepted our nip04 notification: {}",
@@ -367,16 +370,16 @@ async fn send_notification(
log::debug!("NIP04 NOTIFICATION SENT: {event_nip04:?}");
let content_encrypted_nip44 = nip44::encrypt(
- wallet_secret.secret_key(),
- &client_pubkey,
+ wallet_service.wallet_secret.secret_key(),
+ &wallet_service.client_pubkey,
notification,
nip44::Version::V2,
)?;
let event_nip44 = EventBuilder::new(Kind::from_u16(23197), content_encrypted_nip44)
- .tag(Tag::public_key(client_pubkey))
- .finalize_async(wallet_secret)
+ .tag(Tag::public_key(wallet_service.client_pubkey))
+ .finalize_async(&wallet_service.wallet_secret)
.await?;
- let nip44_result = client.send_event(&event_nip44).await?;
+ let nip44_result = wallet_service.client.send_event(&event_nip44).await?;
if nip44_result.success.is_empty() {
log::warn!(
"None of the relays accepted our nip44 notification: {}",
@@ -392,6 +395,7 @@ async fn send_notification(
Ok(())
}
+#[allow(clippy::too_many_lines)]
pub async fn holdinvoice_accepted_handler(
plugin: Plugin,
payment_hash: Vec,
@@ -514,8 +518,8 @@ pub async fn holdinvoice_accepted_handler(
};
let notification = serde_json::to_string(&content).unwrap();
- for (client, client_pubkey, wallet_secret) in clients.values() {
- send_notification(¬ification, client, client_pubkey.clone(), wallet_secret).await?;
+ for wallet_service in clients.values() {
+ send_notification(¬ification, wallet_service).await?;
}
Ok(())
}
diff --git a/src/rpc.rs b/src/rpc.rs
index 06387aa..8b46ad0 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -155,7 +155,7 @@ pub async fn nwc_budget(
clients
.get(&label)
.ok_or_else(|| anyhow!("No client found for label: {label}"))?
- .0
+ .client
.clone(),
method_capabilities,
wallet_keys,
diff --git a/src/structs.rs b/src/structs.rs
index 22c166b..8f3b86f 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -15,8 +15,7 @@ pub const NOT_INV_ERR: &str = "Not an invoice or invalid invoice";
#[derive(Clone)]
pub struct PluginState {
pub config: Arc>,
- pub handles:
- Arc>>,
+ pub handles: Arc>>,
pub rpc_lock: Arc>,
pub budget_jobs: Arc>>>,
pub hold_client: Arc>>>,
@@ -33,6 +32,12 @@ impl PluginState {
}
}
+pub struct WalletService {
+ pub client: client::Client,
+ pub client_pubkey: nostr::PublicKey,
+ pub wallet_secret: nostr::Keys,
+}
+
#[derive(Clone, Debug)]
pub struct Config {
pub relays: Vec,
diff --git a/tests/pyproject.toml b/tests/pyproject.toml
index 874fadb..70483b9 100644
--- a/tests/pyproject.toml
+++ b/tests/pyproject.toml
@@ -6,12 +6,12 @@ description = "python dependencies for running tests"
[dependency-groups]
dev = [
- "pytest>=7.4,<9",
+ "pytest>=8,<10",
"pytest-asyncio>=0.23.8,<2",
"pytest-xdist>=3.7,<4",
"pytest-timeout>=2.4,<3",
"nostr-sdk>=0.44",
- "pyln-testing>=25.5",
- "pyln-client>=25.5",
- "pyln-proto>=25.5",
+ "pyln-testing>=25.9",
+ "pyln-client>=25.9",
+ "pyln-proto>=25.9",
]
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
old mode 100755
new mode 100644
index 03210a9..9b46a41
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -1,43 +1,46 @@
+# ruff: noqa: DTZ005
+
+import asyncio
import hashlib
import inspect
import json
import logging
-import time
-import asyncio
import secrets
+import time
import uuid
+from collections.abc import Awaitable, Callable
from datetime import datetime, timedelta
-from typing import Any, Awaitable, Callable, Union
+from typing import Any, Union
import pytest
-from pyln.testing.fixtures import * # noqa: F403
-from pyln.testing.utils import RpcError, wait_for, TIMEOUT
-from util import generate_random_label, get_plugin, get_hold # noqa: F401
-
from nostr_sdk import (
Client,
- RelayUrl,
+ Event,
EventBuilder,
Filter,
- Event,
+ HandleNotification,
Keys,
KeysendTlvRecord,
Kind,
- HandleNotification,
ListTransactionsRequest,
LookupInvoiceRequest,
MakeInvoiceRequest,
+ Method,
NostrSdkError,
NostrSigner,
NostrWalletConnectUri,
Nwc,
PayInvoiceRequest,
PayKeysendRequest,
+ PublicKey,
+ RelayUrl,
Tag,
TagKind,
- Method,
- PublicKey,
+ TransactionType,
)
+from pyln.testing.fixtures import *
+from pyln.testing.utils import TIMEOUT, RpcError, wait_for
+from util import generate_random_label, get_hold, get_plugin # noqa: F401
LOGGER = logging.getLogger(__name__)
@@ -83,7 +86,7 @@ async def fetch_event_responses(
handler = NotificationHandler(events, stop_after)
task = asyncio.create_task(client.handle_notifications(handler))
- time.sleep(1)
+ await asyncio.sleep(1)
if inspect.iscoroutine(action):
action_result = await action
elif inspect.iscoroutinefunction(action):
@@ -123,7 +126,7 @@ async def fetch_info_event(
while events.len() < 1 and (datetime.now() - start_time) < timedelta(
seconds=TIMEOUT
):
- time.sleep(1)
+ await asyncio.sleep(1)
events = await client.fetch_events(
response_filter, timeout=timedelta(seconds=1)
)
@@ -135,7 +138,7 @@ async def fetch_info_event(
@pytest.mark.asyncio
async def test_get_balance(nostr_relay, node_factory, get_plugin): # noqa: F811
url = nostr_relay
- l1, l2 = node_factory.line_graph(
+ l1, _l2 = node_factory.line_graph(
2,
wait_for_announce=True,
opts=[
@@ -237,7 +240,7 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
},
)
l1.daemon.wait_for_log("All NWC's loaded")
- time.sleep(5)
+ await asyncio.sleep(5)
await client.connect()
info_event = await fetch_info_event(client, uri)
get_info = await nwc.get_info()
@@ -341,7 +344,7 @@ async def test_make_invoice(nostr_relay, node_factory, get_plugin): # noqa: F81
MakeInvoiceRequest(
amount=3001,
description="test2",
- description_hash=hashlib.sha256("test2".encode()).hexdigest(),
+ description_hash=hashlib.sha256(b"test2").hexdigest(),
expiry=120,
)
)
@@ -367,7 +370,7 @@ async def test_make_invoice(nostr_relay, node_factory, get_plugin): # noqa: F81
MakeInvoiceRequest(
amount=3001,
description=None,
- description_hash=hashlib.sha256("test2".encode()).hexdigest(),
+ description_hash=hashlib.sha256(b"test2").hexdigest(),
expiry=120,
)
)
@@ -378,7 +381,7 @@ async def test_make_invoice(nostr_relay, node_factory, get_plugin): # noqa: F81
MakeInvoiceRequest(
amount=3001,
description="test1",
- description_hash=hashlib.sha256("test2".encode()).hexdigest(),
+ description_hash=hashlib.sha256(b"test2").hexdigest(),
expiry=120,
)
)
@@ -562,7 +565,7 @@ async def test_lookup_invoice(nostr_relay, node_factory, get_plugin): # noqa: F
MakeInvoiceRequest(
amount=3001,
description="test2",
- description_hash=hashlib.sha256("test2".encode()).hexdigest(),
+ description_hash=hashlib.sha256(b"test2").hexdigest(),
expiry=1000,
)
)
@@ -584,9 +587,7 @@ async def test_lookup_invoice(nostr_relay, node_factory, get_plugin): # noqa: F
assert invoice_lookup.created_at.as_secs() == pytest.approx(
invoice_decode["created_at"], abs=3
)
- assert (
- invoice_lookup.description_hash == hashlib.sha256("test2".encode()).hexdigest()
- )
+ assert invoice_lookup.description_hash == hashlib.sha256(b"test2").hexdigest()
assert invoice_lookup.expires_at.as_secs() == pytest.approx(
listpays_rpc["expires_at"], abs=3
)
@@ -613,9 +614,7 @@ async def test_lookup_invoice(nostr_relay, node_factory, get_plugin): # noqa: F
assert invoice_lookup.created_at.as_secs() == pytest.approx(
invoice_decode["created_at"], abs=3
)
- assert (
- invoice_lookup.description_hash == hashlib.sha256("test2".encode()).hexdigest()
- )
+ assert invoice_lookup.description_hash == hashlib.sha256(b"test2").hexdigest()
assert invoice_lookup.expires_at.as_secs() == pytest.approx(
listpays_rpc["expires_at"], abs=3
)
@@ -693,9 +692,9 @@ async def test_list_transactions(nostr_relay, node_factory, get_plugin): # noqa
],
)
l1.rpc.call(
- "pay",
+ "xpay",
{
- "bolt11": l2.rpc.call(
+ "invstring": l2.rpc.call(
"invoice",
{
"amount_msat": 500000000,
@@ -710,7 +709,7 @@ async def test_list_transactions(nostr_relay, node_factory, get_plugin): # noqa
l2.rpc.call("listpeerchannels", [l1.info["id"]])["channels"][0][
"spendable_msat"
]
- > 30001
+ > 400000000
)
)
uri_str = l1.rpc.call("nip47-create", ["test1"])["uri"]
@@ -741,7 +740,7 @@ async def test_list_transactions(nostr_relay, node_factory, get_plugin): # noqa
amount=3000, description="test2", description_hash=None, expiry=None
)
)
- result = l2.rpc.call("pay", [invoice.invoice])
+ result = l2.rpc.call("xpay", [invoice.invoice])
invoice = await nwc.make_invoice(
MakeInvoiceRequest(
@@ -762,19 +761,23 @@ async def test_list_transactions(nostr_relay, node_factory, get_plugin): # noqa
)
assert len(result) == 22
for tx in result:
- tx.description is not None
- tx.invoice is not None
- tx.amount is not None
- tx.created_at is not None
- tx.description_hash is None
- tx.expires_at is None
- tx.preimage is not None
- tx.settled_at is not None
- tx.metadata is None
- tx.transaction_type is not None
- tx.state is not None
- tx.payment_hash is not None
- tx.fees_paid is not None
+ assert tx.description is not None
+ assert tx.invoice is not None
+ assert tx.amount is not None
+ assert tx.created_at is not None
+ assert tx.description_hash is None
+ assert tx.preimage is not None
+ assert tx.settled_at is not None
+ assert tx.metadata is None
+ assert tx.transaction_type is not None
+ assert tx.state is not None
+ assert tx.payment_hash is not None
+ assert tx.fees_paid is not None
+
+ if tx.transaction_type == TransactionType.INCOMING:
+ assert tx.expires_at is not None
+ else:
+ assert tx.expires_at is None
@pytest.mark.asyncio
@@ -927,7 +930,7 @@ async def test_notifications(nostr_relay, node_factory, get_plugin): # noqa: F8
},
)
l1.daemon.wait_for_log("All NWC's loaded")
- time.sleep(3)
+ await asyncio.sleep(3)
await client.connect()
await fetch_info_event(client, uri)
@@ -940,7 +943,7 @@ async def test_notifications(nostr_relay, node_factory, get_plugin): # noqa: F8
},
)
with pytest.raises(AssertionError, match="0 == 1"):
- (responses3, pay3) = await fetch_event_responses(
+ (_responses3, _pay3) = await fetch_event_responses(
client,
client_pubkey,
23196,
@@ -1036,7 +1039,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
},
)
l1.daemon.wait_for_log("All NWC's loaded")
- time.sleep(3)
+ await asyncio.sleep(3)
uri = NostrWalletConnectUri.parse(uri_str)
signer = NostrSigner.keys(Keys(uri.secret()))
client = Client(signer)
@@ -1066,7 +1069,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
},
)
l1.daemon.wait_for_log("All NWC's loaded")
- time.sleep(3)
+ await asyncio.sleep(3)
await client.connect()
await fetch_info_event(client, uri)
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
@@ -1107,7 +1110,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
PayInvoiceRequest(id=None, amount=None, invoice=invoice_exceeded["bolt11"])
)
- time.sleep(11)
+ await asyncio.sleep(11)
list = l1.rpc.call("nip47-list", ["test1"])[0]
assert list["test1"]["budget_msat"] == 3000
@@ -1138,7 +1141,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
},
)
l1.daemon.wait_for_log("All NWC's loaded")
- time.sleep(3)
+ await asyncio.sleep(3)
await client.connect()
await fetch_info_event(client, uri)
@@ -1147,7 +1150,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
PayInvoiceRequest(id=None, amount=None, invoice=invoice_exceeded["bolt11"])
)
- time.sleep(11)
+ await asyncio.sleep(11)
list = l1.rpc.call("nip47-list", ["test1"])[0]
assert list["test1"]["budget_msat"] == 3000
@@ -1242,7 +1245,7 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
== "payment_received payment_sent"
)
- time.sleep(18)
+ await asyncio.sleep(18)
balance = await nwc.get_balance()
assert balance == 5000
@@ -1706,7 +1709,7 @@ async def test_hold_invoice(
start_time = datetime.now()
while (datetime.now() - start_time) < timedelta(seconds=10):
- time.sleep(1)
+ await asyncio.sleep(1)
try:
await nwc.lookup_invoice(
LookupInvoiceRequest(
@@ -1757,7 +1760,7 @@ async def test_hold_invoice(
start_time = datetime.now()
while (datetime.now() - start_time) < timedelta(seconds=10):
- time.sleep(1)
+ await asyncio.sleep(1)
try:
await nwc.lookup_invoice(
LookupInvoiceRequest(
diff --git a/tests/uv.lock b/tests/uv.lock
index 7baa4f7..d90c9ac 100644
--- a/tests/uv.lock
+++ b/tests/uv.lock
@@ -1,14 +1,9 @@
version = 1
revision = 3
requires-python = ">=3.10"
-
-[[package]]
-name = "asn1crypto"
-version = "1.5.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/de/cf/d547feed25b5244fcb9392e288ff9fdc3280b10260362fc45d37a798a6ee/asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c", size = 121080, upload-time = "2022-03-15T14:46:52.889Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/c9/7f/09065fd9e27da0eda08b4d6897f1c13535066174cc023af248fc2a8d5e5a/asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67", size = 105045, upload-time = "2022-03-15T14:46:51.055Z" },
+resolution-markers = [
+ "python_full_version >= '3.11'",
+ "python_full_version < '3.11'",
]
[[package]]
@@ -40,88 +35,88 @@ wheels = [
[[package]]
name = "bitarray"
-version = "3.8.1"
+version = "3.9.2"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/fc/47/b5da717e7bbe97a6dc4c986f053ca55fd3276078d78f68f9e8b417d1425a/bitarray-3.8.1.tar.gz", hash = "sha256:f90bb3c680804ec9630bcf8c0965e54b4de84d33b17d7da57c87c30f0c64c6f5", size = 152471, upload-time = "2026-04-02T16:29:01.712Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/53/71/dd598d2d546d11d7aca6cd25f05875e2dad194df0a663f1892690d4fb90d/bitarray-3.9.2.tar.gz", hash = "sha256:37342f81c8f8e10ee5d1e23d5eda2e8dbd9d8d3a9d90e8285181fad57f21cdc1", size = 160932, upload-time = "2026-07-25T06:39:21.234Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ff/fc/4352b1dd55a50c85f7b502c011d40279a66a05eb0c6a5d3d44160838d9a4/bitarray-3.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:30d42c34da2974a5e2e0b51c57ecf89892c1e83ed67e1084d1e27eefc27add91", size = 149074, upload-time = "2026-04-02T16:26:16.319Z" },
- { url = "https://files.pythonhosted.org/packages/34/06/104c9ff50e5230f6581056d6f4b0d1e0db14aba41549cae4b0541be0369c/bitarray-3.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0793c51d3b1c7410bde1f7254fff71fabff1bc0cdeba1fa51319ac4e7931df3d", size = 146031, upload-time = "2026-04-02T16:26:18.453Z" },
- { url = "https://files.pythonhosted.org/packages/65/0b/99d65fa6ceb3616c4b96ab9fef2dcd4994ad05fa48f595706ba001f13ba7/bitarray-3.8.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133648c3405564e7fef9103f1768cb018de1b4976f3d8beff09cd4acea73bfe4", size = 325129, upload-time = "2026-04-02T16:26:19.77Z" },
- { url = "https://files.pythonhosted.org/packages/18/d4/e0913c6b15fbd1e6b4d60a541a6784eb5d8f1fddcbcbb8c076240f665f2e/bitarray-3.8.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4fd3399eaf6f1c77ea3132611efbc3d7a8c0eb899793387b3266be221dc75fd", size = 353126, upload-time = "2026-04-02T16:26:21.274Z" },
- { url = "https://files.pythonhosted.org/packages/49/1b/0fd86dece4eca8078a99e54ca01183d5b660195dea8f2c8ad5740b190e9f/bitarray-3.8.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3b9790ae107fc8648155f120e80a58ef8e94424efefff5b355de84061de6a18b", size = 363588, upload-time = "2026-04-02T16:26:22.638Z" },
- { url = "https://files.pythonhosted.org/packages/ec/2d/e62ddf9e52a0124a19f2cd83be5dfa256c6c1f20722fb0bb4b0aed51bb0b/bitarray-3.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:af01133e78e5528ee282ceb1cf4bc54aecb937c2001913e751452ad7dffbbeb1", size = 331725, upload-time = "2026-04-02T16:26:24.296Z" },
- { url = "https://files.pythonhosted.org/packages/cd/fc/ea1c532169d56747c128f4e0256a3ad1f0c91ed00ca83cdf93964a60fec3/bitarray-3.8.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2da2ca9495668ab77132a911f6bd530d2bfe686d10467584894efc3b66e9ffb5", size = 322939, upload-time = "2026-04-02T16:26:25.904Z" },
- { url = "https://files.pythonhosted.org/packages/5b/01/8fe68993779f077c713fc4c21c0d9ba2719beeea596bcdc37f9660b6f181/bitarray-3.8.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:72a0e87b2196120523fc6194ca6b580fcffa12d7daa4d57a16d7838e60f82d0e", size = 351084, upload-time = "2026-04-02T16:26:27.396Z" },
- { url = "https://files.pythonhosted.org/packages/96/c5/f5cb62b60e0da428ef9457e7e1d9a3d3d8874b4f0f925adfff4b9ab3a319/bitarray-3.8.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:defa3c12cb06b2fd2066a9e21bf00aab96465be84d9585c8c05195f080510506", size = 347489, upload-time = "2026-04-02T16:26:28.935Z" },
- { url = "https://files.pythonhosted.org/packages/88/71/bb9baadbdd305f80def4220ce38266f53404433661492fc2c3d894129bfb/bitarray-3.8.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7eae9e763fbd32f19f2a66dfc2e37906f8422e0c4ad4a6c9dcf9d3246740812e", size = 328394, upload-time = "2026-04-02T16:26:30.585Z" },
- { url = "https://files.pythonhosted.org/packages/0c/1a/c4d487b029488bebef38a4c04df34294d27f313b5ab3491aa3a051394f24/bitarray-3.8.1-cp310-cp310-win32.whl", hash = "sha256:3b9358f6437a5fa0c765ffae5810c9830547baf4bcf469438b82845c3f33f998", size = 143245, upload-time = "2026-04-02T16:26:32.414Z" },
- { url = "https://files.pythonhosted.org/packages/98/ae/adadedf7cdd49fb8d81b8013d3471c193d6208035a0748205c808b1709cd/bitarray-3.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:6f92d12a46b2a67d56194bb5d226dabf586b386d1f1a5e25be5b745a3080dbba", size = 149976, upload-time = "2026-04-02T16:26:33.868Z" },
- { url = "https://files.pythonhosted.org/packages/26/de/2a7a8c2868d85e671a6cdb5282bbb299d98cdc0b4c4ade0cfa9a2a21d91d/bitarray-3.8.1-cp310-cp310-win_arm64.whl", hash = "sha256:8e12d50d4d65c74bd877e15c276992263b878456a7cfcf72521e7205a553557f", size = 146729, upload-time = "2026-04-02T16:26:35.216Z" },
- { url = "https://files.pythonhosted.org/packages/05/5c/32ace44d0313b4a9986d2abc3a1349744920dafcfb6a4e454a10ed09ef5a/bitarray-3.8.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:660e11b9932f58f10151d0febd11f77d3b0d48d6fa4dd4686d8983f40187101e", size = 149069, upload-time = "2026-04-02T16:26:36.671Z" },
- { url = "https://files.pythonhosted.org/packages/6d/85/7bd0a218478f0a226ddfb756dd64286f8ee3c61a17991a1a50aae8d89dca/bitarray-3.8.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb1df55f5700187c6db4b47dbdaf8a0653a111341ac7fccc596b397aa3399e65", size = 146036, upload-time = "2026-04-02T16:26:38.179Z" },
- { url = "https://files.pythonhosted.org/packages/e8/e9/e4e6aec6874efac185959f4627b6a61a88c0dad3ec92eee433fd395daa78/bitarray-3.8.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:838fd67b3d00c5a64181073282a2c0bf8f76465da4844d5e79d2dbbc64c987dc", size = 333036, upload-time = "2026-04-02T16:26:39.723Z" },
- { url = "https://files.pythonhosted.org/packages/50/5f/d493eb77f79b58eaa489e9e032aa1c91f6af844287b341c6be681df11b0d/bitarray-3.8.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5743f532e408cfd716fa16776b5a6447b83ff2cf39021fb5f8d052aa0f331508", size = 361247, upload-time = "2026-04-02T16:26:41.023Z" },
- { url = "https://files.pythonhosted.org/packages/24/a3/2e3f33c66f61754b5bb4724d54c9c1122699facc580bcb416d44f1164ffc/bitarray-3.8.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0c8c66f5d8055cb84ad0ea14af57b3579cb0b6db589f2086f5e33f0922cf2354", size = 371922, upload-time = "2026-04-02T16:26:42.373Z" },
- { url = "https://files.pythonhosted.org/packages/05/03/4dfca9a69dfa69cde6fdbcfafbc039e069e105ea2443688177f6873d8444/bitarray-3.8.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8c3fe25871f1758519a3ad8dcafb1bd95c5d1aaeb122e6492ac739ab11fa5907", size = 339203, upload-time = "2026-04-02T16:26:43.915Z" },
- { url = "https://files.pythonhosted.org/packages/14/5d/a2275da6c935893f275624c88afab6cdd5b6aa916d0b45c50dd400cafb20/bitarray-3.8.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e9ff57452fcadfd1a379314234657b8f4e9967ae64480ddf7c2fd82139bc8cf8", size = 330956, upload-time = "2026-04-02T16:26:45.675Z" },
- { url = "https://files.pythonhosted.org/packages/2d/fd/7f4041c7a7e94ef3e7de86fdb4102d3fe366998b507de77ba0fe5dff6c44/bitarray-3.8.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4e34f1cb6cdb036c5f4a839a2b74419f75fa36177a70c4bab2867f48973cbe44", size = 358882, upload-time = "2026-04-02T16:26:47.327Z" },
- { url = "https://files.pythonhosted.org/packages/29/4e/2d0c381327c0f5bc49681b799bbe7d80d5e629079f9609a79d39da6e8b8f/bitarray-3.8.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:698c37fca3761af69a09a1d39cc0492f7e8cb9e263af39a288dce8f3b8a9e2bc", size = 355761, upload-time = "2026-04-02T16:26:48.665Z" },
- { url = "https://files.pythonhosted.org/packages/e8/d9/66644d45d9f844d1c78b80f3517c8717ac4b4d9853ec61bd02b3cabc06e6/bitarray-3.8.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:81ede1f094f26eeaff62e029ff1bc4e84e9d568f20d4669f64dcf7c7b18a28fc", size = 336422, upload-time = "2026-04-02T16:26:49.988Z" },
- { url = "https://files.pythonhosted.org/packages/ad/7d/4ea3fd2424535630d4d236bc0c721621260b39878eed669dbc1deb5c6b22/bitarray-3.8.1-cp311-cp311-win32.whl", hash = "sha256:8a345b5dc8ab8cafdf338e08530d48fe3f73df27f4ff569be793c7a7e7bb6b6b", size = 143391, upload-time = "2026-04-02T16:26:51.69Z" },
- { url = "https://files.pythonhosted.org/packages/d0/4f/46309fcf9e1793c7184e3fc1aa73d7daf2b6a2b0fa1efbcf8d497101690e/bitarray-3.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:ddcd25a1f72b2b545fb27e17882046a6c161f3f24514b2e028c00c58ed73a2dd", size = 150143, upload-time = "2026-04-02T16:26:52.9Z" },
- { url = "https://files.pythonhosted.org/packages/0e/1e/10289fb8e44fdd2d01adcc24d64b5c45ead709fbec76ee973f42e22b3059/bitarray-3.8.1-cp311-cp311-win_arm64.whl", hash = "sha256:dc2cab92c42991b711132bc52405680e075d1505d4356c4468bc6e9c93d49137", size = 147024, upload-time = "2026-04-02T16:26:54.151Z" },
- { url = "https://files.pythonhosted.org/packages/5d/4f/6ab3767b6642a6cbee4353f10a71fe25ade9899d539fae47c3d50686ebe2/bitarray-3.8.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4494c599effa16064f2b600f6eb28115182d6826847d795a55691339788d8a4d", size = 149202, upload-time = "2026-04-02T16:26:55.635Z" },
- { url = "https://files.pythonhosted.org/packages/eb/53/22bfffd13dd0a266f90011338b24eec45f25c91d37155bb2aa330351e17d/bitarray-3.8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ff2ca039a161d49a8c713f5380def315c6f793df5fe348b94782b1dbee37a644", size = 145999, upload-time = "2026-04-02T16:26:56.849Z" },
- { url = "https://files.pythonhosted.org/packages/5d/dc/60aff29c88b648e18248921001cf9d7169abeda4d8db96f2dc1a24ed98ca/bitarray-3.8.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df3ffa6ef88166bb36f5d1492e71e664868b9b8b6afd55821e0ac0cb96625441", size = 335945, upload-time = "2026-04-02T16:26:58.403Z" },
- { url = "https://files.pythonhosted.org/packages/83/c8/225380610a01ae0d8f2f5256e531bae7135b2ade6f4607156424718ec43a/bitarray-3.8.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:478b9f0ea86f957624dd2b159066855716f78db94666e9b04babe85fc013e01b", size = 364213, upload-time = "2026-04-02T16:26:59.742Z" },
- { url = "https://files.pythonhosted.org/packages/6c/df/83899be9a74ec5878972e8b636f645ef1771e146c6425a161fdafdd74aaa/bitarray-3.8.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e127b2e7fc533728295196f9265d12834530f475bc6cd6f74619df415d04b8b1", size = 375409, upload-time = "2026-04-02T16:27:01.081Z" },
- { url = "https://files.pythonhosted.org/packages/6c/93/38bc15cb097107d220a942eb66dc50882496d7da54f41e5eea6c31b1c443/bitarray-3.8.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6ef49462a615de062dcac8281944d0b036fe1e9c96a6c690bf6cf5e4b5488f0e", size = 343645, upload-time = "2026-04-02T16:27:02.577Z" },
- { url = "https://files.pythonhosted.org/packages/5a/c3/75fae6991946f8bf643ec50233432ea81b5b65bfdb2918b09d7e37605380/bitarray-3.8.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4da256fc567a57ded2a4aa962fc9e9d430ab740e5c67be9e98a63ef4eb467f2f", size = 333844, upload-time = "2026-04-02T16:27:03.963Z" },
- { url = "https://files.pythonhosted.org/packages/b7/7e/649e7c3bb12ba938c387bcad6a6c0b84312663c9807ec1457888936690d8/bitarray-3.8.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b46b7aec9272fd81c984e723e599957629a91204120b3e7f0933f138e0792fdf", size = 361267, upload-time = "2026-04-02T16:27:05.361Z" },
- { url = "https://files.pythonhosted.org/packages/cd/5f/db0fb71a7c6c3ef047b84256157e96fa35e10ed8b79b80e892d354ab37f6/bitarray-3.8.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2dc07dab252c63c4f6600e200b26fa05207db6b650d41ae88ab0cec4d6c59459", size = 359373, upload-time = "2026-04-02T16:27:07.106Z" },
- { url = "https://files.pythonhosted.org/packages/b6/b6/a082d84cba7ba509b48d160034f6a2d31df6bf4fff0471801e888bba96c9/bitarray-3.8.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:29c8c10a49d6a9586f592116618b99c3dabcb24d881b7a649e0691ef87f314c4", size = 340633, upload-time = "2026-04-02T16:27:08.794Z" },
- { url = "https://files.pythonhosted.org/packages/7f/b7/1ba7ec1f3aa62933dfef505b09de0b75778a3cb05984ee8bb798539381db/bitarray-3.8.1-cp312-cp312-win32.whl", hash = "sha256:67125404d12547443d74113862a80c10310cf875aff8dbfc5548fee1d9737123", size = 143521, upload-time = "2026-04-02T16:27:10.423Z" },
- { url = "https://files.pythonhosted.org/packages/82/30/5ff9d30a1121810f336517e51b1cbdea0fa92e92b142efe0741e335dc14e/bitarray-3.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:ba0339d6aa80615a17f47fabc5700485e9469121d658458f95cdd2003288c28b", size = 150451, upload-time = "2026-04-02T16:27:11.993Z" },
- { url = "https://files.pythonhosted.org/packages/a6/08/51e49eb09ca45ecda4a5f05b70a10977a5f0ac39967c79479e9d3e41cb29/bitarray-3.8.1-cp312-cp312-win_arm64.whl", hash = "sha256:c0b367a00e8c88a714b2384c97dedcc85340547b3a54b6037a42fca5554d0576", size = 147218, upload-time = "2026-04-02T16:27:13.566Z" },
- { url = "https://files.pythonhosted.org/packages/13/79/015a30f40f716a0372907a7ac5c399db5428209dcf264b85ef1305f9b3e2/bitarray-3.8.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:55f4b105a1686eb486069a9e578d502d1998e890d8144012225de9e0450aeabd", size = 149201, upload-time = "2026-04-02T16:27:15.383Z" },
- { url = "https://files.pythonhosted.org/packages/23/fe/f70b150ea9a330daecc546a5a63576ba2d6b3bacc1ccde42abc9dd35a1ad/bitarray-3.8.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b3118ec012a799456f7fca6cc002c078590578b7640fbaab52d8ecb9a651f1c1", size = 146001, upload-time = "2026-04-02T16:27:17.041Z" },
- { url = "https://files.pythonhosted.org/packages/78/49/2c637658851ea0408c7375f5f278c0ebb69cbe861f8fcc9477db14ee7fa2/bitarray-3.8.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2762db8049b230520358ac742cbc57bceaacebe34e5d25c096f2b4bc3887a3a8", size = 335162, upload-time = "2026-04-02T16:27:18.587Z" },
- { url = "https://files.pythonhosted.org/packages/d3/3c/ae665a0b2d6183cc706c03b683b7f9ad53195731379ab82dfa537e73f70f/bitarray-3.8.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5b67b869f860eb19055e2560844d8c7d0935245938935bdb764b3e683e2014e2", size = 363031, upload-time = "2026-04-02T16:27:19.98Z" },
- { url = "https://files.pythonhosted.org/packages/2a/ee/7b7c37fbb15209525f0daff1a51a042c035e931ebd526aabb483fdc7a476/bitarray-3.8.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a661f3492462e7adf8a054fb7414a22fc8251f1e18b9d8cbcf008d2dc85f012", size = 374623, upload-time = "2026-04-02T16:27:21.468Z" },
- { url = "https://files.pythonhosted.org/packages/96/dd/26a17534742561974e5b2a3448d70fd8d370ed885bd88bbbb36bdd022875/bitarray-3.8.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:300e3026d17ae3328320ba78d3165bdb1c43d0dfdbc461a69ebbdc005d9ce0b3", size = 342850, upload-time = "2026-04-02T16:27:22.814Z" },
- { url = "https://files.pythonhosted.org/packages/58/f1/97410e88a8b441c1a6e5841c651e483787c3c87f2b98c1d2421aee23790d/bitarray-3.8.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ad5a71c1ef4a2e404c2c888db09226c821d9d14eff8813e1da873572f5fbb89d", size = 333109, upload-time = "2026-04-02T16:27:24.271Z" },
- { url = "https://files.pythonhosted.org/packages/64/1a/74a3af2d314ec6a035ae8f139491ace4fc8b3362bfdc86aee652b8f15be5/bitarray-3.8.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:78cbda57a2808d994517b53571eaa2d9299359f63aa71cf4bc94210169aad8b1", size = 360334, upload-time = "2026-04-02T16:27:25.999Z" },
- { url = "https://files.pythonhosted.org/packages/d8/86/01ea58ca9795401489f9de662ef9ba759d6712870696a5806441b2c14224/bitarray-3.8.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:89c7c125a0913d71ba9cc1fa8e14c7cfe1517b1c1f45416e1f9babcedd3b545d", size = 358674, upload-time = "2026-04-02T16:27:27.597Z" },
- { url = "https://files.pythonhosted.org/packages/68/c9/14587fd3c712047af60a875889ad69926386c3fdbf8061e9baf23d12d997/bitarray-3.8.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7875abfd90f2ae3aa22d50f3fa1c93bbae456458cc73d3179b838f07bed1fc10", size = 339689, upload-time = "2026-04-02T16:27:29.14Z" },
- { url = "https://files.pythonhosted.org/packages/5b/82/a8cc5172dba50c90d7cc89d9f5c1cfb99deb77af10b4762eb75ece52e20a/bitarray-3.8.1-cp313-cp313-win32.whl", hash = "sha256:21add0aa968496a2bd8341d85720d09808e22e0adc7dbefc1e0f8f67c4b83f36", size = 143503, upload-time = "2026-04-02T16:27:30.948Z" },
- { url = "https://files.pythonhosted.org/packages/7f/b2/f647dcd098c275a67b89d21c92471180996a797cec11e308b4d1936d170d/bitarray-3.8.1-cp313-cp313-win_amd64.whl", hash = "sha256:40d1b57012bf9b4fefd25345aaa95aab3ca510cc693f33c2cb02a4b771d8e51a", size = 150441, upload-time = "2026-04-02T16:27:32.642Z" },
- { url = "https://files.pythonhosted.org/packages/ba/78/bde39d566f70149c6858c7e61c0a0d902a643a136a56dd37b6135cc59a68/bitarray-3.8.1-cp313-cp313-win_arm64.whl", hash = "sha256:72b32d8c471930c95d49640ec99f7694f9b040ca1342ff03ed69d3aea90f9339", size = 147209, upload-time = "2026-04-02T16:27:34.289Z" },
- { url = "https://files.pythonhosted.org/packages/b0/3b/d07ee3ef120a3b3f1db2434c4b955fbf900bb3f878e25a71ee82408e9d91/bitarray-3.8.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fe989bbed9d6f332c1e24d333936f3fa1375f380cd8028da0b985dcdefa6015a", size = 149181, upload-time = "2026-04-02T16:27:35.608Z" },
- { url = "https://files.pythonhosted.org/packages/ab/bf/43bf76bbf95354e74b80923e8aa7d6cb178e25546eeab0705524ad4d5171/bitarray-3.8.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:75e33c9187da271d1dbeb2582ab2df2e441346492098f67559b09173ea4edde4", size = 146020, upload-time = "2026-04-02T16:27:37.279Z" },
- { url = "https://files.pythonhosted.org/packages/89/8c/868644e4f61220529ceea0be6dff1c659a7c20dc354f8c5aa367409e6150/bitarray-3.8.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fd7e3158be382f8f140caccc0dc7742a7553ce4bf2978982abe3054d2cedd705", size = 335102, upload-time = "2026-04-02T16:27:39.065Z" },
- { url = "https://files.pythonhosted.org/packages/f9/6f/0eb0ed1214bb6436e078a44006127685b587b6aeb1600bc2f77bf53e96b9/bitarray-3.8.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9fa5620f7f352f9706924c0e2071a212be36421f09ee064b0fd7e1128289fcdb", size = 363405, upload-time = "2026-04-02T16:27:40.596Z" },
- { url = "https://files.pythonhosted.org/packages/25/eb/07d6ec5ad40792ff92857ac51cb91c01f855e3edb7b589eb099937420722/bitarray-3.8.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:190b20cbffc9cd7f308f7a57d406119c3af3ae197613325fd2d92d99c8882ad6", size = 374225, upload-time = "2026-04-02T16:27:42.101Z" },
- { url = "https://files.pythonhosted.org/packages/46/53/2c5d688ea0f91025d3fdd08e13f9d5195c384953961070ce79719efd18b3/bitarray-3.8.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec3d0a6c37a816ea6e3550697c60d90861c9b0f982a98a40b59ac1f7a360bfa9", size = 342742, upload-time = "2026-04-02T16:27:43.706Z" },
- { url = "https://files.pythonhosted.org/packages/2e/8a/25a932f02a8d1ca0c97cae62399f475d219669dbfecca3b2d7567effec73/bitarray-3.8.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:746e25f17ba4203b5933773782cf2d30bca5cdb66a9ba5d48a53a6c795aedc57", size = 333236, upload-time = "2026-04-02T16:27:45.237Z" },
- { url = "https://files.pythonhosted.org/packages/fe/a2/83fc66eb64ee0e74dc04894fbe8ae7e2d083c824ae9c1396d68a14c50760/bitarray-3.8.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ab363a5baae965fb3438f2137583853ad9c77d7e45f2a62ba63e609a34d792ea", size = 360526, upload-time = "2026-04-02T16:27:46.724Z" },
- { url = "https://files.pythonhosted.org/packages/a1/60/eee517c36956d9fc8d4ae2b2fbcf9122477b0730dacd52a2800226b11e61/bitarray-3.8.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5e30d8e399f38ae1ec86aa9be76d20ba15872dd0c41b4b46d1b78905857363b9", size = 358208, upload-time = "2026-04-02T16:27:48.221Z" },
- { url = "https://files.pythonhosted.org/packages/f4/a5/2d35fb2d1abc8afa4fef93f3ad96192eebd81595c3f9389a95f5d01ee782/bitarray-3.8.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0f099a4a77daf9bb99787070854894fe588c7d6988ea729f970ba2b3b82c7559", size = 339373, upload-time = "2026-04-02T16:27:49.911Z" },
- { url = "https://files.pythonhosted.org/packages/f4/b5/64d6d485725076472e0f151643ac4fa78ed54f10f6b7bf9620690a24af7a/bitarray-3.8.1-cp314-cp314-win32.whl", hash = "sha256:539880ddf9a8cc54c9e6126e7d072c991563f0c90ef73b3519a783d53df00352", size = 142632, upload-time = "2026-04-02T16:27:51.371Z" },
- { url = "https://files.pythonhosted.org/packages/04/e9/cf02dfac88f4c7d3de2dbafec4ec0616eaf9547dd7be98e81dc0fde97a77/bitarray-3.8.1-cp314-cp314-win_amd64.whl", hash = "sha256:c08cd5b19c570e1e9e094a6ce70d35bb39d12360e0763474ed9374229f174fcc", size = 149180, upload-time = "2026-04-02T16:27:53.027Z" },
- { url = "https://files.pythonhosted.org/packages/ef/a8/8e56397347bad7b042aefee9afc0cb085f2a779f7c8cc38954b12671d37c/bitarray-3.8.1-cp314-cp314-win_arm64.whl", hash = "sha256:0da5f17bed67ffe1d72f79fbf98403513a6e51a4f9b8293c1ff8a64e121242be", size = 146389, upload-time = "2026-04-02T16:27:54.759Z" },
- { url = "https://files.pythonhosted.org/packages/ff/a6/52bcd001c5cdf5c381a7317b07157070be1a6bc7fa5d58314ef6da33626b/bitarray-3.8.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:154a19e1dcd430494fdad7d1a0fb36383baaa363e1cb9d5a7b744cd2418c44d2", size = 150091, upload-time = "2026-04-02T16:27:56.154Z" },
- { url = "https://files.pythonhosted.org/packages/b6/22/86f51124a9d0e622be0bd171b797e0d507d5c9d6f76f5b97cb12e4ecf113/bitarray-3.8.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:814bb54db2a016026efc055a3527461e5eb551c0d91b32eeade003829ff84311", size = 147130, upload-time = "2026-04-02T16:27:57.916Z" },
- { url = "https://files.pythonhosted.org/packages/eb/d4/2153c6de23e26d0bfa65e0994ef771f06f8697a9ae65473923f6922ab1b9/bitarray-3.8.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac49519fcfeb4a7ecdf6b7d0ec6cac409e59f94c1bb54630db577a97893b6e38", size = 343168, upload-time = "2026-04-02T16:27:59.345Z" },
- { url = "https://files.pythonhosted.org/packages/55/bd/6ff9be5965c11e2f67bec674cd1bbe41e81531ec970251986f4d4978a72d/bitarray-3.8.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:329b994944993c45c3845047476ef4f231fe1a53972f18f8d005fd12fac163e1", size = 371961, upload-time = "2026-04-02T16:28:00.956Z" },
- { url = "https://files.pythonhosted.org/packages/7d/24/9aca563d253ed28be47b9a8d5f2fe0942e0191bc4ef49589e7670177807c/bitarray-3.8.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1d7b786a1ddd9b8dda17c445060a94a465cba2e113603ae7bdc5364efc1efd11", size = 381778, upload-time = "2026-04-02T16:28:02.589Z" },
- { url = "https://files.pythonhosted.org/packages/be/e2/81ac4c98694857b7eabdb9ada77db5b44fb6b6d5d19a3a716fb8a486c251/bitarray-3.8.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd9b848c17ef034f2ae31b2a1bd9276710c2baf03509f1f3fa4dc4382b0a1b53", size = 348165, upload-time = "2026-04-02T16:28:04.431Z" },
- { url = "https://files.pythonhosted.org/packages/ee/c5/2107bf1474a139f934621703135985f2acfae92d786561edde62ec557f60/bitarray-3.8.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0a33f8931ac91ebc23ce4decb99ed8fdddba2bafd2af3bb2781bcfd9878d4822", size = 340225, upload-time = "2026-04-02T16:28:05.899Z" },
- { url = "https://files.pythonhosted.org/packages/31/95/a3d2571055279a09373d1f93249404ac37a34045e334935adbc2ce780f83/bitarray-3.8.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07626f76a248fce5ebbb10fb0d4899d3c7f908ba21cb2fb4f5a7a9daf24c20cd", size = 369440, upload-time = "2026-04-02T16:28:07.49Z" },
- { url = "https://files.pythonhosted.org/packages/ef/56/7fad5bb52c0b9cdcdea4405f5d9a41f5efbf2873045d668bc2b8db10213b/bitarray-3.8.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:18f3a2c8908e63a66d3994808254397a5f989b1fb91087c33739f62bf1a1a064", size = 364733, upload-time = "2026-04-02T16:28:09.086Z" },
- { url = "https://files.pythonhosted.org/packages/10/b0/a23a1c312206c65146021aea68d69c8c7d817ae2f99698cbc23b3c744bba/bitarray-3.8.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ced27af6aee28782260bfa5643797937e96a6489bca972202834017208cf74f5", size = 343729, upload-time = "2026-04-02T16:28:11.09Z" },
- { url = "https://files.pythonhosted.org/packages/a4/a0/fe5dbdfadcba2314551614d023db100e3aea7b09da2cdcbf1386f5c797a6/bitarray-3.8.1-cp314-cp314t-win32.whl", hash = "sha256:cf99e36c0f6ae5643ecef7ad7e1194aeb4a9798d9cff60b20ac041533fa6db0a", size = 144160, upload-time = "2026-04-02T16:28:12.702Z" },
- { url = "https://files.pythonhosted.org/packages/4e/0a/e95ed44f6d89e63ed666755fc0773223b10df0058d5de30d529f4cf35948/bitarray-3.8.1-cp314-cp314t-win_amd64.whl", hash = "sha256:9befda0dbd27ed95fba1c26be4bf98a49ba166b3c91beb5fc04364c130ce950c", size = 150852, upload-time = "2026-04-02T16:28:14.149Z" },
- { url = "https://files.pythonhosted.org/packages/0f/90/454b88b193743b4cd0fce0819a11b1c43b7f629cb2533f6ddc62cbb5e097/bitarray-3.8.1-cp314-cp314t-win_arm64.whl", hash = "sha256:4b7d7d10a1c82050efbb9a83d7a43974f70cf8f021afb86463b42e4ac4e5a46b", size = 147343, upload-time = "2026-04-02T16:28:15.632Z" },
+ { url = "https://files.pythonhosted.org/packages/df/0b/8509a00dc5ab2945e9856582f8a4908a78f15a7a08b425dc067f733299d1/bitarray-3.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a334e162a24c4e85babffb78823d83aa04c882a7dd40c2106b668a8cde3da752", size = 156246, upload-time = "2026-07-25T06:37:14.799Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/1e/40d32865af46ff2c8a4ee488c60f1dd3724f3ff2c8405cb6594e75685c7d/bitarray-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8855aab242b4865e7ac7e14b6ce80f4cdf213984f260f31d92505d6877c620f9", size = 152874, upload-time = "2026-07-25T06:37:16.141Z" },
+ { url = "https://files.pythonhosted.org/packages/12/07/0a646e68fa1fdb73e260474fdca595b93a7ecae6da49ac1d4c34be2b3b08/bitarray-3.9.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf06a3a5263268a35ed0d5513309791040ec8e8d3089bb5af12f51979dbf0a2a", size = 350232, upload-time = "2026-07-25T06:37:17.071Z" },
+ { url = "https://files.pythonhosted.org/packages/38/5c/c1926f34269fb112d4b8b2b4fb0b84fc47b02268c30b300d237cccf07060/bitarray-3.9.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b82130cfba659e6a9da81298f43be678e99c598e64d814cfa86f0df8c1e230aa", size = 372334, upload-time = "2026-07-25T06:37:18.165Z" },
+ { url = "https://files.pythonhosted.org/packages/42/b8/9937340228a814d72194543a1d452d552e3ea45d1537e27914deff41bbe0/bitarray-3.9.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2ebc32a4fd8659a848d2c92ca5d75a1029cff9711bedbf3a32c515a19d4b3868", size = 384431, upload-time = "2026-07-25T06:37:19.251Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/f1/311991e38cae3aa2b0f48726578e98aa584157c1f5bf4c8df51ed5a273d0/bitarray-3.9.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047e6ad06ffe606cdc9d75b83effc5f14ab11f30bf6ca38fd98553410e23880b", size = 353328, upload-time = "2026-07-25T06:37:20.383Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/e0/7087f78801ad89fedf4812bd9cf46c204e48c1cfbf83bd0d8eede7dbd076/bitarray-3.9.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:42e7735c20e3e8e8044bd566ffa8461ad4870a8459c5d3fe9d43984eaa2d6104", size = 348330, upload-time = "2026-07-25T06:37:21.579Z" },
+ { url = "https://files.pythonhosted.org/packages/71/b9/42b7265266ceee164942e34c278e3982618ff022b40771004693c6a64055/bitarray-3.9.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:23aa70b05518ee20d965a8cbd1e168ba4085647f12d7bdb654412a253c476652", size = 370012, upload-time = "2026-07-25T06:37:22.584Z" },
+ { url = "https://files.pythonhosted.org/packages/11/11/a80fde6c902cdef198a20e218a1005f09d9bc5266a8db310cfd2468d0e7b/bitarray-3.9.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0197a8970233d65e04357308d52e5310ea8219e07587f8db8a98d7ac21b7de50", size = 365747, upload-time = "2026-07-25T06:37:23.791Z" },
+ { url = "https://files.pythonhosted.org/packages/30/6b/01ae2bfc9778ff2bc78c20c1fe5a80b7290baa1b57e98f04435eafa09a68/bitarray-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1a5b7919ab373df270f268ab35c49aa311ed06412290313cecfae9406003ee", size = 350281, upload-time = "2026-07-25T06:37:25.015Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/ec/1ccde07e363791274c6f4f376d1e844254d97ea762fd25a2372a1e56f92a/bitarray-3.9.2-cp310-cp310-win32.whl", hash = "sha256:3aba64f5b449f50498185c81ba16dc9b819b06d985630f1b630e836081cf5051", size = 148006, upload-time = "2026-07-25T06:37:26.138Z" },
+ { url = "https://files.pythonhosted.org/packages/85/26/ee9cbd0b3df4cb9939bbbe41b0e9fca5185c33b0788eb5129a432784bf58/bitarray-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3a6bda7bd4a77926a18dc9890acad77ae96c2e4d9ff163a20438a67a23d7d956", size = 157184, upload-time = "2026-07-25T06:37:27.093Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/ae/04a86f8fc6a57205b27bad5e201aaa3bdafd70324eb4407c764018b712a2/bitarray-3.9.2-cp310-cp310-win_arm64.whl", hash = "sha256:4f9576e2e417eb4b45257c135b40d5e465969382dbf4291377f4b7327ca74603", size = 153173, upload-time = "2026-07-25T06:37:28.061Z" },
+ { url = "https://files.pythonhosted.org/packages/61/cf/1c8efde1c873445d7609e2b1576edb29a7b946a8135a8a5f60b5e775fb79/bitarray-3.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38c850db9ae8602e21c5c29193546a7ac85f1a70adfd4d65853154825675fce2", size = 156241, upload-time = "2026-07-25T06:37:29.185Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/2e/21ebb66fb272295c1e90ee04245e00f3655109b95881cf014485fae35526/bitarray-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:06df682d5b9ef233a21fab71912f131b2c295913202f2ad5370e44b0e0b26241", size = 152869, upload-time = "2026-07-25T06:37:30.329Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/db/4af8e55d377c25ca37a1da550d1852e44fd280ce5b550bef91d5aa52d2e9/bitarray-3.9.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0c064263c54fffe8fdfe8e20074816c67ec70608b0efb42a7d9fdf35ef67271", size = 359514, upload-time = "2026-07-25T06:37:31.384Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/20/464b03e4388d2093998bb355de1396d318728f9d8e1cc715770295babda7/bitarray-3.9.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0a61eac6a5a47cc7bc458b1f0737a701767543949580605cd85272c48121fb0a", size = 381209, upload-time = "2026-07-25T06:37:32.499Z" },
+ { url = "https://files.pythonhosted.org/packages/02/fd/f24ec964e5737180957366473b664f8587a34dc7792e674a9d6c839db2e6/bitarray-3.9.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b62d7de8e4dc4ffbff407e1c7f868b84a00ac4a9919e28755fd299e86740fced", size = 393701, upload-time = "2026-07-25T06:37:33.501Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/c2/0ac619df1eb86593c7b7d833325cfa6cf5a3bcd55f3fa0871e30e1d6036d/bitarray-3.9.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ea75f495073f95e96e3f3049411854b5db1693901d8b324439a170ef45088fa", size = 362278, upload-time = "2026-07-25T06:37:34.691Z" },
+ { url = "https://files.pythonhosted.org/packages/23/6b/3325564d17cebb71f6beca6b41d463d1083acc68ae06abb3ef2729f78b46/bitarray-3.9.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f3eb99f3cc4ef93b4830e8532ba506be4105f15daddba9302bbd96f24b1cf72", size = 357205, upload-time = "2026-07-25T06:37:35.764Z" },
+ { url = "https://files.pythonhosted.org/packages/16/37/6253ca3aa44d257c8a70ce9bb98c0d05302bff586979c22b2264c9ae4457/bitarray-3.9.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e22236531f0193457277a7340d8bdd006f202f563f22f29abb873dc0850eb472", size = 378079, upload-time = "2026-07-25T06:37:36.958Z" },
+ { url = "https://files.pythonhosted.org/packages/04/4f/e7595cb740e1b296f601b0d1292702b867292204e8f4ff010772f3a75c02/bitarray-3.9.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:92a438122d35d5e5703983c7dda7de90fc25c50282ce60f73ad61a6ced3ce0bc", size = 374941, upload-time = "2026-07-25T06:37:38.021Z" },
+ { url = "https://files.pythonhosted.org/packages/87/61/135e3b0b42d65577725f2ddada426fce35cf816bc7d07e954ff6194b1193/bitarray-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:47ec58fceafd38d5839bb9d8262ca6150e222f81d1e4adc8feafda6caf360334", size = 359249, upload-time = "2026-07-25T06:37:39.079Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/7e/9b7a01e4d5d634f36fc1151854fdc61c09678b53dfd667f66baaff7efbff/bitarray-3.9.2-cp311-cp311-win32.whl", hash = "sha256:e8ec38401d9370684709f8cc3a0febbb742edf9fbacb1e432bcad8d023990e6d", size = 148130, upload-time = "2026-07-25T06:37:40.15Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/be/ee0813622d5fc2c6419aa5ec8e12407593f56c41a6e70fe1b8092b158c82/bitarray-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:30e2516878f7745957948e1a2d877f56ceda13b5f6b51d92d2174ef1756ab473", size = 157489, upload-time = "2026-07-25T06:37:41.158Z" },
+ { url = "https://files.pythonhosted.org/packages/26/4c/1ad11f39eb6b1851777fb25185e839d19d273f2350c5e1bcbf0e014a7fda/bitarray-3.9.2-cp311-cp311-win_arm64.whl", hash = "sha256:89c87ffdb399a53821cb0f5566a7d04e0f2870096a4964b038866a894b40c9c6", size = 153465, upload-time = "2026-07-25T06:37:42.151Z" },
+ { url = "https://files.pythonhosted.org/packages/73/c3/6d33775d73e22cfe3fe23dae2ed50dbabdb38ea651e8b5c983262c39ce26/bitarray-3.9.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c967be9bd2fadd58e0d2c4e139e6e7443b5dd9162e52e43ef5e2489218c4fecb", size = 156385, upload-time = "2026-07-25T06:37:43.505Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/9f/24b22bfa3016fdd50966966f7dec0ecf11a911429be5178880228068e108/bitarray-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c17c918e569a81a2dd87794e15991c9643accf72b5c005e8791cdedcb2d6189", size = 152941, upload-time = "2026-07-25T06:37:44.64Z" },
+ { url = "https://files.pythonhosted.org/packages/48/61/affb7fd0ce338529b57eea7d1fda983b4f4adde89eb7ea8e4201c4aa4e47/bitarray-3.9.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eea0dc21749eeb53b163d45c3dd0524e62c0301dd512bfb4f5ef34ccce7be6ad", size = 362020, upload-time = "2026-07-25T06:37:45.687Z" },
+ { url = "https://files.pythonhosted.org/packages/31/e1/43f6eed3ae86d08c11eb424ad0c7ffd40bb081eb50c682c76adeead3ed0d/bitarray-3.9.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:64fb672905884fc236ef200b9fbde529c6673a8217c62bf8651bdce4842ba366", size = 382732, upload-time = "2026-07-25T06:37:47.212Z" },
+ { url = "https://files.pythonhosted.org/packages/12/f1/cf664f54fef3c5c921e7133a2795201e508c2c984ffe7c0f3f851f2b976d/bitarray-3.9.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:be25330b9da322a806b29bae0147e6ea3730b6f85a5036e25f8e50247fee013a", size = 396696, upload-time = "2026-07-25T06:37:48.309Z" },
+ { url = "https://files.pythonhosted.org/packages/35/fc/6d6409ec30dabd388b6f3ee6c461eae353f04d95dc287f7be19fffff8fcc/bitarray-3.9.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7e14fd457ccea13e0adca60d93ffcd17b70184e7f485a986523241a077f3ac9", size = 366507, upload-time = "2026-07-25T06:37:49.671Z" },
+ { url = "https://files.pythonhosted.org/packages/37/47/d241a6dde522a213cd624a820e0be998b0e5548d141098e990bba03913cd/bitarray-3.9.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f719003b0d692d3088e8f783ec684bf7caf00bddb5392efbe7842ba1ff15e8e", size = 359937, upload-time = "2026-07-25T06:37:50.725Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/a6/0f4dd5a813f87b79e07e4bece697e872f4836486fca92903c63cc75c42db/bitarray-3.9.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a72e6b82f1800a08dff90a9d401ffd3f8c278644e4f6711a7458c9f16ee9446e", size = 379627, upload-time = "2026-07-25T06:37:51.884Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/27/cbc55ea191b52710c19702cbbae7814ff55082b02a4c23aba11c23dd1990/bitarray-3.9.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d043ef192ae741f0524b3d3404a2e6e8dbb6affeda421d40d46456cf6cfa1064", size = 378404, upload-time = "2026-07-25T06:37:53.43Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/70/20179544538444c0896099a10a035d857c2f4ce707a950834aa62d645714/bitarray-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:23fe97bfed91ae4c927871b779caa159000da958fe5521d92420a09ed524efdf", size = 363092, upload-time = "2026-07-25T06:37:54.796Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/97/c9b206363aad0239cf966ea4eefaaa0da2717cd695ac11af1effbe3819bb/bitarray-3.9.2-cp312-cp312-win32.whl", hash = "sha256:ff72bbdd7c01ca661cb6712e706c0e0f0bc45a6b2426f69e9517cf7508b8d294", size = 148523, upload-time = "2026-07-25T06:37:55.915Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/2a/67f161485ba266ad76064405cd19dda50057f466d796b4ad9d9e2645b877/bitarray-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:12c2e7556f7d7f3d2a2017d66159790ed6cadf849a3aa436d9c3541dd3facd6c", size = 157829, upload-time = "2026-07-25T06:37:57.285Z" },
+ { url = "https://files.pythonhosted.org/packages/58/cc/aefdf64e5c3b057538ed6e5f244fa055bc825b10cb3a08ead0895ba9ff67/bitarray-3.9.2-cp312-cp312-win_arm64.whl", hash = "sha256:76c0a98d85b2ed7090ff6c0fff9917a2ddffaffb82c2d0ce7d424f0830dc8dee", size = 153677, upload-time = "2026-07-25T06:37:58.332Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/33/a15849ec7ca05b55835b52baa4f226ee1d75cffd0943cf0a648c52bf9048/bitarray-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5156ae1fb0d56238b2ba64b8c0da9a14dbc2e16c9d79114ad3850b7aff513b0a", size = 156131, upload-time = "2026-07-25T06:37:59.76Z" },
+ { url = "https://files.pythonhosted.org/packages/53/98/f097b0e50c31c4e1cc8f8612e21b8d193a66c0d14ca07f06eba376c5f090/bitarray-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:054fc478842a95d8e9e200117a7e170cd8ec17608e3cfa451e44fc78e5ab5007", size = 152618, upload-time = "2026-07-25T06:38:00.769Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/c2/ea3786bb4231564482f23f1aaf478a1ddf8e8d08cfb90167c17cca89623d/bitarray-3.9.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d5e428a70d6e395b9fd415bba70bfb463d2b9e8010d471cb99eb0f82e91d179", size = 360335, upload-time = "2026-07-25T06:38:01.829Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/93/5772f7c4ffa4d6a1e9e486e8623f4f89041268e8c91b5761ad0920fc53e8/bitarray-3.9.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a34d717b362f96a767b03f350cefecd0f613a44ce774868d3635423eec1e5d75", size = 381029, upload-time = "2026-07-25T06:38:03.1Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/6b/e84a9a61cbf7db68703f6ebeb853c4d323c9b1d83bd4d863ceb424575785/bitarray-3.9.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:068a100b2d3507e1ebd6f0cb3515551ddf3c7db1c98426dc854ddff985508eb8", size = 394606, upload-time = "2026-07-25T06:38:04.149Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/3c/127d48763eaf8941556486fc7883096d9024139276dfc19150523bfc6e31/bitarray-3.9.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a797165662ce08029a5975e05e928b77f979d8322cc719ba46eb8b3d9ab5c9b", size = 364341, upload-time = "2026-07-25T06:38:05.401Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/9b/d58b96fc10bec25fa59aa894964dadb5cbfb150fe4b30aeecea162c2cda4/bitarray-3.9.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6468d775054cb4fe777d585c661df89e99f9398fa9cb31e428a9b42105e6ce48", size = 358005, upload-time = "2026-07-25T06:38:06.464Z" },
+ { url = "https://files.pythonhosted.org/packages/61/5f/25989fb53e1e4f079b2c75b24d0bcb500b407cb0be2c35953fee092a872a/bitarray-3.9.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:9bd26caa42d12c747af2c3a3995b08db32ac7afa0c5262c0b6c6931293067805", size = 378038, upload-time = "2026-07-25T06:38:07.818Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/42/e80c45b496d60e216af776ed284c65cc55434cfbe39cd459975f1fb6a0ca/bitarray-3.9.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:11574711bae2b501141f64cf6d7a9819c9f45e7d8edcd2d9fe282b377dadb900", size = 376295, upload-time = "2026-07-25T06:38:09.079Z" },
+ { url = "https://files.pythonhosted.org/packages/04/84/8bc4a8e12a802199b20912f57427e3ba6b8cc3649190fecb7c97bb35a69d/bitarray-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c6e16d6a8d93362f65336fc57e76fb1fe94f257bb54a843cf1a83c86887ac1ca", size = 360959, upload-time = "2026-07-25T06:38:10.299Z" },
+ { url = "https://files.pythonhosted.org/packages/34/ca/3ebd885ae0df8f9ec508315361e602fada65c5c75d8b1d1660c81659cce0/bitarray-3.9.2-cp313-cp313-win32.whl", hash = "sha256:7fd8d649b10ba26c032c76ffb2610385496ebf5e52c44c26864e9b16ac8102b3", size = 148350, upload-time = "2026-07-25T06:38:11.473Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/92/7ecff07e9bbf6f51092bc3a01361bd5bae5814cd3326abc8423a2ae637a0/bitarray-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:0df2bd4b5fea65be332cf9c17351d4c68d3eb442c0e13a5bda8019554cb36ce1", size = 157627, upload-time = "2026-07-25T06:38:12.591Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/c4/28122fd875b6bdbebfc15bf60ea3704149540b0f3f43e15f247a7e9604ba/bitarray-3.9.2-cp313-cp313-win_arm64.whl", hash = "sha256:94278c9d37a6f4316ae1f100e98e6582369f25b1f8186bb595ee1578fbc5c52e", size = 153528, upload-time = "2026-07-25T06:38:13.863Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/b2/307b9857295d37489b3269eb3cbcf62ab55d19e17c6c567602a2fbf3a589/bitarray-3.9.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b0debddd2eb7d1a0417f602b2520dd6fb6897ab140c1d69b8c42a69d164ef61b", size = 156152, upload-time = "2026-07-25T06:38:14.92Z" },
+ { url = "https://files.pythonhosted.org/packages/95/55/3d13cb858176c2a9189c35becccef29b45c32720e7a1f36c57af431ff7c0/bitarray-3.9.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5d0387459ac35f6be40c4b809c34f34afe14aa930493e0b06f6df5d327f405c3", size = 152690, upload-time = "2026-07-25T06:38:16.096Z" },
+ { url = "https://files.pythonhosted.org/packages/59/1f/7d01c3130fac3d7cd9f52697019e4dbf992fc67befb7c915faf456bc1c1c/bitarray-3.9.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5bde034041875a48ea8c0a4b272e9a6e29174b234bd4905c86a65484f34cd140", size = 360268, upload-time = "2026-07-25T06:38:17.27Z" },
+ { url = "https://files.pythonhosted.org/packages/25/61/2b6f05eb6c855727799dd3092b70e933ff433e9464740245042c2bfc68f7/bitarray-3.9.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:37c76ff084118ab1db8b826e35c01ce4d0137e66b611542e16b1f296c96e6aa6", size = 381244, upload-time = "2026-07-25T06:38:18.462Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/b0/72d15249f41ffcfad56b4cea7d2a518d936c33c3548f6f474de96ae9da88/bitarray-3.9.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d12c7b574e2903477124a0d77bbc903fd4c3beaefa841f4a63c199014192447b", size = 393965, upload-time = "2026-07-25T06:38:19.823Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/6c/e880b52ebed9441a423afdb9f8f3b71186b689cefdcdc6fcb434ca4775ee/bitarray-3.9.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bbff5cccf3a1f4129c8ad43b2bcb789882fba47c87422b30a74bc3bee98a292", size = 363960, upload-time = "2026-07-25T06:38:21.06Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/39/2fb0d14bc884de3dda42a6cfbe2325d76af45733e6f97709924352db2bf8/bitarray-3.9.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c374884716ab641c36ee4f51859fa4274fbdf0355ae7242290a29af3cf49381d", size = 357843, upload-time = "2026-07-25T06:38:22.263Z" },
+ { url = "https://files.pythonhosted.org/packages/af/ca/5f7fe5898ea35e34ce79b653ae513d4c67bc0ae607229c51a09d8278195e/bitarray-3.9.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2fe1d36b6d816512af098699c85e9237ce5978863a336a2833ebc03f59545781", size = 378105, upload-time = "2026-07-25T06:38:23.436Z" },
+ { url = "https://files.pythonhosted.org/packages/3e/c9/c6b3121421783f10481836140ab976cba7b73bceb9f58216eabf1cee073b/bitarray-3.9.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4f719595fde8bdf030282c8221c738248a3a73928db3087ea62db2c29de5342d", size = 375952, upload-time = "2026-07-25T06:38:24.695Z" },
+ { url = "https://files.pythonhosted.org/packages/30/95/05f50342d799d7f49688371ebd3695b79c6fa65db4eeb9fc335c72aa755e/bitarray-3.9.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:28c4edee03ece6768ee51c1889c5d4df05764f8ad956fed6295912dbe4aef729", size = 360654, upload-time = "2026-07-25T06:38:25.944Z" },
+ { url = "https://files.pythonhosted.org/packages/30/88/836ad7a1421cd4dd888ed602eb7e7fb297de866e64dab19150be596e9abf/bitarray-3.9.2-cp314-cp314-win32.whl", hash = "sha256:f01b94e8bd0229c214f0873f8d19cf4db4602a230064317a8be00428922f7987", size = 147264, upload-time = "2026-07-25T06:38:27.106Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/cd/ca5feb145af0ad602c88a2bb43ff3c44067846324c58e8c972a397adf2ee/bitarray-3.9.2-cp314-cp314-win_amd64.whl", hash = "sha256:7892775de516287fbc850cfb9476599bc399b971105fbbe216513ac4cb67d6bf", size = 156687, upload-time = "2026-07-25T06:38:28.268Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/f4/8d9516a9aa91b18c9c0075451386b09c342acf3cca536331438d38e8c955/bitarray-3.9.2-cp314-cp314-win_arm64.whl", hash = "sha256:7dcbf363dce364722a3cd3875be5453a36db8c476af551bc5b194ea9960c591f", size = 153104, upload-time = "2026-07-25T06:38:29.357Z" },
+ { url = "https://files.pythonhosted.org/packages/38/ac/62db07d42f4713d8032acb2c5776550f99da74ead726d3ab49845ac2b768/bitarray-3.9.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:732fc6464eebdfbbdb28e7a2e98424ba7633619665fb065cb6d756ffef5f6b08", size = 159619, upload-time = "2026-07-25T06:38:30.939Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/4a/7ddb362b4dc3f7beb428e96c129fbc96196c7a716658d5d677dffe8fffbd/bitarray-3.9.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c23f1dc6f118c3a885ee2a281261da37e98c35b4361dcf2c9a9d3d70370b32e6", size = 155980, upload-time = "2026-07-25T06:38:32.085Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/78/08b2ac57ff404a33e98193481d1a4fe716999ed2255335fbd56ddda7737d/bitarray-3.9.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ada39b08677af76c48a64f1f14e8e518315cf478004ddf4b6c580ce3625c1a9d", size = 378321, upload-time = "2026-07-25T06:38:33.376Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/79/5a0734dbc080748b11680483d74f29469c85b56ff6b490028c301732c658/bitarray-3.9.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:70e5a48906a8cab0b8d84ad356d8cf8f0fb533b93475da26437a4a3aed8a9a4b", size = 397775, upload-time = "2026-07-25T06:38:34.619Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/2f/a4d87cc0a1a01851fb76cb13633413fc8d2187cfbf00d9f85397edba301c/bitarray-3.9.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b14351e75d76662d10c1479c8864f4076ab393a297323b85277d2253ccfb96e", size = 411104, upload-time = "2026-07-25T06:38:35.945Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/df/5b2d12198c9403a8b757dfc54fee1199e202ec361ad7fb4cb84f295e917e/bitarray-3.9.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:920edc84385932401ddabe62e244774acaa69e991072768fcf7e621c29599f6f", size = 380204, upload-time = "2026-07-25T06:38:37.14Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/5f/b6daaa21059439703d53349d9e9158860fa04d31b8a5613dfdc45c8f4b9c/bitarray-3.9.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3d6dd06fd0e1c88e6da86e4c0479457c74f03f66a2dc16c0c60ecce12c5dee1d", size = 374273, upload-time = "2026-07-25T06:38:38.435Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/4f/625e820bdc9235f56ef9644892c7b6b89a96cb7f5a0823748e9a912f1d1a/bitarray-3.9.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:ee339e8f9a763499c5fc855927c8174680183e8751f03f797234a0bd1223c3ff", size = 394096, upload-time = "2026-07-25T06:38:39.785Z" },
+ { url = "https://files.pythonhosted.org/packages/02/27/04ee7179dd670781a3c457969e94503a10c516e43340faf04f6862c7c0ef/bitarray-3.9.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:50f0ff3b5e5cfa7ca42e2469418a26d098a42e47b0e171adf9c6c69ea800d055", size = 391958, upload-time = "2026-07-25T06:38:41.011Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/7d/ef4ce2906e6c3056021196d11efb220f351f7db74783882e802c8f81c17f/bitarray-3.9.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c898478e6dde8ca75970b91a602b1f48ebedff49841b89cb8495c1949b6d762c", size = 376178, upload-time = "2026-07-25T06:38:42.535Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/63/ff961878f0671e921d03a498705b4a15bb96b53474685f2d04abb79204f4/bitarray-3.9.2-cp314-cp314t-win32.whl", hash = "sha256:415675dbae4d1c58a5ae31550db6224e0785443e41d9ed74cf4371aec38d61d3", size = 150524, upload-time = "2026-07-25T06:38:43.939Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/ec/a3eb15a4a9730e3f48315f8d510867944f9051b82a465f4fe1d28b9a9e76/bitarray-3.9.2-cp314-cp314t-win_amd64.whl", hash = "sha256:de17695646139d2a9863cf1d8ff83f1335aa3d593f2730c9ae442fb08ef80241", size = 160476, upload-time = "2026-07-25T06:38:45.145Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/81/73c274307ec6f74fb072623ec2644e6467f36b24f7464f0be2ed236c183c/bitarray-3.9.2-cp314-cp314t-win_arm64.whl", hash = "sha256:19105d5ff84450b341a0dc1021c7f8d63cb1ffedcdc78b46e62f4cd76f28a7f1", size = 156219, upload-time = "2026-07-25T06:38:46.274Z" },
]
[[package]]
@@ -148,198 +143,208 @@ wheels = [
[[package]]
name = "certifi"
-version = "2026.4.22"
+version = "2026.7.22"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" },
]
[[package]]
name = "cffi"
-version = "2.0.0"
+version = "2.1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" },
- { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" },
- { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" },
- { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" },
- { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" },
- { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" },
- { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" },
- { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" },
- { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" },
- { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" },
- { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" },
- { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" },
- { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" },
- { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" },
- { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" },
- { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" },
- { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" },
- { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" },
- { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" },
- { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" },
- { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" },
- { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" },
- { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" },
- { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" },
- { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" },
- { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" },
- { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" },
- { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" },
- { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
- { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
- { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
- { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
- { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
- { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
- { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" },
- { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" },
- { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" },
- { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" },
- { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" },
- { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" },
- { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" },
- { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" },
- { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" },
- { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" },
- { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" },
- { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" },
- { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
- { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
- { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
- { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
- { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
- { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
- { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
- { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
- { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
- { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
- { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
- { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
- { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
- { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
- { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
- { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
- { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
- { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
- { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
- { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
- { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
- { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
- { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
- { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
- { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/e9/6d7724983b3d5a0908dbf74f64038ade77c18646ff6636ec7894fd392ce1/cffi-2.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b65f590ef2a44640f9a05dbb548a429b4ade77913ce683ac8b1480777658a6c0", size = 183837, upload-time = "2026-07-06T21:32:09.655Z" },
+ { url = "https://files.pythonhosted.org/packages/69/aa/24580a278de21fd7322635556334d9b535f1cbc00b0a3919447cdf464c65/cffi-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164bff1657b2a74f0b6d54e11c9b375bc97b931f2ca9c43fcf875838da1570dd", size = 184226, upload-time = "2026-07-06T21:32:11.196Z" },
+ { url = "https://files.pythonhosted.org/packages/88/a9/02cae418ec4beb282ace11958d9d4737793439d561fadc7e6d56f2e2b354/cffi-2.1.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c941bb58d5a6e1c3892d86e42927ed6c180302f07e6d395d08c416e594b98b46", size = 211107, upload-time = "2026-07-06T21:32:12.328Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/30/c806937ed5e4c2c7ac30d9d6b76b5dc57ff8b75d83800d9bb11a8253cf2a/cffi-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a016194dbe13d14ee9556e734b772d8d67b947092b268d757fd4290e3ba2dfc2", size = 218733, upload-time = "2026-07-06T21:32:13.67Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/cf/398272b8bbfd58aa314fda5a7f1cdbb26d1d78ae324a11211521315dd1f0/cffi-2.1.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:03e9810d18c646077e501f661b682fbf5dee4676048527ca3cffe66faa9960dd", size = 205543, upload-time = "2026-07-06T21:32:15.148Z" },
+ { url = "https://files.pythonhosted.org/packages/45/ca/f91641185cdd90c36d317a9dc7f85e88ef8682d8b300977baff5e23c35d8/cffi-2.1.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:19c54ac121cad98450b4896fa9a43ee0180d57bc4bc911a33db6cab1efab6cd3", size = 205460, upload-time = "2026-07-06T21:32:16.479Z" },
+ { url = "https://files.pythonhosted.org/packages/38/66/04781a77b411f0bb5b234d62c1814754ab75ebe455ccff1b08e8d7aae98f/cffi-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d433a51f1870e43a13b6732f92aaf540ff77c2015097c78556f75a2d6c030e0", size = 218760, upload-time = "2026-07-06T21:32:17.98Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/9a/bb1d5ed9c3fcae158e9f6391bf309c95d98c2ac37ed56573228471d0af5e/cffi-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3d7f118b5adbfdfead90c25822690b02bc8074fba949bb7858bec4ebd55adb43", size = 221230, upload-time = "2026-07-06T21:32:19.407Z" },
+ { url = "https://files.pythonhosted.org/packages/41/aa/3c1409cdd26094efacd1c36c66e0a6eb9d4296e4fd4f9901b8b2042f4323/cffi-2.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c5f5df567f6eb216de69be06ce55c8b714090fae02b18a3b40da8163b8c5fa9c", size = 213524, upload-time = "2026-07-06T21:32:20.828Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/75/74dfb7c3fc6ebbd408038476bd4c1d7e925c62614e7b9c534ecc34218288/cffi-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:11b3fb55f4f8ad92274ed26705f65d8f91457de71f5380061eb6d125a768fecd", size = 220341, upload-time = "2026-07-06T21:32:21.9Z" },
+ { url = "https://files.pythonhosted.org/packages/70/b6/9003c33a3e7d2c1306f5962e646457dcfe5a8cd8fce6bbe02d7af25db783/cffi-2.1.0-cp310-cp310-win32.whl", hash = "sha256:9d72af0cf10a76a600a9690078fe31c63b9588c8e86bf9fd353f713c84b5db0f", size = 174578, upload-time = "2026-07-06T21:32:23.073Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/26/710688310447531c7a22f857c7f79d9855ec18b03e04494ced723fb37e2f/cffi-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb62edb5bb52cca65fab91a63afa7561607120d26090a7e8fda6fb9f064726da", size = 185071, upload-time = "2026-07-06T21:32:24.671Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/67/85c89a59ba36a671e79638f44d466749f08179266a57e4f2ffdf92174072/cffi-2.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:02cb7ff33ded4f1532476731f89ede53e2e488a8e6205515a82144246ffa7dcc", size = 183845, upload-time = "2026-07-06T21:32:26.32Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/dd/e3b0baa2d3d6a857ac72b7efbf18e32e487c9cdafcc13049ad765495b15e/cffi-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5bce581e6b8c235e566a14768a943b172ada3ed73537bb0c0be1edee312d4e7", size = 184186, upload-time = "2026-07-06T21:32:28.025Z" },
+ { url = "https://files.pythonhosted.org/packages/65/68/9f3ef890cf3c6ab97bd531c5677f67613d302165d16f8142b2811782a614/cffi-2.1.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:30b65779d598c370374fefabf138d456fd6f3216bfa7bedfab1ba82025b0cd93", size = 211892, upload-time = "2026-07-06T21:32:29.565Z" },
+ { url = "https://files.pythonhosted.org/packages/22/d7/1a74539db16d8bfd839ff1515948948efbb162e574650fd3d846896eea95/cffi-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88023dfe18799507b73f1dbb0d14326a17465de1bc9c9c7655c22845e9ddc3a2", size = 218793, upload-time = "2026-07-06T21:32:30.951Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/d1/9a5b7169499e8e8d8e636de70b97ac7c9447104d2ff1a2cd94790cea5162/cffi-2.1.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:0a96b74cda968eebbad56d973efe5098974f0a9fb323865bf99ea1fd24e3e64c", size = 205737, upload-time = "2026-07-06T21:32:32.216Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/b0/e131a9c41f10607926278453d9596163594fe1c4ebc46efe3b5e5b34eb84/cffi-2.1.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a5781494d4d400a3f47f8f1da94b324f6e6b440a53387774002890a2a2f4b50f", size = 204909, upload-time = "2026-07-06T21:32:33.655Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/d2/4398416cd699b35167947c6e22aca52c47e69ad5695073c9f1f2c52e04aa/cffi-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aa7a1b53a2a4452ada2d1b5dade9960b2522f1e61293a811a077439e39029565", size = 217883, upload-time = "2026-07-06T21:32:35.173Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/a5/d4fe77b589e5e82d43ebc809bf2e6474afe8e48e32ea050b9357645b6471/cffi-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d8272c0e483b024e1b9ad029821470ed8ec65631dbd90217469da0e7cd89f1c", size = 221251, upload-time = "2026-07-06T21:32:36.527Z" },
+ { url = "https://files.pythonhosted.org/packages/22/f0/a2fc43084c0433caf7f461bccc013e28f848d04ee1c5ed7fce71423cf4d9/cffi-2.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7762faa47e8ff7eb80bd261d9a7d8eea2d8baa69de5e95b70c1f338bbe712f02", size = 214250, upload-time = "2026-07-06T21:32:37.852Z" },
+ { url = "https://files.pythonhosted.org/packages/04/8c/b925975448cf20634a9fbd5efceb807219db452653648d2897c0989cab2d/cffi-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89095c1968b4ba8285840e131bf2891b09ae137fe2146905acae0354fbce1b5e", size = 219441, upload-time = "2026-07-06T21:32:39.146Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/da/5c4918a2d61d86fa927d716cb3d8e4626ef8dc8f605a599d32f33897f59a/cffi-2.1.0-cp311-cp311-win32.whl", hash = "sha256:64c753a0f87a256020004f37a1c8c02c480e725f910f0b2a0f3f07debd1b2479", size = 174496, upload-time = "2026-07-06T21:32:40.467Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/c8/6c2de1d55cf35ef8b92885d5ef280790f0fb9634d87ea1cc315176aecd61/cffi-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:4f26194e3d95e06501b942642855aed4f953d55e95d7d01b7c4483db3ecff458", size = 185113, upload-time = "2026-07-06T21:32:41.761Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/4e/e8d7cb5783f1841a3c8fb3a7735838d7484d08ec08c9f984b14cac1ac0e9/cffi-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:35aaea0c7ee0e58a5cd8c2fd1a48fdf7ece0d2699b7ecdda08194e9ce5dd9b3d", size = 179927, upload-time = "2026-07-06T21:32:42.961Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/85/990925db5df586ec90beb97529c853497e7f85ba0234830447faf41c3057/cffi-2.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:df2b82571a1b30f58a87bf4e5a9e78d2b1eff6c6ce8fd3aa3757221f93f0863f", size = 184829, upload-time = "2026-07-06T21:32:44.324Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/92/e7bb136ad6b5352603732cf907ef862ca103f20f2031c1735a46300c20c9/cffi-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78474632761faa0fb96f30b1c928c84ebcf68713cbb80d15bab09dfe61640fde", size = 184728, upload-time = "2026-07-06T21:32:45.683Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/c0/d1ec30ffb370f748f2fb54425972bfef9871e0132e82fb589c46b6676049/cffi-2.1.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5972433ad71a9e46516584ef60a0fda12d9dc459938d1539c3ddecf9bdc1368d", size = 214815, upload-time = "2026-07-06T21:32:48.557Z" },
+ { url = "https://files.pythonhosted.org/packages/1b/dc/5620cf930688be01f2d673804291de757a934c90b946dbdc3d84130c2ea4/cffi-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b6422532152adf4e59b110cb2808cee7a033800952f5c036b4af047ee43199e7", size = 222429, upload-time = "2026-07-06T21:32:49.848Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/a4/77b53abbf7a1e0beb9637edbef2a94d15f9c822f591e85d439ffd91519a6/cffi-2.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:46b1c8db8f6122420f32d02fffb924c2fe9bc772d228c7c711748fff56aabb2b", size = 210315, upload-time = "2026-07-06T21:32:51.221Z" },
+ { url = "https://files.pythonhosted.org/packages/58/0c/f528df19cc94b675087324d4760d9e6d5bfae97d6217aa4fac43de4f5fcc/cffi-2.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9fafc5aa2e2a39aaf7f8cc0c1f044a9b07fca12e558dca53a3cc5c654ad67a7", size = 208859, upload-time = "2026-07-06T21:32:52.512Z" },
+ { url = "https://files.pythonhosted.org/packages/62/f2/c9522a81c32132799a1972c39f5c5f8b4c8b9f00488a23feaa6c06f07741/cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e9f50d192a3e525b15a75ab5114e442d83d657b7ec29182a991bc9a88fd3a66", size = 221844, upload-time = "2026-07-06T21:32:53.704Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/28/bd53988b9833e8f8ad539d26f4c07a6b3f6bcb1e9e02e7ca038250b3428d/cffi-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98fff996e983a36d3aa2eca83af40c5821202e7e6f32d13ae94e3d2286f10cfe", size = 225287, upload-time = "2026-07-06T21:32:54.907Z" },
+ { url = "https://files.pythonhosted.org/packages/79/99/0d0fd37f055224085f42bbb2c022d002e17dde4a97972822327b07d84101/cffi-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:379de10ce1ba048b1448599d1b37b24caee16309d1ac98d3982fc997f768700b", size = 223681, upload-time = "2026-07-06T21:32:56.329Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/80/c138990aa2a70b1a269f6e06348729836d733d6f970867943f61d367f8cc/cffi-2.1.0-cp312-cp312-win32.whl", hash = "sha256:9b8f0f26ca4e7513c534d351eca551947d053fac438f2a04ac96d882909b0d3a", size = 175269, upload-time = "2026-07-06T21:32:57.777Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/eb/f636456ff21a83fc13c032b58cc5dde061691546ac79efa284b2989b7982/cffi-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:c97f080ea627e2863524c5af3836e2270b5f5dfff1f104392b959f8df0c5d384", size = 185881, upload-time = "2026-07-06T21:32:59.253Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/2c/400ea43e721727dca8a65c4521390e9196757caba4a45643acb2b63271b8/cffi-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:6d194185eabd279f1c05ebe3504265ddfc5ad2b58d0714f7db9f01da592e9eb6", size = 180088, upload-time = "2026-07-06T21:33:02.278Z" },
+ { url = "https://files.pythonhosted.org/packages/96/88/a996879e2eeccb815f6e3a5967b12a308257412acec882039d386bd2aa7b/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:10537b1df4967ca26d21e5072d7d54188354483b91dc75058968d3f0cf13fbda", size = 194331, upload-time = "2026-07-06T21:33:03.697Z" },
+ { url = "https://files.pythonhosted.org/packages/58/85/7ae00d5c8dd6266f4e944c3db630f3c5c9a98b61d469c714d848b1d8138a/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a95b05f9baf29b91171b3a8bd2020b028835243e7b0ff6bb23e2a3c228518b1b", size = 196966, upload-time = "2026-07-06T21:33:05.353Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/e9/45c3a76ad8d43ad9261f4c95436da61128d3ca545d72b9612c0ab5be0b1c/cffi-2.1.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:15faec4adfff450819f3aee0e2e02c812de6edb88203aa58807955db2003472a", size = 184795, upload-time = "2026-07-06T21:33:06.699Z" },
+ { url = "https://files.pythonhosted.org/packages/84/4c/82f132cb4418ee6d953d982b19191e87e2a6372c8a4ce36e50b69d6ade4a/cffi-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:716ff8ec22f20b4d988b12884086bcef0fc99737043e503f7a3935a6be99b1ea", size = 184746, upload-time = "2026-07-06T21:33:08.071Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/1c/4ed5a0e5bdca6cbc275556de3328dd1b76fd0c11cc13c88fe66d1d8715f2/cffi-2.1.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:63960549e4f8dc41e31accb97b975abaecfc44c03e396c093a6436763c2ea7db", size = 214747, upload-time = "2026-07-06T21:33:09.671Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/a6/e879bb68cc23a2bc9ba8f4b7d8019f0c2694bad2ab6c4a3701d429439f58/cffi-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff067a8d8d880e7809e4ac88eb009bb848870115317b306666502ccad30b147f", size = 222392, upload-time = "2026-07-06T21:33:10.896Z" },
+ { url = "https://files.pythonhosted.org/packages/88/f6/01890cfd63c08f8eb96a8319b0443690197d240a8bd6346048cf7bde9190/cffi-2.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3b926723c13eba9f81d2ef3820d63aeceec3b2d4639906047bf675cb8a7a500d", size = 210285, upload-time = "2026-07-06T21:33:12.251Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/cf/2b684132056f438567b61e19d690dd31cd0921ace051e0a458be6074369e/cffi-2.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:47ff3a8bfd8cb9da1af7524b965127095055654c177fcfc7578debcb015eecd0", size = 208801, upload-time = "2026-07-06T21:33:13.617Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/08/f2e7d62c460faae0926f2d6e423694aa409ced3bc1fe2927a0a6e5f05416/cffi-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:799416bae98336e400981ff6e532d67d5c709cfb30afb79865a1315f94b0e224", size = 221808, upload-time = "2026-07-06T21:33:15.466Z" },
+ { url = "https://files.pythonhosted.org/packages/38/37/04f54b8e63a02f3d908332c9effbf8c366167c6f733ed8a3d4f79b7e2a1e/cffi-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:961be50688f7fba2fa65f63712d3b9b341a22311f5253460ce933f52f0de1c8c", size = 225241, upload-time = "2026-07-06T21:33:16.869Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/d6/c72eecca433cd3e681c65ed313ab4835d9d4a379704d0f628a6a05f51c2e/cffi-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf5c6cf48238b0eb4c086978c492ad1cbc22373fc5b2d7353b3a598ce6db887a", size = 223588, upload-time = "2026-07-06T21:33:18.239Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/4b/e706f67279140f92939da3475ad610df18bfd52d50f14953a8e5fede71d5/cffi-2.1.0-cp313-cp313-win32.whl", hash = "sha256:db3eb7d46527159a878ec3460e9d40615bc25ba337d477db681aea6e4f05c5d2", size = 175248, upload-time = "2026-07-06T21:33:19.799Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/47/59eb7975cb0e4ef0afa764ea945b29a5bb4537a9f771cb7d6c8a5dd74c95/cffi-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:8e74a6135550c4748af665b1b1118b6aab33b1fc6a16f9aff630af107c3b4512", size = 185717, upload-time = "2026-07-06T21:33:21.47Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/af/34fee85c48f8d94efc8597bc09470c9dd274c145f1c12e0fbc6ab6d38d74/cffi-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:2282cd5e38aa8accd03e99d1256af8411c84cdbee6a89d841b563fdbd1f3e50f", size = 180114, upload-time = "2026-07-06T21:33:22.515Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/f0/81478e482afa03f6d18dc8f2afb5edc45b3080853b634b5ed91961be0998/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2117334c3af3bdcb9a88522b844a2bdb5efdc4f71c6c822df55486ae1c3347a", size = 194142, upload-time = "2026-07-06T21:33:23.657Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/95/8de304305cd9204974b0ca051b86d307cafca13aa575a0ef1b44d92c0d8c/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:702c436735fbe99d59ada02a1f65cfc0d31c0ee8b7290912f8fbc5cd1e4b16c3", size = 196819, upload-time = "2026-07-06T21:33:25.007Z" },
+ { url = "https://files.pythonhosted.org/packages/20/71/7c8372d30e42415602ed9f268f7cfd66f1b855fed881ecd168bcb45dbc0b/cffi-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1ff3456eab0d889592d1936d6125bbfbc7ae4d3354a700f8bd80450a66445d4d", size = 184965, upload-time = "2026-07-06T21:33:26.605Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/5c/584e626835f0375c928176c04137c96927165cb8733cdb3150ec04e5ee5e/cffi-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c4165821e131d6d4ca444347c2b694e2311bcfa3fe5a861cc72968f28867beac", size = 184952, upload-time = "2026-07-06T21:33:27.823Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/d2/065fcae1c73979fac8e054462478d0ff8a29c40cdc2ed7ea5676a061df53/cffi-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:276f20fffd7b396e12516ba8edf9509210ac248cbbc5acbc39cd512f9f59ebe6", size = 222353, upload-time = "2026-07-06T21:33:29.178Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/a5/e8bbb1ce5b3ac2f53ad6a10bde44318a5a8d99d4f4a000d44a6e39aeb3e4/cffi-2.1.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7d5980a3433d4b71a5e120f9dd551403d7824e31e2e67124fe2769c404c06913", size = 210051, upload-time = "2026-07-06T21:33:30.534Z" },
+ { url = "https://files.pythonhosted.org/packages/28/ed/c127d3ac36e899c965e3361357c3befacd6578c03f40125183e41c3b219e/cffi-2.1.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6ca4919c6e4f89aa99c42510b42cf54596892c00b3f9077f6bdd1505e24b9c8d", size = 208630, upload-time = "2026-07-06T21:33:31.753Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/d7/97d3136f81db489ec8d1d67748c110d6c994268fd7528014aa9f2b085e4e/cffi-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d53d10f7da99ae46f7373b9150393e9c5eab9b224909982b43832668de4779f5", size = 221593, upload-time = "2026-07-06T21:33:33.044Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/27/93195977168ee63aed233a1a0993a2178798654d1f4bddcdd321d6fd3b21/cffi-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c351efb95e832a853a29361675f33a7ce53de1a109cd73fd47af0712213aa4ce", size = 225146, upload-time = "2026-07-06T21:33:34.224Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/c1/6dbd291ee2ae5a50a034aa057207081f545923bbf15dad4511e985aafff5/cffi-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7c7a88e2bac086f06d14577332760bdeecc42bdec8ac4077f6260557d9326", size = 223240, upload-time = "2026-07-06T21:33:35.57Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/6f/ade5ce9863a57992a6ea3d0d10d7e29b8749fc127204b3d493d667b2815f/cffi-2.1.0-cp314-cp314-win32.whl", hash = "sha256:1854b724d00f6654c742097d5387569021be12d3a0f770eae1df8f8acfcc6acd", size = 177723, upload-time = "2026-07-06T21:33:51.626Z" },
+ { url = "https://files.pythonhosted.org/packages/41/de/92b9eeed4ae4a21d6fd9b2a2c8505cbed573299902ea73981cc13f7ff62c/cffi-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:1b96bfe2c4bd825681b7d311ad6d9b7280a091f43e8f63da5729638083cd3bfb", size = 187937, upload-time = "2026-07-06T21:33:53.403Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/1a/cc6ae6c2913a03aab8898eee57963cf1035b8df5872ed8b9115fcc7e2be8/cffi-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:7d28dff1db6764108bc30788d85d61c876beff416d9a49cb9dd7c5a9f34f5804", size = 183001, upload-time = "2026-07-06T21:33:54.74Z" },
+ { url = "https://files.pythonhosted.org/packages/14/f0/134c00ce0779ec86dea2aa1aac69339c2741a8045072676763512363a2ea/cffi-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7ea6b3e2c4250ff1de21c630fe72d0f63eb95c2c32ffbf64a358cf4a8836d714", size = 188538, upload-time = "2026-07-06T21:33:36.792Z" },
+ { url = "https://files.pythonhosted.org/packages/50/d8/3b86aba791cb610d24e8a3e1b2cd529e71fa15096b04e4d4e360049d4a4c/cffi-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6af371f3767faeffc6ac1ef57cdfd25844403e9d3f476c5537caee499de96376", size = 188230, upload-time = "2026-07-06T21:33:38.011Z" },
+ { url = "https://files.pythonhosted.org/packages/14/d0/117dcd9209255ad8571fbc8c92ef32593a1d294dcec91ddc4e4db50606f2/cffi-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb4e8997a49aa2c08a3e43c9045d224448b8941d88e7ac163c7d383e560cbf98", size = 223899, upload-time = "2026-07-06T21:33:39.514Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/3d/f20f8b886b254e3ad10e15cd4186d3aed49f3e6a35ab37aab9f8f25f7c03/cffi-2.1.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf01d8c84cbea96b944c73b22182e6c7c432b3475632b8111dbfdc95ddad6e13", size = 211652, upload-time = "2026-07-06T21:33:40.851Z" },
+ { url = "https://files.pythonhosted.org/packages/28/3b/fad54de07260b93ddeef4b96d0131d57ea900675df1d410ae1deee52d7a6/cffi-2.1.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:33eb1ad83ebe8f313e0df035c406227d55a79456704a863fad9842136af5ad7d", size = 210755, upload-time = "2026-07-06T21:33:42.183Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/82/3d5c705acb7abbba9bbd7d79b8e62e0f25b6120eb7ae6ac49f1b721722fe/cffi-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ac0f1a2d0cfa7eea3f2aaf006ab6e70e8feeb16b75d65b7e5939982ca2f11056", size = 223933, upload-time = "2026-07-06T21:33:43.603Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/d0/47e338384ab6b1004241002fa616301020cea4fc95f283506565d252f276/cffi-2.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c16914df9fb7f500e440e6875fa23ff5e0b31db01fa9c06af98d59a91f0dc2e4", size = 226749, upload-time = "2026-07-06T21:33:45.046Z" },
+ { url = "https://files.pythonhosted.org/packages/70/25/65bd5b58ea4bfdfc15cde02cb5365f89ef8ab8b2adfb8fe5c4bd4233382f/cffi-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5ecbd0499275d57506d397eebe1981cee87b47fcd9ef5c22cab7ed7644a39a94", size = 225703, upload-time = "2026-07-06T21:33:46.374Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/78/aa01ac599a8a4322533d45a1f9bc93b338276d2d59dabbe7c6d92a775c81/cffi-2.1.0-cp314-cp314t-win32.whl", hash = "sha256:7d034dcffa09e9a46c93fa3a3be402096cb5354ac6e41ab8e5cc9cd8b642ad76", size = 182857, upload-time = "2026-07-06T21:33:47.696Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/26/d00496b22de4d4228f32dde94ad996f350c8aad676d63bcca0743c8dea4d/cffi-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0582a58f3051372229ca8e7f5f589f9e5632678208d8636fea3676711fdf7fe5", size = 194065, upload-time = "2026-07-06T21:33:48.953Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/dd/0c7dbf815a579ff005008a2d815a55d6bb047c349eef536d9dc53d3f0a8d/cffi-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:510aeeeac94811b138077451da1fb18b308a5feab47dd2b603af55804155e1c8", size = 186404, upload-time = "2026-07-06T21:33:50.309Z" },
+ { url = "https://files.pythonhosted.org/packages/55/c7/8c8c50cb11c6750051daf12164098a9a6f027ac4356967fd4d800a07f242/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:2e9dabb9abcb7ad15938c7196ad5c1718a4e6d33cc79b4c0209bdb64c4a54a5c", size = 194121, upload-time = "2026-07-06T21:33:56.109Z" },
+ { url = "https://files.pythonhosted.org/packages/99/e2/67680bf19a6b60d2bb7ff83baefa2a4c3d2d7dc0f3277034b802e1fc504c/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:37f525a7e7e50c017fdebe58b787be310ad59357ae43a053943a6e1a6c526001", size = 196820, upload-time = "2026-07-06T21:33:57.288Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/da/4bbe583a3b3a5c8c60892124fe17f3fa3656523faf0d3484eae90f091853/cffi-2.1.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:95f2954c2c9473d892eca6e0409f3568b37ab62a8eedb122461f73cc273476e3", size = 184936, upload-time = "2026-07-06T21:33:58.765Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/4b/1f4c36ab273980d7aa75bb126ea4f8971f24a96108acad3a0a084028c57b/cffi-2.1.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:cdf2448aab5f661c9315308ec8b93f4e8a1a67a3c733f8631067a2b67d5913dc", size = 185045, upload-time = "2026-07-06T21:34:00.085Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/c3/ad299dc38f3583f8d916b299f028af418a9ec98bc695fcbebeae7420691c/cffi-2.1.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90bec57cf82089383bd06a605b3eb8daebf7e5a668520beaf6e327a83a947699", size = 222342, upload-time = "2026-07-06T21:34:01.814Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/d8/df4543cc087245044ed02ef3ad8e0a26619d0075ac7a77a12dc81177851b/cffi-2.1.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6274dcb2d15cef48daa73ed1be5a40d501d74dccd0cd6db364776d12cb6ba022", size = 210073, upload-time = "2026-07-06T21:34:03.255Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/0e/fac738d73728c6cea2a88a2883dca54892496cbba88a1dc1f2909cb8a6f5/cffi-2.1.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b71d409cccee78310ab5dec549aed052aaea483346e282c7b02362596e01bb0", size = 208551, upload-time = "2026-07-06T21:34:04.433Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/3f/0b04a700dd64f465c93020253a793a82c9b4dff9961f48facd0df945d9b8/cffi-2.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d3538f9c0e50670f4deb93dbb696576e60590369cae2faf7de681e597a8a1f1", size = 221649, upload-time = "2026-07-06T21:34:06.157Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/7c/b7379a5704c79eda57ce075869ba70a0368d1c850f803b3c0d078d39dcaf/cffi-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:8f9ec95b8a043d3dfbc74d9abc6f7baf524dd27a8dc160b0a32ff9cdab650c28", size = 225203, upload-time = "2026-07-06T21:34:07.489Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/02/d5e6c43ea85c41bda2a184a3418f195fe7cf602967a8d2b94e085b83deef/cffi-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:af5e2915d41fe6c961694d7bfdc8562942638200f3ce2765dfb8b745cf997629", size = 223263, upload-time = "2026-07-06T21:34:08.712Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/d8/772b8259bf75749adffb1c546828978381fb516f60cf701f6c83daf60c85/cffi-2.1.0-cp315-cp315-win32.whl", hash = "sha256:0a42c688d19fca6e095a53c6a6e2295a5b050a8b289f109adab02a9e61a25de6", size = 177696, upload-time = "2026-07-06T21:34:26.355Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/dd/afa2191fc6d57fedd26e5844a2fe2fcc0bbfa00961bbaa5a41e4921e7cca/cffi-2.1.0-cp315-cp315-win_amd64.whl", hash = "sha256:bccbbb5ee76a61f9d99b5bf3846a51d7fca4b6a732fe46f89295610edaf41853", size = 187914, upload-time = "2026-07-06T21:34:27.58Z" },
+ { url = "https://files.pythonhosted.org/packages/05/ef/6cd4f8c671517162379dc79cfae5aea9106bc38abb89628d5c16adf6a838/cffi-2.1.0-cp315-cp315-win_arm64.whl", hash = "sha256:8d35c139744adb3e727cd51b1a18324bbe44b8bd41bf8322bca4d41289f48eda", size = 183004, upload-time = "2026-07-06T21:34:28.905Z" },
+ { url = "https://files.pythonhosted.org/packages/11/b6/12fc55092817a5faa26fb8c40c7f9d662e11a46ee248c137aafc42517d92/cffi-2.1.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f9912624a0c0b834b7520d7769b3644453aabc0a7e1c839da7359f050750e9bc", size = 188378, upload-time = "2026-07-06T21:34:09.926Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/2e/cdac88979f295fde5daa69622c7d2111e56e7ceb94f211357fbe452339e4/cffi-2.1.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:df92f2aba50eb4d96718b68ef76f2e57a57b54f2fa62333496d16c6d585a85ca", size = 188319, upload-time = "2026-07-06T21:34:11.101Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/27/1d0b408497e41a74795af122d7b603c418c5fed0171450f899afd04e594f/cffi-2.1.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0520e1f4c35f44e209cbbb421b67eec42e6a157f59444dfb6058874ff3610e5d", size = 223904, upload-time = "2026-07-06T21:34:12.606Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/31/e115c985105dd7ffb32444505f18ceb874bb42d992af05d5dced7ecf1980/cffi-2.1.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3681e031db29958a7502f5c0c9d6bbc4c36cb20f7b104086fa642d1799631ff8", size = 211554, upload-time = "2026-07-06T21:34:13.987Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/67/9e6e09409336d9e515c58367e7cfcf4f89df06ad25252675595a58eb59d5/cffi-2.1.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:762f99479dcb369f60ab9017ad4ab97a36a1dd7c1ee5a3b15db0f4b8659120cd", size = 210795, upload-time = "2026-07-06T21:34:15.972Z" },
+ { url = "https://files.pythonhosted.org/packages/19/e5/d3cc82a4a0be7902af279c04181ad038449c096734464a5ae1de3e1401bd/cffi-2.1.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0611e7ebf90573a535ebdc33ae9da222d037853983e13359f580fab781ca017f", size = 223843, upload-time = "2026-07-06T21:34:17.509Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/65/b434abc97ce7cecc2c640fde160507c0ecc7e21544b483ba3325d2e2ea17/cffi-2.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:86cf8755a791f72c85dc287128cc62d4f24d392e3f1e15837245623f4a33cccc", size = 226773, upload-time = "2026-07-06T21:34:19.05Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/9f/d4dc66ca651eb1145a133314cda721abf13cfac3d28c4a0402263ae6ad75/cffi-2.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:ba00f661f8ba35d075c937174e27c2c421cec3942fd2e0ea3e66996757c0fdd9", size = 225719, upload-time = "2026-07-06T21:34:20.576Z" },
+ { url = "https://files.pythonhosted.org/packages/68/5a/e536c528bc8057496c360c0978559a2dc45653f89dd6151078aa7d8fca1a/cffi-2.1.0-cp315-cp315t-win32.whl", hash = "sha256:cb96698e3c7413d906ce83f8ffd245ec1bd94707541f299d0ce4d6b0193e982b", size = 182760, upload-time = "2026-07-06T21:34:22.059Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/0b/0ffe8b82d3875bced5fa1e7986a7a46b748262a40ab7f60b475eb9fb1bb3/cffi-2.1.0-cp315-cp315t-win_amd64.whl", hash = "sha256:f146d154428a2523f9cc7936c02353c2459b8f6cf07d3cd1ee1c0a611109c5d5", size = 193769, upload-time = "2026-07-06T21:34:23.589Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/17/1073b53b68c9b5ca6914adf5f8bf55aacc2d3be102418c90700160ea8605/cffi-2.1.0-cp315-cp315t-win_arm64.whl", hash = "sha256:cbb7640ce37159548d2147b5b8c241f962143d4c71231431820783f4dc78f210", size = 186405, upload-time = "2026-07-06T21:34:24.857Z" },
]
[[package]]
name = "charset-normalizer"
-version = "3.4.7"
+version = "3.4.9"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b", size = 152439, upload-time = "2026-07-07T14:34:58.454Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d", size = 315182, upload-time = "2026-04-02T09:25:40.673Z" },
- { url = "https://files.pythonhosted.org/packages/24/47/b192933e94b546f1b1fe4df9cc1f84fcdbf2359f8d1081d46dd029b50207/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8", size = 209329, upload-time = "2026-04-02T09:25:42.354Z" },
- { url = "https://files.pythonhosted.org/packages/c2/b4/01fa81c5ca6141024d89a8fc15968002b71da7f825dd14113207113fabbd/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790", size = 231230, upload-time = "2026-04-02T09:25:44.281Z" },
- { url = "https://files.pythonhosted.org/packages/20/f7/7b991776844dfa058017e600e6e55ff01984a063290ca5622c0b63162f68/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc", size = 225890, upload-time = "2026-04-02T09:25:45.475Z" },
- { url = "https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393", size = 216930, upload-time = "2026-04-02T09:25:46.58Z" },
- { url = "https://files.pythonhosted.org/packages/e2/ab/b18f0ab31cdd7b3ddb8bb76c4a414aeb8160c9810fdf1bc62f269a539d87/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153", size = 202109, upload-time = "2026-04-02T09:25:48.031Z" },
- { url = "https://files.pythonhosted.org/packages/82/e5/7e9440768a06dfb3075936490cb82dbf0ee20a133bf0dd8551fa096914ec/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af", size = 214684, upload-time = "2026-04-02T09:25:49.245Z" },
- { url = "https://files.pythonhosted.org/packages/71/94/8c61d8da9f062fdf457c80acfa25060ec22bf1d34bbeaca4350f13bcfd07/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34", size = 212785, upload-time = "2026-04-02T09:25:50.671Z" },
- { url = "https://files.pythonhosted.org/packages/66/cd/6e9889c648e72c0ab2e5967528bb83508f354d706637bc7097190c874e13/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1", size = 203055, upload-time = "2026-04-02T09:25:51.802Z" },
- { url = "https://files.pythonhosted.org/packages/92/2e/7a951d6a08aefb7eb8e1b54cdfb580b1365afdd9dd484dc4bee9e5d8f258/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752", size = 232502, upload-time = "2026-04-02T09:25:53.388Z" },
- { url = "https://files.pythonhosted.org/packages/58/d5/abcf2d83bf8e0a1286df55cd0dc1d49af0da4282aa77e986df343e7de124/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53", size = 214295, upload-time = "2026-04-02T09:25:54.765Z" },
- { url = "https://files.pythonhosted.org/packages/47/3a/7d4cd7ed54be99973a0dc176032cba5cb1f258082c31fa6df35cff46acfc/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616", size = 227145, upload-time = "2026-04-02T09:25:55.904Z" },
- { url = "https://files.pythonhosted.org/packages/1d/98/3a45bf8247889cf28262ebd3d0872edff11565b2a1e3064ccb132db3fbb0/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a", size = 218884, upload-time = "2026-04-02T09:25:57.074Z" },
- { url = "https://files.pythonhosted.org/packages/ad/80/2e8b7f8915ed5c9ef13aa828d82738e33888c485b65ebf744d615040c7ea/charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374", size = 148343, upload-time = "2026-04-02T09:25:58.199Z" },
- { url = "https://files.pythonhosted.org/packages/35/1b/3b8c8c77184af465ee9ad88b5aea46ea6b2e1f7b9dc9502891e37af21e30/charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943", size = 159174, upload-time = "2026-04-02T09:25:59.322Z" },
- { url = "https://files.pythonhosted.org/packages/be/c1/feb40dca40dbb21e0a908801782d9288c64fc8d8e562c2098e9994c8c21b/charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008", size = 147805, upload-time = "2026-04-02T09:26:00.756Z" },
- { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" },
- { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" },
- { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" },
- { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" },
- { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" },
- { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" },
- { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" },
- { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" },
- { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" },
- { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" },
- { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" },
- { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" },
- { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" },
- { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" },
- { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" },
- { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" },
- { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" },
- { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" },
- { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" },
- { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" },
- { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" },
- { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" },
- { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" },
- { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" },
- { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" },
- { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" },
- { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" },
- { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" },
- { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" },
- { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" },
- { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" },
- { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" },
- { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" },
- { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" },
- { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" },
- { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" },
- { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" },
- { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" },
- { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" },
- { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" },
- { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" },
- { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" },
- { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" },
- { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" },
- { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" },
- { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" },
- { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" },
- { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" },
- { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" },
- { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" },
- { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" },
- { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" },
- { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" },
- { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" },
- { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" },
- { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" },
- { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" },
- { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" },
- { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" },
- { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" },
- { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" },
- { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" },
- { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" },
- { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" },
- { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" },
- { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" },
- { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" },
- { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" },
- { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" },
- { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" },
- { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" },
- { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" },
- { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" },
- { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" },
- { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" },
- { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" },
- { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" },
- { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" },
- { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" },
- { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" },
- { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" },
+ { url = "https://files.pythonhosted.org/packages/ad/81/8e983840c6e5b93b33c2ba81aa3d52c2e42f0e9a690ce7607a2e61da4a5c/charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a", size = 322240, upload-time = "2026-07-07T14:32:36.236Z" },
+ { url = "https://files.pythonhosted.org/packages/de/d1/b4319dc3229d8272fba305e206fc0a148e2de8d4087917ce62ae6382f359/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616", size = 216475, upload-time = "2026-07-07T14:32:38.142Z" },
+ { url = "https://files.pythonhosted.org/packages/80/33/6c99c1b3e6b8bf730e1bc809b9a2608f224145069114c479a2e9e1494346/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209", size = 238670, upload-time = "2026-07-07T14:32:39.658Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/f4/ffbb83546e1f198ecc70ecd372b65cf2b50f9068b380abd67640f17a8e18/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99", size = 233476, upload-time = "2026-07-07T14:32:41.155Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/5f/b98b8da398637b551e427e7be922bdec19177dc54d6811dcdaa503f23aac/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8", size = 223817, upload-time = "2026-07-07T14:32:42.592Z" },
+ { url = "https://files.pythonhosted.org/packages/36/31/a276bb2e66243072a3fd06fdcab9cbb61a305b02143d70d2bda21d888fa8/charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b", size = 207974, upload-time = "2026-07-07T14:32:44.258Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/be/7ee4453d7e88dfbc4104ccd34900b9f2c7c17dac22881865fe0e82424a25/charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2", size = 221655, upload-time = "2026-07-07T14:32:45.64Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/85/181c652953eb5276d198f375b1dd641047392050098100a3a02d6534f657/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9", size = 219229, upload-time = "2026-07-07T14:32:47.376Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/e7/aaf6da33fc9f4691cda8f7efbc9f69179d3d39ec8a4799baf273ee1d8db0/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15", size = 209704, upload-time = "2026-07-07T14:32:48.855Z" },
+ { url = "https://files.pythonhosted.org/packages/63/01/f2fb3bd3a73be48b173ee0c6aa8d2497af97d5663a8c4c4b491de4c62f7a/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d", size = 226243, upload-time = "2026-07-07T14:32:50.239Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/02/c57a22739fe05246b0b5783b3bfb6afaac4eebb46f3ececdfb2f048f780e/charset_normalizer-3.4.9-cp310-cp310-win32.whl", hash = "sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381", size = 150935, upload-time = "2026-07-07T14:32:51.676Z" },
+ { url = "https://files.pythonhosted.org/packages/37/8d/ca39a7559a4797505530d084fd3a49a2c959efbbbff146302fb7be4e3b35/charset_normalizer-3.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee", size = 162314, upload-time = "2026-07-07T14:32:53.193Z" },
+ { url = "https://files.pythonhosted.org/packages/01/da/a44bd7a13d426e69e4894557106cd58669097bfad4a8681123b618fbfc5d/charset_normalizer-3.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419", size = 153075, upload-time = "2026-07-07T14:32:54.554Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/e3/85ec501f206fb049259288c1f3506e53876937fb00edb47009348e66756b/charset_normalizer-3.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5", size = 317075, upload-time = "2026-07-07T14:32:56.021Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/69/2a5385192e67175f7d8bd5ce4f57c24bc956439adeae5c13a99aa28a53d1/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2", size = 213837, upload-time = "2026-07-07T14:32:57.78Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/46/03ddc7da576d814fe0a36dd1f0fd3258e95404b4b2e3c026b7923d7e133f/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a", size = 235503, upload-time = "2026-07-07T14:32:59.205Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/6e/de0229a7ef40f6f9d28a837eebf4ec47bdca5dab4e900c84f22919af636a/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29", size = 229944, upload-time = "2026-07-07T14:33:00.803Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/34/49b9060e8418b14fb5cba9cf6bfb383111e2538a03a1fb18e66a95aeb3d5/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c", size = 221276, upload-time = "2026-07-07T14:33:02.199Z" },
+ { url = "https://files.pythonhosted.org/packages/44/95/80282cce0fae9c3061203d723ee87da996aed79679e65d8935050ee7ca1f/charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b", size = 205260, upload-time = "2026-07-07T14:33:03.698Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/74/2f62c8821b969ea3bd67cc2e6976834f48ca5d12664d2559ebcd9bcfbed7/charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db", size = 217786, upload-time = "2026-07-07T14:33:05.12Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/8d/feabb82cb49fcad14515b1d7d1ca4787b0da7fc723a212bf89bc9e0fac52/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993", size = 216798, upload-time = "2026-07-07T14:33:06.629Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/ff/c946d63bc3786d5b84d960b0f7ab7e25b828486a946b5aa997625bcaf6a6/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da", size = 206429, upload-time = "2026-07-07T14:33:08.006Z" },
+ { url = "https://files.pythonhosted.org/packages/af/ba/5e5007c370702f85d2ef75791fac7943ed41e080364a673b20142e430e3e/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3", size = 223066, upload-time = "2026-07-07T14:33:09.783Z" },
+ { url = "https://files.pythonhosted.org/packages/83/d5/9096aa3cf532dfad237861544eb47a0f20d5adbf1039760fed8eaae935d9/charset_normalizer-3.4.9-cp311-cp311-win32.whl", hash = "sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d", size = 150456, upload-time = "2026-07-07T14:33:11.217Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/a1/e29995109e455dc8eff8d0fac6ae509be39561318a7cfeac5d33ad029213/charset_normalizer-3.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1", size = 161410, upload-time = "2026-07-07T14:33:12.743Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/8d/1569f4d0032d6ba2a4fe4591c35bf87868c600c41a71eb5c2e1ffa8464c2/charset_normalizer-3.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec", size = 152649, upload-time = "2026-07-07T14:33:14.173Z" },
+ { url = "https://files.pythonhosted.org/packages/70/4a/ecbd131485c07fcdfad54e28946d513e3da22ef3b4bd854dcafae54ec739/charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0", size = 319300, upload-time = "2026-07-07T14:33:15.666Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/96/5d9364e3342d69f3a045e1777bc47c85c383e6e9466d561b33fdb419d1f9/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9", size = 215802, upload-time = "2026-07-07T14:33:17.031Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/4c/5361f9aa7f2cb58d94f2ab831b3d493f69efb1d239654b4744e3c09527cb/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44", size = 237171, upload-time = "2026-07-07T14:33:18.576Z" },
+ { url = "https://files.pythonhosted.org/packages/50/78/ce342ca4ff30b2eb49fe6d9578df85974f90c67d294113e94efdd9664cbd/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9", size = 233075, upload-time = "2026-07-07T14:33:20.084Z" },
+ { url = "https://files.pythonhosted.org/packages/01/c4/4fa4c8b3097a11f3c5f09a35b72ed6855fb1d332469504962ab7bafcc702/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd", size = 224256, upload-time = "2026-07-07T14:33:21.747Z" },
+ { url = "https://files.pythonhosted.org/packages/87/3a/ad914516df7e358a81aae018caa5e0470ba827fa6d763b1d2e87d920a5f6/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84", size = 208784, upload-time = "2026-07-07T14:33:23.313Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/74/3c12f9755717dfe5c5c87da63f35d765fa0c00382ec26bf23f7fae34f2ba/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b", size = 219928, upload-time = "2026-07-07T14:33:24.814Z" },
+ { url = "https://files.pythonhosted.org/packages/33/9a/895095b83e7907abd6d3d99aad3a38ad0d9686cc186cb0c94c24320fe63e/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde", size = 218489, upload-time = "2026-07-07T14:33:26.42Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/34/ef5c05f412f42520d7709b7d3784d19640839eb7366ded1755511585429f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39", size = 210267, upload-time = "2026-07-07T14:33:27.952Z" },
+ { url = "https://files.pythonhosted.org/packages/83/dc/9b29fa4412b318bf3bfea985c35d67eb55e04b59a7c3f2237168b0e0be6f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62", size = 226030, upload-time = "2026-07-07T14:33:29.397Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/42/6dbc00b8cd16011691203e33570fa42ed5746599a2e878112d16eab403a3/charset_normalizer-3.4.9-cp312-cp312-win32.whl", hash = "sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642", size = 151185, upload-time = "2026-07-07T14:33:30.781Z" },
+ { url = "https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0", size = 162557, upload-time = "2026-07-07T14:33:32.176Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/e6/0386d43a261ff4e4b30c5857af7df877254b46bec7b9d1b74b6bf969a90b/charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2", size = 152665, upload-time = "2026-07-07T14:33:33.711Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/06/97ec2aeae780b31d742b6352218b43841a6871e2564578ca522dce4a45c3/charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614", size = 317688, upload-time = "2026-07-07T14:33:35.408Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698", size = 214982, upload-time = "2026-07-07T14:33:36.996Z" },
+ { url = "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b", size = 236460, upload-time = "2026-07-07T14:33:38.536Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9", size = 232003, upload-time = "2026-07-07T14:33:40.059Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33", size = 223149, upload-time = "2026-07-07T14:33:41.631Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63", size = 207901, upload-time = "2026-07-07T14:33:43.209Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0", size = 219176, upload-time = "2026-07-07T14:33:44.725Z" },
+ { url = "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe", size = 217356, upload-time = "2026-07-07T14:33:46.192Z" },
+ { url = "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35", size = 209614, upload-time = "2026-07-07T14:33:47.705Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8", size = 224991, upload-time = "2026-07-07T14:33:49.238Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/a3/53ddae3db108a088156aa8ddfafd411ebbc1340f48c5573f697b27f69a39/charset_normalizer-3.4.9-cp313-cp313-win32.whl", hash = "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9", size = 150622, upload-time = "2026-07-07T14:33:50.711Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/ef/6953a77c7cf2c2ff9998e6f575ab3e380119f100223381565a4f94c1f836/charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115", size = 161947, upload-time = "2026-07-07T14:33:52.197Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/fb/d560d1d1555debbfe7849d9cac6145c1b537709d79576bf22557ed803b82/charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012", size = 152594, upload-time = "2026-07-07T14:33:53.486Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/8d/496817fa0944239ecae662dd57ea765cfeaec6a735f9f025d4b7b72e7143/charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380", size = 317253, upload-time = "2026-07-07T14:33:54.994Z" },
+ { url = "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9", size = 215898, upload-time = "2026-07-07T14:33:56.334Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4", size = 236718, upload-time = "2026-07-07T14:33:57.9Z" },
+ { url = "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a", size = 232519, upload-time = "2026-07-07T14:33:59.811Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046", size = 223143, upload-time = "2026-07-07T14:34:01.517Z" },
+ { url = "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81", size = 206742, upload-time = "2026-07-07T14:34:03.04Z" },
+ { url = "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917", size = 219191, upload-time = "2026-07-07T14:34:04.657Z" },
+ { url = "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41", size = 218328, upload-time = "2026-07-07T14:34:06.115Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1", size = 207406, upload-time = "2026-07-07T14:34:07.554Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf", size = 225157, upload-time = "2026-07-07T14:34:09.061Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/f2/c0d4b8508565a36bc5c624e88ed297f5b0b1095011034d7f5b83a69908b5/charset_normalizer-3.4.9-cp314-cp314-win32.whl", hash = "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48", size = 151095, upload-time = "2026-07-07T14:34:10.901Z" },
+ { url = "https://files.pythonhosted.org/packages/49/fd/a1d26144398c67486422a72bf5812cda22cb4ccfcd95a290fb41ceb4b8e2/charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b", size = 162796, upload-time = "2026-07-07T14:34:12.47Z" },
+ { url = "https://files.pythonhosted.org/packages/20/95/d75e82f8ce9fd323ebf059c16c9aadefb22a1ecde13b7840b35835e4886c/charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519", size = 153334, upload-time = "2026-07-07T14:34:14.044Z" },
+ { url = "https://files.pythonhosted.org/packages/00/5e/17398df3a139985ba9d11ed072531986f408c8fca952835ef1ab1820c02b/charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198", size = 338848, upload-time = "2026-07-07T14:34:15.688Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32", size = 223022, upload-time = "2026-07-07T14:34:17.248Z" },
+ { url = "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632", size = 241590, upload-time = "2026-07-07T14:34:18.813Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf", size = 239584, upload-time = "2026-07-07T14:34:20.52Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990", size = 230224, upload-time = "2026-07-07T14:34:22.189Z" },
+ { url = "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d", size = 212667, upload-time = "2026-07-07T14:34:23.857Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e", size = 227179, upload-time = "2026-07-07T14:34:25.586Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c", size = 225372, upload-time = "2026-07-07T14:34:27.212Z" },
+ { url = "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2", size = 215222, upload-time = "2026-07-07T14:34:28.774Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534", size = 231958, upload-time = "2026-07-07T14:34:30.345Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/27/693ee5e8a18191eb38647360c51cd505013e2bd3b366aa43fd5344c21e3c/charset_normalizer-3.4.9-cp314-cp314t-win32.whl", hash = "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226", size = 155580, upload-time = "2026-07-07T14:34:31.884Z" },
+ { url = "https://files.pythonhosted.org/packages/80/3f/bd97d3d9c613013d07cb7733d299385b41df37f0471310f5a73dc359f0b8/charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177", size = 167620, upload-time = "2026-07-07T14:34:33.438Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/c6/eee9dca4439b1061f76373f06ea855678cc4a64c1c3c90b50e479edbb8eb/charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501", size = 158037, upload-time = "2026-07-07T14:34:35.018Z" },
+ { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5", size = 64538, upload-time = "2026-07-07T14:34:56.993Z" },
]
[[package]]
@@ -357,14 +362,14 @@ wheels = [
[[package]]
name = "click"
-version = "8.3.3"
+version = "8.4.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" },
]
[[package]]
@@ -389,55 +394,61 @@ dev = [
[package.metadata.requires-dev]
dev = [
{ name = "nostr-sdk", specifier = ">=0.44" },
- { name = "pyln-client", specifier = ">=25.5" },
- { name = "pyln-proto", specifier = ">=25.5" },
- { name = "pyln-testing", specifier = ">=25.5" },
- { name = "pytest", specifier = ">=7.4,<9" },
+ { name = "pyln-client", specifier = ">=25.9" },
+ { name = "pyln-proto", specifier = ">=25.9" },
+ { name = "pyln-testing", specifier = ">=25.9" },
+ { name = "pytest", specifier = ">=8,<10" },
{ name = "pytest-asyncio", specifier = ">=0.23.8,<2" },
{ name = "pytest-timeout", specifier = ">=2.4,<3" },
{ name = "pytest-xdist", specifier = ">=3.7,<4" },
]
[[package]]
-name = "coincurve"
-version = "20.0.0"
+name = "coincurve-cp314-fix"
+version = "22.0.1"
source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "asn1crypto" },
- { name = "cffi" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/d9/4c/9e5e51e6c12cec6444c86697992f9c6ccffa19f84d042ff939c8b89206ff/coincurve-20.0.0.tar.gz", hash = "sha256:872419e404300302e938849b6b92a196fabdad651060b559dc310e52f8392829", size = 122865, upload-time = "2024-06-02T18:15:50.787Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/bd/f9/e9d3c502369933915d3e72d596a1ddf81b3d5ae986f5bd65bc5ada52e6b9/coincurve_cp314_fix-22.0.1.tar.gz", hash = "sha256:b68397f902a73ba15ab5652fae712f6ba85625e382026be2a5c5e698845a79f4", size = 129346, upload-time = "2026-07-17T14:49:10.202Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/14/0c/f6a8b06f461089aeab441824134ea5d5824dba3acaac0a9dbf8444cbe1d6/coincurve-20.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d559b22828638390118cae9372a1bb6f6594f5584c311deb1de6a83163a0919b", size = 1255634, upload-time = "2024-06-02T18:14:26.381Z" },
- { url = "https://files.pythonhosted.org/packages/62/c2/0dbabd2c6648f49f730fdcbba84c53b5ffaf452fca85c750633141fe049c/coincurve-20.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33d7f6ebd90fcc550f819f7f2cce2af525c342aac07f0ccda46ad8956ad9d99b", size = 1255532, upload-time = "2024-06-02T18:14:28.792Z" },
- { url = "https://files.pythonhosted.org/packages/f5/77/c4fa50f8cb5d050a9bcab806503acdd1705b0dfb5c554eed15cc18bc12e8/coincurve-20.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22d70dd55d13fd427418eb41c20fde0a20a5e5f016e2b1bb94710701e759e7e0", size = 1191928, upload-time = "2024-06-02T18:14:30.874Z" },
- { url = "https://files.pythonhosted.org/packages/a3/11/6254ea354a32a3a1d70722daf58f2ebf0f689f0940eaced5127233416553/coincurve-20.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46f18d481eaae72c169f334cde1fd22011a884e0c9c6adc3fdc1fd13df8236a3", size = 1194364, upload-time = "2024-06-02T18:14:32.684Z" },
- { url = "https://files.pythonhosted.org/packages/a7/a9/d8717d41eb02688691adc30d7348f7c5fdc78e977f4cea83ee84622050b5/coincurve-20.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de1ec57f43c3526bc462be58fb97910dc1fdd5acab6c71eda9f9719a5bd7489", size = 1204658, upload-time = "2024-06-02T18:14:33.919Z" },
- { url = "https://files.pythonhosted.org/packages/55/13/40923832d99c18fb01a00f83e5f6f702156e71cc0eb5d6281535eee662af/coincurve-20.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a6f007c44c726b5c0b3724093c0d4fb8e294f6b6869beb02d7473b21777473a3", size = 1215298, upload-time = "2024-06-02T18:14:35.318Z" },
- { url = "https://files.pythonhosted.org/packages/4d/87/646462a7a7810c7a3dcadae8969e1b78d535bcff072c26b17588e93a39b8/coincurve-20.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0ff1f3b81330db5092c24da2102e4fcba5094f14945b3eb40746456ceabdd6d9", size = 1204504, upload-time = "2024-06-02T18:14:36.567Z" },
- { url = "https://files.pythonhosted.org/packages/01/58/fbb9a312d559aee701491435b691e409fb0efa12eabf269ff651d537fed4/coincurve-20.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82f7de97694d9343f26bd1c8e081b168e5f525894c12445548ce458af227f536", size = 1209298, upload-time = "2024-06-02T18:14:38.384Z" },
- { url = "https://files.pythonhosted.org/packages/ee/d0/1d5679c000b31f3b32512632d98571f2bb752cd25c127d6f5bf3711b6eae/coincurve-20.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:e905b4b084b4f3b61e5a5d58ac2632fd1d07b7b13b4c6d778335a6ca1dafd7a3", size = 1198934, upload-time = "2024-06-02T18:14:39.788Z" },
- { url = "https://files.pythonhosted.org/packages/a3/f6/8c1499f730fac49ec13740fb1c015ce8082fa6b917790056988559f22212/coincurve-20.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:3657bb5ed0baf1cf8cf356e7d44aa90a7902cc3dd4a435c6d4d0bed0553ad4f7", size = 1193319, upload-time = "2024-06-02T18:14:41.165Z" },
- { url = "https://files.pythonhosted.org/packages/24/a7/d60a41b3f0a546854c9b7ca65ab99a5fdf1c9e158ae264a580de8f23fd1c/coincurve-20.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:44087d1126d43925bf9a2391ce5601bf30ce0dba4466c239172dc43226696018", size = 1255635, upload-time = "2024-06-02T18:14:42.483Z" },
- { url = "https://files.pythonhosted.org/packages/b7/4a/727fab66c0fbecfd7beeb38467910bd3652a77df649565e30160a9d2bae2/coincurve-20.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ccf0ba38b0f307a9b3ce28933f6c71dc12ef3a0985712ca09f48591afd597c8", size = 1255536, upload-time = "2024-06-02T18:14:44.077Z" },
- { url = "https://files.pythonhosted.org/packages/0f/8b/25d4ae5bb60665023e6d71681fada88ee95b5010dae6fc0b44d8b23b8df1/coincurve-20.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:566bc5986debdf8572b6be824fd4de03d533c49f3de778e29f69017ae3fe82d8", size = 1191928, upload-time = "2024-06-02T18:14:45.739Z" },
- { url = "https://files.pythonhosted.org/packages/0d/86/8c32c512fa27bfe7cfe70329fd43ebac23c0c8cec202cf6e4f52854e7ce3/coincurve-20.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4d70283168e146f025005c15406086513d5d35e89a60cf4326025930d45013a", size = 1194365, upload-time = "2024-06-02T18:14:47.008Z" },
- { url = "https://files.pythonhosted.org/packages/fe/74/fefbe512f54df7d02a7ea4821b87cf199a91b3565cdf0c94448b3f6b1af1/coincurve-20.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:763c6122dd7d5e7a81c86414ce360dbe9a2d4afa1ca6c853ee03d63820b3d0c5", size = 1204658, upload-time = "2024-06-02T18:14:48.348Z" },
- { url = "https://files.pythonhosted.org/packages/09/68/05b29f881f628ce8e8468f5f7420f6c4d7c129f43964e81d15bf388ae67a/coincurve-20.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f00c361c356bcea386d47a191bb8ac60429f4b51c188966a201bfecaf306ff7f", size = 1215301, upload-time = "2024-06-02T18:14:49.84Z" },
- { url = "https://files.pythonhosted.org/packages/ee/5d/d91549cf5a163797b0724dc2dcd551b908b6beddb6598b37743df7f6f3ec/coincurve-20.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4af57bdadd2e64d117dd0b33cfefe76e90c7a6c496a7b034fc65fd01ec249b15", size = 1204505, upload-time = "2024-06-02T18:14:51.816Z" },
- { url = "https://files.pythonhosted.org/packages/37/0f/898022e08760fb57d281f3695576e859b0f8a8ac629670223d9066c3f60d/coincurve-20.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a26437b7cbde13fb6e09261610b788ca2a0ca2195c62030afd1e1e0d1a62e035", size = 1209305, upload-time = "2024-06-02T18:14:53.39Z" },
- { url = "https://files.pythonhosted.org/packages/57/b9/643567d3f680ddf8d1bf10a56112ae7755296500d8eaaef498be637a8533/coincurve-20.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ed51f8bba35e6c7676ad65539c3dbc35acf014fc402101fa24f6b0a15a74ab9e", size = 1198932, upload-time = "2024-06-02T18:14:54.751Z" },
- { url = "https://files.pythonhosted.org/packages/b3/3a/898f5c12469b292042608dd0702bcb0420ec32bac6b1ca2a0dd790f922bd/coincurve-20.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:594b840fc25d74118407edbbbc754b815f1bba9759dbf4f67f1c2b78396df2d3", size = 1193318, upload-time = "2024-06-02T18:14:55.981Z" },
- { url = "https://files.pythonhosted.org/packages/8f/24/e1bf259dd57186fbdc7cec51909db320884162cfad5ec72cbaa63573ff9d/coincurve-20.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4df4416a6c0370d777aa725a25b14b04e45aa228da1251c258ff91444643f688", size = 1255671, upload-time = "2024-06-02T18:14:57.863Z" },
- { url = "https://files.pythonhosted.org/packages/0a/c5/1817f87d1cd5ff50d8537fe60fb96f66b76dd02da885d970952e6189a801/coincurve-20.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1ccc3e4db55abf3fc0e604a187fdb05f0702bc5952e503d9a75f4ae6eeb4cb3a", size = 1255565, upload-time = "2024-06-02T18:14:59.128Z" },
- { url = "https://files.pythonhosted.org/packages/90/9f/35e15f993717ed1dcc4c26d9771f073a1054af26808a0f421783bb4cd7e0/coincurve-20.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8335b1658a2ef5b3eb66d52647742fe8c6f413ad5b9d5310d7ea6d8060d40f", size = 1191953, upload-time = "2024-06-02T18:15:01.047Z" },
- { url = "https://files.pythonhosted.org/packages/4a/3d/6a9bc32e69b738b5e05f5027bace1da6722352a4a447e495d3c03a601d99/coincurve-20.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ac025e485a0229fd5394e0bf6b4a75f8a4f6cee0dcf6f0b01a2ef05c5210ff", size = 1194425, upload-time = "2024-06-02T18:15:02.919Z" },
- { url = "https://files.pythonhosted.org/packages/1a/a6/15424973dc47fc7c87e3c0f8859f6f1b1032582ee9f1b85fdd5d1e33d630/coincurve-20.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e46e3f1c21b3330857bcb1a3a5b942f645c8bce912a8a2b252216f34acfe4195", size = 1204678, upload-time = "2024-06-02T18:15:04.308Z" },
- { url = "https://files.pythonhosted.org/packages/6a/e7/71ddb4d66c11c4ad13e729362f8852e048ae452eba3dfcf57751842bb292/coincurve-20.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:df9ff9b17a1d27271bf476cf3fa92df4c151663b11a55d8cea838b8f88d83624", size = 1215395, upload-time = "2024-06-02T18:15:05.701Z" },
- { url = "https://files.pythonhosted.org/packages/b9/7d/03e0a19cfff1d86f5d019afc69cfbff02caada701ed5a4a50abc63d4261c/coincurve-20.0.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4155759f071375699282e03b3d95fb473ee05c022641c077533e0d906311e57a", size = 1204552, upload-time = "2024-06-02T18:15:07.107Z" },
- { url = "https://files.pythonhosted.org/packages/07/cd/e9bd4ca7d931653a35c74194da04191a9aecc54b8f48a554cd538dc810e4/coincurve-20.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0530b9dd02fc6f6c2916716974b79bdab874227f560c422801ade290e3fc5013", size = 1209392, upload-time = "2024-06-02T18:15:08.663Z" },
- { url = "https://files.pythonhosted.org/packages/99/54/260053f14f74b99b645084231e1c76994134ded49407a3bba23a8ffc0ff6/coincurve-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:eacf9c0ce8739c84549a89c083b1f3526c8780b84517ee75d6b43d276e55f8a0", size = 1198932, upload-time = "2024-06-02T18:15:10.786Z" },
- { url = "https://files.pythonhosted.org/packages/b4/b5/c465e09345dd38b9415f5d47ae7683b3f461db02fcc03e699b6b5687ab2b/coincurve-20.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:52a67bfddbd6224dfa42085c88ad176559801b57d6a8bd30d92ee040de88b7b3", size = 1193324, upload-time = "2024-06-02T18:15:12.511Z" },
+ { url = "https://files.pythonhosted.org/packages/af/ca/ec5e2c4ba1df02844e1087e58636ecc78a096fa7e7dfd85cab286c0c1c31/coincurve_cp314_fix-22.0.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:9fec35946bfe7784e92aaa656b298b3b67f0a093f52c7970496dde4621bbe6c0", size = 1388687, upload-time = "2026-07-17T14:48:04.925Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/01/5c0435325516a6d7ce2958e90e4d050652d105465a187ff8e983a1271370/coincurve_cp314_fix-22.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f5f4abc2e639a4007ca212b7029ea9fc549dc1e1207348f1c8729e34b6e0a94c", size = 1383962, upload-time = "2026-07-17T14:48:06.636Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/93/d9ea4c7955a1f67740e492adca7d8ffdb7b9434c2ddc9628e578d37552bb/coincurve_cp314_fix-22.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2dc1deb3cec48571fa05064fa8dad3488a0d63e3f16fa731c7815f3f204a2cb", size = 1371893, upload-time = "2026-07-17T14:48:08.247Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/0c/eec3262ad43b0f40203656d1a1e52377d603a47f76de6352dd15659285bc/coincurve_cp314_fix-22.0.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b60d06533f4820023a4e91679c2181ccc29a23193d55fc51e6d55874186b67", size = 1370994, upload-time = "2026-07-17T14:48:09.9Z" },
+ { url = "https://files.pythonhosted.org/packages/36/9c/733843a2423ec759ccdd78338dba53f9bb9093f011ea8b31feab07e510cc/coincurve_cp314_fix-22.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:01428e65cfac5bedbeb7a6c1e146970d8aa8a384a7dc39f0c45c38350c6960cc", size = 1377492, upload-time = "2026-07-17T14:48:11.756Z" },
+ { url = "https://files.pythonhosted.org/packages/33/e1/6c8bca371a395b32ddd86b2bcbae146789984b0bdf329524f6e85a73846e/coincurve_cp314_fix-22.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b787b23c80501e1af903bfe4f89a07c51ccc02e2333913e152f4e4c2cdbf644f", size = 1374123, upload-time = "2026-07-17T14:48:13.33Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/52/e9a7a1c82d615e9f4060ac77509bae9d95e1c9a4ad24941abca9f356d091/coincurve_cp314_fix-22.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:6b02bca3564e795a945c0a2a7f575d3af7d6e3c0e84133c610ca84cf0b824d21", size = 1329759, upload-time = "2026-07-17T14:48:14.845Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/55/c858d0ce0a2a3ec590463838af052492680debae92ca38b071ee459f351c/coincurve_cp314_fix-22.0.1-cp310-cp310-win_arm64.whl", hash = "sha256:c2a0afd16f410f0b9932cc2123ba1adceca8676cffd649c4a5c1fe344d3a55df", size = 1320063, upload-time = "2026-07-17T14:48:16.294Z" },
+ { url = "https://files.pythonhosted.org/packages/74/d9/6e191269f241861ed25ce193bb1d24e8758eb83276a0bc28d7f929704d45/coincurve_cp314_fix-22.0.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c7beead9480fc1e47b3727172af2279f1043bacc68f1a7226af7687bd893058e", size = 1388699, upload-time = "2026-07-17T14:48:18.13Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/1e/a330eba734c262182bd7d35595c1e4b72a32cced388b649ab826b8b93d47/coincurve_cp314_fix-22.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3a710296ef735bb96434a152101bcdef9bdabbec291305eb0e6cc864935e7db", size = 1383919, upload-time = "2026-07-17T14:48:19.759Z" },
+ { url = "https://files.pythonhosted.org/packages/52/ef/fa17567e5044fdbe958534191b31e461affc2019df6e21f6644981bc2cb1/coincurve_cp314_fix-22.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8bb83a3ea92906d5fe1623c3554c4973c0b51cb7f3a5e10dae549eec9b1b1eb", size = 1371952, upload-time = "2026-07-17T14:48:21.412Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/d1/b6cbf61dcbb11b053891d593d82fb976e5cc44092fef09d0787c8edb7071/coincurve_cp314_fix-22.0.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9d88f8faf7156fddad08dbd032671d6bb2427a262fc57e81be5fc4f9d1357aa", size = 1370118, upload-time = "2026-07-17T14:48:23.358Z" },
+ { url = "https://files.pythonhosted.org/packages/99/f5/8d629287c7c2e7b9efca2cab3cfa95a02c2312881551b39875cb81671edc/coincurve_cp314_fix-22.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8a41bd1c4012d8ff480a3972cc9300400530edb8e7f0d16617e0f241fe0b72d2", size = 1377513, upload-time = "2026-07-17T14:48:24.923Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/ca/8aac5adcd9616dd73095a2c4a707b30bc31674fae8522de44992309d34df/coincurve_cp314_fix-22.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b9083d1e5042866a1e28e91e9d5c8fdcf51629dd2a273f6b405059e7c95945fb", size = 1373226, upload-time = "2026-07-17T14:48:26.512Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/98/1b4f2f26d6980bdd17a8f2864832f9dff895b032a49234b51389ab58596d/coincurve_cp314_fix-22.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:918b4ad4d1e4f4cf38c11aa39b9d842418987f898caccc6114b45aa081ae2c90", size = 1329815, upload-time = "2026-07-17T14:48:27.899Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/e1/21f17125e8b9160dd5f6db3f92da6e18b1f4cdececfc3a154f023a7f9ad7/coincurve_cp314_fix-22.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:ab926906a2718de26a3e23955103e41e39cb316e5cbb68489405d4a2bc2011c3", size = 1320212, upload-time = "2026-07-17T14:48:29.473Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/32/24fef91a512c51b57b5980207bdf4974ab6e998aefde3c50abb565b4f346/coincurve_cp314_fix-22.0.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:b077081c058338aaab7fe634275da0248fe59b469be9ec2bfa598e6e328fc5d1", size = 1389725, upload-time = "2026-07-17T14:48:31.19Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/7a/24b3079bee4bd2f081865e28a08eb13b909470c7d8ce3a8c4ac9aae80727/coincurve_cp314_fix-22.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0ed7e6c3434333ecc17b00834f17effa5f48fc89b3e130d19157e3b18e0bd149", size = 1384501, upload-time = "2026-07-17T14:48:32.942Z" },
+ { url = "https://files.pythonhosted.org/packages/41/26/7a4fbaff523784b9339f247a315056f99439fe671705d92bd9df01612e59/coincurve_cp314_fix-22.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b72535b8303d45bfc47bb27e7b1b898cfba11ddb9ca6db9e528f0e23360da5f3", size = 1375639, upload-time = "2026-07-17T14:48:34.777Z" },
+ { url = "https://files.pythonhosted.org/packages/82/2e/c6f93f5bbbe6c050f5425b9e1ebb1fc8a28e3074b4ebe6542c91be186e27/coincurve_cp314_fix-22.0.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a56ec57a1ce4116db6281703c5c64d35a9fbcb4ed2ab65ac38109c412afb3b6", size = 1374117, upload-time = "2026-07-17T14:48:37.179Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/f0/911d0295ed3a199c7a4eb43d2f8ffff1d1dcca39f2128fe5fc7f1fe52c17/coincurve_cp314_fix-22.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0501e49a206b5ab4105f65daeb338dcf3559bd7d5392a03afc3f31db83f661fc", size = 1381644, upload-time = "2026-07-17T14:48:39.018Z" },
+ { url = "https://files.pythonhosted.org/packages/be/68/b3ecefd5edccd3202f24c0cfb696aff0756e6095db9f7c67da78aff57f27/coincurve_cp314_fix-22.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7a5d93127fea898e53882ac106535fbc39ff4f2a26e9c5f23e1efae716bcf6a6", size = 1377529, upload-time = "2026-07-17T14:48:40.608Z" },
+ { url = "https://files.pythonhosted.org/packages/57/54/be427f7e8b037b14b94eb97e22fab08b8d41535075dd1b1d7a668fc1d4dc/coincurve_cp314_fix-22.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:07fcc0a4b6c86566462c9918f6c68303e3699820c4df595daef9a8d131584f29", size = 1330618, upload-time = "2026-07-17T14:48:42.12Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/0b/1833d9b75a8d0dabba52db6a4e665cd0bf24401c513a062f82c8fc4f56a2/coincurve_cp314_fix-22.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:f7b282d27d234b96e064e6bf061d56a4148a4e4fb14f0309fdcc555206892ab6", size = 1320184, upload-time = "2026-07-17T14:48:43.588Z" },
+ { url = "https://files.pythonhosted.org/packages/93/9f/2d2576282a16fcddd4bacaae9767852203bc6fe6a851a2410b0dffb0bc87/coincurve_cp314_fix-22.0.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:227158f4cbd329f0b75780198ab312ac72d697b2ec28daade45d0c3d8aa7ae3a", size = 1389695, upload-time = "2026-07-17T14:48:45.298Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/6a/fc8e76c2f6d62af177960a719b5987e644412b13fd673175dea4f2696370/coincurve_cp314_fix-22.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6cde6eda5348115cd46555aae8e5fc8a1329cdd34560293a371a3e8394390c16", size = 1384517, upload-time = "2026-07-17T14:48:46.86Z" },
+ { url = "https://files.pythonhosted.org/packages/63/f1/f3a62079cb2d4205712545d70e7bd221b276b0b379329d844ed825076014/coincurve_cp314_fix-22.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:155c9364dcea3b4028fc03d02b5ac4c1d791c7989c54ea8d73ff52600fa9bab1", size = 1375601, upload-time = "2026-07-17T14:48:48.388Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/1c/d4769d938a000d14ce99f08c42148e8fda85b5b243943e804a5f27e4d951/coincurve_cp314_fix-22.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ccf73b280220759fa02251f09300d85af54ff23631da3e95c14eef30cba7408", size = 1374082, upload-time = "2026-07-17T14:48:49.852Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/88/246bad1924267d0064a7a6092d10851f66765caefe9a0010be8c25c94a6c/coincurve_cp314_fix-22.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5eb5a6aa08e8e07d2edb3a6b8e6602f0dc94a1b0fbf4d83138df749b921fe8b2", size = 1381599, upload-time = "2026-07-17T14:48:51.33Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/e0/08dbec75aced7f23dba7dc52f1294f30e862de33cc9112bd01ccf3b3f50d/coincurve_cp314_fix-22.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0bde261973270d2313bf82d526a6a395d084faa74f514d98c2dfe96bcb3d331f", size = 1377435, upload-time = "2026-07-17T14:48:53.016Z" },
+ { url = "https://files.pythonhosted.org/packages/28/ac/ff86fc78fa9dcf4792f57e0675030dd21701e0f121c165801a2434598e20/coincurve_cp314_fix-22.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:07ab4f37249dab54d3dc02e35dd82f0309c9995a1656f91ab1c8efebf7c35ed4", size = 1330553, upload-time = "2026-07-17T14:48:54.539Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/17/5f27565dd86fff04636b5a4a7a5450f6f35474b3c02ad6832852ce98e134/coincurve_cp314_fix-22.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:8d0d6057895da2d4fb7da49463c08ccbc3399a57df5b1ae18b296edcfe724cae", size = 1320215, upload-time = "2026-07-17T14:48:56.047Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/60/721383a5cc7079360afa5a235c8bbddbdf09505f39cc315d5eafba90f638/coincurve_cp314_fix-22.0.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6b18156408e60b12b87810ae323ef0b483251c33f05f172e344c325a034014e5", size = 1389892, upload-time = "2026-07-17T14:48:57.533Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/f2/9f8518e3b138256d80d40ccdb3cb8edb78dd01846ff221da3d212f6c44b9/coincurve_cp314_fix-22.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:15c9257f42a42c14e098e0f37b8b5fc32371854c84f3bebe2448a307ca674b3e", size = 1384743, upload-time = "2026-07-17T14:48:58.999Z" },
+ { url = "https://files.pythonhosted.org/packages/44/40/913a7a3f02678bc1990e508fba9fa156d643a788cceb611d8c35b99a4436/coincurve_cp314_fix-22.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c04475afd71244fb6e04af2d8f2e2ad98264f6b6f549826560ea96925425f33", size = 1375586, upload-time = "2026-07-17T14:49:00.759Z" },
+ { url = "https://files.pythonhosted.org/packages/46/6d/21c2888ac918199cedd9b438a2bb5cd9e1746bff4cccbdf27f35c646b94d/coincurve_cp314_fix-22.0.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2e1066e72ac20310fb2359f0c7bdcc7d09f796eb3d316b3e03b3c5e59fab349", size = 1373843, upload-time = "2026-07-17T14:49:02.524Z" },
+ { url = "https://files.pythonhosted.org/packages/61/64/d1ae34a2843dc76e69f65ef6c611fd3f09bc6a11924a56c555b6aea9339e/coincurve_cp314_fix-22.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0a629e282b8a9d531b882ee1735a6ce1cfc0c8c37531583131ade5c4ca5d08b1", size = 1381502, upload-time = "2026-07-17T14:49:03.993Z" },
+ { url = "https://files.pythonhosted.org/packages/06/ad/1c0b90430feefd17594fda215880137a40bb7858dde62bb60c4b58cf0771/coincurve_cp314_fix-22.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f7697cc7d75de9b9e34e041cfe7dd903db2141a4c31c92ec420674f937c3af8", size = 1377090, upload-time = "2026-07-17T14:49:05.59Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/20/1267eb8492b9d2d7a904739476eebc7d4d3921d13e716621ca99128e25cb/coincurve_cp314_fix-22.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:56ddf3b2340c23c22fe16fbf171e18219de291cf2c26f75805c92640ec5ef8c8", size = 1334976, upload-time = "2026-07-17T14:49:07.092Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/e7/9765c390984195f79c6b0d3ab299cc17749f57a9856651db30065cc66264/coincurve_cp314_fix-22.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:acfcd79081fc04e4f699731973c41165dfeee85b855dc352ee2d46250dd46f6e", size = 1327417, upload-time = "2026-07-17T14:49:08.695Z" },
]
[[package]]
@@ -451,62 +462,59 @@ wheels = [
[[package]]
name = "cryptography"
-version = "48.0.0"
+version = "49.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/9f/a9/db8f313fdcd85d767d4973515e1db101f9c71f95fced83233de224673757/cryptography-48.0.0.tar.gz", hash = "sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920", size = 832984, upload-time = "2026-05-04T22:59:38.133Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/df/3d/01f6dd9190170a5a241e0e98c2d04be3664a9e6f5b9b872cde63aff1c3dd/cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6", size = 8001587, upload-time = "2026-05-04T22:57:36.803Z" },
- { url = "https://files.pythonhosted.org/packages/b2/6e/e90527eef33f309beb811cf7c982c3aeffcce8e3edb178baa4ca3ae4a6fa/cryptography-48.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c", size = 4690433, upload-time = "2026-05-04T22:57:40.373Z" },
- { url = "https://files.pythonhosted.org/packages/90/04/673510ed51ddff56575f306cf1617d80411ee76831ccd3097599140efdfe/cryptography-48.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3", size = 4710620, upload-time = "2026-05-04T22:57:42.935Z" },
- { url = "https://files.pythonhosted.org/packages/14/d5/e9c4ef932c8d800490c34d8bd589d64a31d5890e27ec9e9ad532be893294/cryptography-48.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5", size = 4696283, upload-time = "2026-05-04T22:57:45.294Z" },
- { url = "https://files.pythonhosted.org/packages/0c/29/174b9dfb60b12d59ecfc6cfa04bc88c21b42a54f01b8aae09bb6e51e4c7f/cryptography-48.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c", size = 5296573, upload-time = "2026-05-04T22:57:47.933Z" },
- { url = "https://files.pythonhosted.org/packages/95/38/0d29a6fd7d0d1373f0c0c88a04ba20e359b257753ac497564cd660fc1d55/cryptography-48.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f", size = 4743677, upload-time = "2026-05-04T22:57:50.067Z" },
- { url = "https://files.pythonhosted.org/packages/30/be/eef653013d5c63b6a490529e0316f9ac14a37602965d4903efed1399f32b/cryptography-48.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25", size = 4330808, upload-time = "2026-05-04T22:57:52.301Z" },
- { url = "https://files.pythonhosted.org/packages/84/9e/500463e87abb7a0a0f9f256ec21123ecde0a7b5541a15e840ea54551fd81/cryptography-48.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602", size = 4695941, upload-time = "2026-05-04T22:57:54.603Z" },
- { url = "https://files.pythonhosted.org/packages/e3/dc/7303087450c2ec9e7fbb750e17c2abfbc658f23cbd0e54009509b7cc4091/cryptography-48.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c", size = 5252579, upload-time = "2026-05-04T22:57:57.207Z" },
- { url = "https://files.pythonhosted.org/packages/d0/c0/7101d3b7215edcdc90c45da544961fd8ed2d6448f77577460fa75a8443f7/cryptography-48.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5", size = 4743326, upload-time = "2026-05-04T22:57:59.535Z" },
- { url = "https://files.pythonhosted.org/packages/ac/d8/5b833bad13016f562ab9d063d68199a4bd121d18458e439515601d3357ec/cryptography-48.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321", size = 4826672, upload-time = "2026-05-04T22:58:01.996Z" },
- { url = "https://files.pythonhosted.org/packages/98/e1/7074eb8bf3c135558c73fc2bcf0f5633f912e6fb87e868a55c454080ef09/cryptography-48.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74", size = 4972574, upload-time = "2026-05-04T22:58:03.968Z" },
- { url = "https://files.pythonhosted.org/packages/04/70/e5a1b41d325f797f39427aa44ef8baf0be500065ab6d8e10369d850d4a4f/cryptography-48.0.0-cp311-abi3-win32.whl", hash = "sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4", size = 3294868, upload-time = "2026-05-04T22:58:06.467Z" },
- { url = "https://files.pythonhosted.org/packages/f4/ac/8ac51b4a5fc5932eb7ee5c517ba7dc8cd834f0048962b6b352f00f41ebf9/cryptography-48.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7", size = 3817107, upload-time = "2026-05-04T22:58:08.845Z" },
- { url = "https://files.pythonhosted.org/packages/6b/84/70e3feea9feea87fd7cbe77efb2712ae1e3e6edf10749dc6e95f4e60e455/cryptography-48.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec", size = 7986556, upload-time = "2026-05-04T22:58:11.172Z" },
- { url = "https://files.pythonhosted.org/packages/89/6e/18e07a618bb5442ba10cf4df16e99c071365528aa570dfcb8c02e25a303b/cryptography-48.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18", size = 4684776, upload-time = "2026-05-04T22:58:13.712Z" },
- { url = "https://files.pythonhosted.org/packages/be/6a/4ea3b4c6c6759794d5ee2103c304a5076dc4b19ae1f9fe47dba439e159e9/cryptography-48.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20", size = 4698121, upload-time = "2026-05-04T22:58:16.448Z" },
- { url = "https://files.pythonhosted.org/packages/2f/59/6ff6ad6cae03bb887da2a5860b2c9805f8dac969ef01ce563336c49bd1d1/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff", size = 4690042, upload-time = "2026-05-04T22:58:18.544Z" },
- { url = "https://files.pythonhosted.org/packages/ca/b4/fc334ed8cfd705aca282fe4d8f5ae64a8e0f74932e9feecb344610cf6e4d/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c", size = 5282526, upload-time = "2026-05-04T22:58:20.75Z" },
- { url = "https://files.pythonhosted.org/packages/11/08/9f8c5386cc4cd90d8255c7cdd0f5baf459a08502a09de30dc51f553d38dc/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db", size = 4733116, upload-time = "2026-05-04T22:58:23.627Z" },
- { url = "https://files.pythonhosted.org/packages/b8/77/99307d7574045699f8805aa500fa0fb83422d115b5400a064ddd306d7750/cryptography-48.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741", size = 4316030, upload-time = "2026-05-04T22:58:25.581Z" },
- { url = "https://files.pythonhosted.org/packages/fd/36/a608b98337af3cb2aff4818e406649d30572b7031918b04c87d979495348/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166", size = 4689640, upload-time = "2026-05-04T22:58:27.747Z" },
- { url = "https://files.pythonhosted.org/packages/dd/a6/825010a291b4438aecc1f568bc428189fc1175515223632477c07dc0a6df/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336", size = 5237657, upload-time = "2026-05-04T22:58:29.848Z" },
- { url = "https://files.pythonhosted.org/packages/b9/09/4e76a09b4caa29aad535ddc806f5d4c5d01885bd978bd984fbc6ca032cae/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057", size = 4732362, upload-time = "2026-05-04T22:58:32.009Z" },
- { url = "https://files.pythonhosted.org/packages/18/78/444fa04a77d0cb95f417dda20d450e13c56ba8e5220fc892a1658f44f882/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae", size = 4819580, upload-time = "2026-05-04T22:58:34.254Z" },
- { url = "https://files.pythonhosted.org/packages/38/85/ea67067c70a1fd4be2c63d35eeed82658023021affccc7b17705f8527dd2/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c", size = 4963283, upload-time = "2026-05-04T22:58:36.376Z" },
- { url = "https://files.pythonhosted.org/packages/75/54/cc6d0f3deac3e81c7f847e8a189a12b6cdd65059b43dad25d4316abd849a/cryptography-48.0.0-cp314-cp314t-win32.whl", hash = "sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f", size = 3270954, upload-time = "2026-05-04T22:58:38.791Z" },
- { url = "https://files.pythonhosted.org/packages/49/67/cc947e288c0758a4e5473d1dcb743037ab7785541265a969240b8885441a/cryptography-48.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12", size = 3797313, upload-time = "2026-05-04T22:58:40.746Z" },
- { url = "https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86", size = 7983482, upload-time = "2026-05-04T22:58:43.769Z" },
- { url = "https://files.pythonhosted.org/packages/d5/ac/f5b5995b87770c693e2596559ffafe195b4033a57f14a82268a2842953f3/cryptography-48.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e", size = 4683266, upload-time = "2026-05-04T22:58:46.064Z" },
- { url = "https://files.pythonhosted.org/packages/ec/c6/8b14f67e18338fbc4adb76f66c001f5c3610b3e2d1837f268f47a347dbbb/cryptography-48.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f", size = 4696228, upload-time = "2026-05-04T22:58:48.22Z" },
- { url = "https://files.pythonhosted.org/packages/ea/73/f808fbae9514bd91b47875b003f13e284c8c6bdfd904b7944e803937eec1/cryptography-48.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7", size = 4689097, upload-time = "2026-05-04T22:58:50.9Z" },
- { url = "https://files.pythonhosted.org/packages/93/01/d86632d7d28db8ae83221995752eeb6639ffb374c2d22955648cf8d52797/cryptography-48.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832", size = 5283582, upload-time = "2026-05-04T22:58:53.017Z" },
- { url = "https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c", size = 4730479, upload-time = "2026-05-04T22:58:55.611Z" },
- { url = "https://files.pythonhosted.org/packages/6f/af/99a582b1b1641ff5911ac559beb45097cf79efd4ead4657f578ef1af2d47/cryptography-48.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a", size = 4326481, upload-time = "2026-05-04T22:58:57.607Z" },
- { url = "https://files.pythonhosted.org/packages/90/ee/89aa26a06ef0a7d7611788ffd571a7c50e368cc6a4d5eef8b4884e866edb/cryptography-48.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a", size = 4688713, upload-time = "2026-05-04T22:59:00.077Z" },
- { url = "https://files.pythonhosted.org/packages/70/ba/bcb1b0bb7a33d4c7c0c4d4c7874b4a62ae4f56113a5f4baefa362dfb1f0f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a", size = 5238165, upload-time = "2026-05-04T22:59:02.317Z" },
- { url = "https://files.pythonhosted.org/packages/c9/70/ca4003b1ce5ca3dc3186ada51908c8a9b9ff7d5cab83cc0d43ee14ec144f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239", size = 4729947, upload-time = "2026-05-04T22:59:05.255Z" },
- { url = "https://files.pythonhosted.org/packages/44/a0/4ec7cf774207905aef1a8d11c3750d5a1db805eb380ee4e16df317870128/cryptography-48.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c", size = 4822059, upload-time = "2026-05-04T22:59:07.802Z" },
- { url = "https://files.pythonhosted.org/packages/1e/75/a2e55f99c16fcac7b5d6c1eb19ad8e00799854d6be5ca845f9259eae1681/cryptography-48.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4", size = 4960575, upload-time = "2026-05-04T22:59:09.851Z" },
- { url = "https://files.pythonhosted.org/packages/b8/23/6e6f32143ab5d8b36ca848a502c4bcd477ae75b9e1677e3530d669062578/cryptography-48.0.0-cp39-abi3-win32.whl", hash = "sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd", size = 3279117, upload-time = "2026-05-04T22:59:12.019Z" },
- { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" },
- { url = "https://files.pythonhosted.org/packages/be/d2/024b5e06be9d44cb021fb0e1a03d34d63989cf56a0fe62f3dfbab695b9b4/cryptography-48.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855", size = 3950391, upload-time = "2026-05-04T22:59:17.415Z" },
- { url = "https://files.pythonhosted.org/packages/bc/17/3861e17c56fa0fd37491a14a8673fdb77c57fc5693cafe745ea8b06dba75/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b", size = 4637126, upload-time = "2026-05-04T22:59:20.197Z" },
- { url = "https://files.pythonhosted.org/packages/f0/0a/7e226dbff530f21480727eb764973a7bff2b912f8e15cd4f129e71b56d1d/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13", size = 4667270, upload-time = "2026-05-04T22:59:22.647Z" },
- { url = "https://files.pythonhosted.org/packages/3b/f2/5a72274ca9f1b2a8b44a662ee0bf1b435909deb473d6f97bcd035bcdbc71/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb", size = 4636797, upload-time = "2026-05-04T22:59:24.912Z" },
- { url = "https://files.pythonhosted.org/packages/b4/e1/48cedb2fe63626e91ded1edad159e2a4fb8b6906c4425eb7749673077ce7/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355", size = 4666800, upload-time = "2026-05-04T22:59:27.474Z" },
- { url = "https://files.pythonhosted.org/packages/a2/ca/7e8365deec19afb2b2c7be7c1c0aa8f99633b54e90c570999acda93260fc/cryptography-48.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a", size = 3739536, upload-time = "2026-05-04T22:59:29.61Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" },
+ { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" },
+ { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" },
+ { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" },
+ { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" },
+ { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/9e/db72b3ae7fc9cfad53e630e56c6ae83b9b6ff0bf3718ffb8012d20b3aabf/cryptography-49.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:73a205dce83953d131a4aa1e0fd917a2fd1c5b1eef251e9d7152efefcbf5caf7", size = 4013892, upload-time = "2026-06-12T20:02:10.735Z" },
+ { url = "https://files.pythonhosted.org/packages/86/12/c48a424f38db03027be9f7ed5c7dc5de9933dbee992865f98b13727a009d/cryptography-49.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:196ecd6a36e4e9aa10270393bb98d8df88fccee0bf1e5128b91ae4eb4375896d", size = 4678835, upload-time = "2026-06-12T20:02:48.743Z" },
+ { url = "https://files.pythonhosted.org/packages/68/28/8a3ad4653662c93fc44dc4e5d8fd374c25c42e07b34bbfbadf49cf57a5a8/cryptography-49.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7abcee80084cda3f7691f3eb1ce480d8df49cec637b429aa35986c1de71738aa", size = 4697239, upload-time = "2026-06-12T20:02:56.03Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/b2/2193fc74f81aee4f9b62733133b73b5176718932ed8f2e4b03fa040480a6/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:4ae387c9cb68ea569ca17e490d66d8142b81c3cc814bf179974b7d146e490bbb", size = 4685593, upload-time = "2026-06-12T20:02:50.666Z" },
+ { url = "https://files.pythonhosted.org/packages/47/f1/1d3eaa243bfc5de4a187b22aa8c048b3e4980bfbe830ac46e6bac2e66947/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:f37d847238971164fdbc68ade6f6574aecc9c0af714190e2083429ff68f4ce9d", size = 5289961, upload-time = "2026-06-12T20:01:46.468Z" },
+ { url = "https://files.pythonhosted.org/packages/58/39/2d51306721330c486495853eda1c567880ff036de15a14c4b74f399934af/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c2bc30226390d60ea19d9f82b19db005fe0452154a23c1c410c12ea801e43561", size = 4731145, upload-time = "2026-06-12T20:02:16.832Z" },
+ { url = "https://files.pythonhosted.org/packages/17/50/983e838c7fd0d87fd8c969bcdd328edaf5f756e38df5281637424c155873/cryptography-49.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:07cab27cc7b7e0fd28e5e26bb9eeedde5c135c868b46de4a27845abe94af6122", size = 4321719, upload-time = "2026-06-12T20:02:52.611Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/f5/8f571d7e27c55bce9f76f026143bcb1e040a4233149ecca0bea5fa5dd5f7/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:b20133d204d2bb56ba047642199603876c872026ca53e79c35b83772ab2cc505", size = 4685209, upload-time = "2026-06-12T20:02:07.282Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/84/0e27016a6fc5a0886f797018b26aa42f40c09a82332bff77822a451deaaa/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b970c6da94d5bb18629db453d14f2a1300f6bf59b61e9b82377931ef95504866", size = 5246285, upload-time = "2026-06-12T20:01:32.439Z" },
+ { url = "https://files.pythonhosted.org/packages/11/2d/5e1fb307cb5931881516b464c98774b3f2c36b5d4bb9a2830253cf553cad/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d8ecde755e2e91bf773fc94e8c9d730cd7f2007004cb492263a794ec3899a1c8", size = 4730441, upload-time = "2026-06-12T20:02:01.469Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/c0/bff5a02ee731d207d6a1ed51732549d8c53d2bc8da1d10ec6f2844201d68/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e3fb64c420688e5319ae25113a354015abbd8dffbfbc41781a1ea66fc7622ac3", size = 4815869, upload-time = "2026-06-12T20:01:36.574Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/26/814681d14248d95d73d5c3eea0c39a94eb8302df966f670a2c60de90974b/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32703d93296f5c1f4b53349ad3a250c2cae0fdecd3a3dd5d47e616d8d616af27", size = 4960948, upload-time = "2026-06-12T20:02:18.688Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/fe/93ecac273d3738939d023612ad12cca9a3740a5345d69fda04134c43fd96/cryptography-49.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:33cd0565932807baddb67b96dbee92f2c374b5c89dee09fd74079aeb8c8dba61", size = 3799153, upload-time = "2026-06-12T20:01:39.059Z" },
+ { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" },
+ { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" },
+ { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" },
+ { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" },
+ { url = "https://files.pythonhosted.org/packages/63/d3/4a83af35d65e3fad632c926fad684c193ea4398569ccb0bbbc7fe8f5dc9a/cryptography-49.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fc1e275c2f1d97b1a6450b8b0ea3ebfa6e087a611c2b26cb2404d48588abab7b", size = 3993685, upload-time = "2026-06-12T20:02:14.883Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/a7/f9dac0ab7f80368c56993a7bf638ef9935f825c91902798481fac0898138/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83782480a4a9da4d0feb51950131ba32e12e70813848b3343f6e18c28a66838", size = 4676239, upload-time = "2026-06-12T20:02:28.793Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/70/2ba3769dd0ae167e2f33dfa9592d45db6ff9a61d62ca1a5b3d1bdd09068f/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b39efa323140595abd3ecca8529d321ae50f55f3aa3ba9cc81ea56a6011953d5", size = 4715584, upload-time = "2026-06-12T20:01:27.495Z" },
+ { url = "https://files.pythonhosted.org/packages/94/64/2923570ac1c0bd3a737aa366ac3abbbbde273042308b8cde95e2364a6e6a/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b47db11c2c3525083296069b98ac5221907455e989ae0c2e3008bde851921615", size = 4675885, upload-time = "2026-06-12T20:01:55.49Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/f8/614dc7e051418cfe53d55173c1e24c6b0085e89996fe90508c2fdf769aef/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:084ef1af862eb07ec46d25f68689f2102a9fc0e05ce7b80f14f5fe51e4eef0f6", size = 4715449, upload-time = "2026-06-12T20:02:05.469Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/50/a9caea39ad19c431c1a3f8a31114df65b260cdfe67786b6c7e7c040c4c44/cryptography-49.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be9fcb48a55f023493482827d4f459bd263cc20efde64f204b97c123201850c6", size = 3783731, upload-time = "2026-06-12T20:02:43.319Z" },
]
[[package]]
@@ -523,7 +531,7 @@ name = "exceptiongroup"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+ { name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
wheels = [
@@ -558,11 +566,11 @@ wheels = [
[[package]]
name = "idna"
-version = "3.14"
+version = "3.18"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/05/b1/efac073e0c297ecf2fb33c346989a529d4e19164f1759102dee5953ee17e/idna-3.14.tar.gz", hash = "sha256:466d810d7a2cc1022bea9b037c39728d51ae7dad40d480fc9b7d7ecf98ba8ee3", size = 198272, upload-time = "2026-05-10T20:32:15.935Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/6c/3c/3f62dee257eb3d6b2c1ef2a09d36d9793c7111156a73b5654d2c2305e5ce/idna-3.14-py3-none-any.whl", hash = "sha256:e677eaf072e290f7b725f9acf0b3a2bd55f9fd6f7c70abe5f0e34823d0accf69", size = 72184, upload-time = "2026-05-10T20:32:14.295Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" },
]
[[package]]
@@ -585,14 +593,14 @@ wheels = [
[[package]]
name = "jaraco-functools"
-version = "4.4.0"
+version = "4.6.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "more-itertools" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/0f/27/056e0638a86749374d6f57d0b0db39f29509cce9313cf91bdc0ac4d91084/jaraco_functools-4.4.0.tar.gz", hash = "sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb", size = 19943, upload-time = "2025-12-21T09:29:43.6Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/6c/1f/c23395957d41ccf27c4e535c3d334c4051e5395b3752057ba4cbaec35c56/jaraco_functools-4.6.0.tar.gz", hash = "sha256:880c577ec9720b3a052d5bc611fb9f2269b3d87902ef42440df443b88e443280", size = 20837, upload-time = "2026-07-14T01:28:02.544Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl", hash = "sha256:9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176", size = 10481, upload-time = "2025-12-21T09:29:42.27Z" },
+ { url = "https://files.pythonhosted.org/packages/02/36/ecc85bc96c273dc8a11273ed4782272975e6338d4a3e9228621175edf0e3/jaraco_functools-4.6.0-py3-none-any.whl", hash = "sha256:99e3dc0060c5cbe8fcd1cdb36258e2a65ca40f1566b2033b12abb1bb44dd3c30", size = 11677, upload-time = "2026-07-14T01:28:01.59Z" },
]
[[package]]
@@ -615,7 +623,8 @@ dependencies = [
{ name = "attrs" },
{ name = "jsonschema-specifications" },
{ name = "referencing" },
- { name = "rpds-py" },
+ { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
+ { name = "rpds-py", version = "2026.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" }
wheels = [
@@ -730,31 +739,31 @@ wheels = [
[[package]]
name = "more-itertools"
-version = "11.0.2"
+version = "11.1.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a2/f7/139d22fef48ac78127d18e01d80cf1be40236ae489769d17f35c3d425293/more_itertools-11.0.2.tar.gz", hash = "sha256:392a9e1e362cbc106a2457d37cabf9b36e5e12efd4ebff1654630e76597df804", size = 144659, upload-time = "2026-04-09T15:01:33.297Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/de/1d/f4da6f02cdffe04d6362210b807146a26044c88d839208aec273bb0d9184/more_itertools-11.1.0.tar.gz", hash = "sha256:48e8f4d9e7e5878571ecf6f2b4e57634f93cd474cc8cfbd2376f2d11b396e30d", size = 145772, upload-time = "2026-05-22T14:14:29.909Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/cb/98/6af411189d9413534c3eb691182bff1f5c6d44ed2f93f2edfe52a1bbceb8/more_itertools-11.0.2-py3-none-any.whl", hash = "sha256:6e35b35f818b01f691643c6c611bc0902f2e92b46c18fffa77ae1e7c46e912e4", size = 71939, upload-time = "2026-04-09T15:01:32.21Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl", hash = "sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192", size = 72226, upload-time = "2026-05-22T14:14:28.824Z" },
]
[[package]]
name = "nostr-sdk"
-version = "0.44.2"
+version = "0.44.6"
source = { registry = "https://pypi.org/simple" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/35/ea/cd40b12352a5cba810116641959a7054f83d5f48d16e5e47614992b9ba64/nostr_sdk-0.44.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:184075689531e34085bc1e71b62f3a964df2d4aeb15a25f94557e15a4294c584", size = 3360561, upload-time = "2026-01-29T10:56:37.285Z" },
- { url = "https://files.pythonhosted.org/packages/ed/66/81057ec283cb6bcc5df27c1d58a0a7996afa4fb96c0c9a4570ae50190f9a/nostr_sdk-0.44.2-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:65e85c79295f4e258e5276a82b52e36ffb3f5cf59c2c7c4a959970ed9303cf6f", size = 3475196, upload-time = "2026-01-29T10:56:39.296Z" },
- { url = "https://files.pythonhosted.org/packages/61/fd/567b67c832b6263817470885e92b059b7d19cd9967b83ef1f59b6e04e603/nostr_sdk-0.44.2-cp39-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:d1d557aeb8a423dcd054f699bbf7371eb268a6cec5916bf147957cb3f9f7da02", size = 3613359, upload-time = "2026-01-29T10:56:41.079Z" },
- { url = "https://files.pythonhosted.org/packages/fc/93/cdf2cd98f8fbb045a1ca12f073ad747342961b0a3bbe9cd6a09760cb0132/nostr_sdk-0.44.2-cp39-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:41b1bb050f890f81b4c4edaf4d6cc3054ae9e783911eb4ce7dce6b8e97dfa60e", size = 3364451, upload-time = "2026-01-29T10:56:42.987Z" },
- { url = "https://files.pythonhosted.org/packages/8d/ec/7e9e9630af0b49e931cff8f65a5c9ce4086e9f2c372213d355b53871253c/nostr_sdk-0.44.2-cp39-abi3-manylinux_2_17_i686.whl", hash = "sha256:db584ba95de5abbb74da77036c3316e9a166bc22d9d2ea3ca38fc09325d9c6a9", size = 3603547, upload-time = "2026-01-29T10:56:44.404Z" },
- { url = "https://files.pythonhosted.org/packages/6a/03/c7ed0230f84615e2930259788b1fc1c485b159093f2070125ae9ddae327e/nostr_sdk-0.44.2-cp39-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:4e1dccf29b7ad6eeb44945175a45334d4e45d82881ae5f3a28433899f155831c", size = 3726609, upload-time = "2026-01-29T10:56:45.709Z" },
- { url = "https://files.pythonhosted.org/packages/d1/8d/bfb2172743a99a21bbba0a4f77572be50cb8b10dbcf837b70be0e0b8f4b7/nostr_sdk-0.44.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:aa347c6437dc33ae45cc2ed56177f5aeded0fda42285b1b325a840de44e1f708", size = 3607268, upload-time = "2026-01-29T10:56:47.312Z" },
- { url = "https://files.pythonhosted.org/packages/a3/af/cb61a46d91bf61f15b628d188a2338b9e76e9fee4078728d4a7ded876381/nostr_sdk-0.44.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:a7a03b35ddbc69f31d79bea17ac60b8d250ef62bcf1d52fc33b9e36e0ecf772b", size = 3360529, upload-time = "2026-01-29T10:56:49.248Z" },
- { url = "https://files.pythonhosted.org/packages/b2/dc/5405965ef11cc784be2dd473297caf997f8fa00b5f2e92884a029eae6eee/nostr_sdk-0.44.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:e53682dbf192acd137a92ae5d91903fbb22728d55452a8fa2315581f1d8413f2", size = 3494705, upload-time = "2026-01-29T10:56:51.158Z" },
- { url = "https://files.pythonhosted.org/packages/03/89/febbbec3d20cb63ab30eee84f59cb06317f24b8e2ab15c2d99212d71d622/nostr_sdk-0.44.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b3e6dd4191997546f157aba4532a995d06ad8b0cf9c17e77c0015553f06a9cf2", size = 3727113, upload-time = "2026-01-29T10:56:52.513Z" },
- { url = "https://files.pythonhosted.org/packages/67/d5/718b0428af9a3c9e33bd6a21b2b32920559db356e0369d0013b6421286d9/nostr_sdk-0.44.2-cp39-abi3-win32.whl", hash = "sha256:aa94a18eb8f4d77559c0290c0f17d6816c00f4fdddba5f1fcf96ff01b4690b42", size = 3164430, upload-time = "2026-01-29T10:56:54.334Z" },
- { url = "https://files.pythonhosted.org/packages/96/67/3f19800f6a52c2e1e7ba2b2b04ed0fca7a11a1819a2d02cdd961c4f4a54b/nostr_sdk-0.44.2-cp39-abi3-win_amd64.whl", hash = "sha256:31e609a864c3857cddde70d8a91181e2b2cadf923e562b6a9d82e655edded117", size = 3384420, upload-time = "2026-01-29T10:56:56.19Z" },
- { url = "https://files.pythonhosted.org/packages/71/bb/b2c2bb390fb309477bff63507c9d6058bea55d01f4938a749269dd5dd8bc/nostr_sdk-0.44.2-cp39-abi3-win_arm64.whl", hash = "sha256:3a9d3284af0547e224bf705d90cd6d9ca5a1b48f5becea1021da915de4408310", size = 3233797, upload-time = "2026-01-29T10:56:57.538Z" },
+ { url = "https://files.pythonhosted.org/packages/61/c3/1fbcb47aff23b368b817e5f6e90f3284b4b299e9bcf08e9a4cd414b80020/nostr_sdk-0.44.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:41dabb2539513db0b354c4fd2a3391307e50eb913a60c9325b1565e80e98530f", size = 3365132, upload-time = "2026-07-26T09:02:22.234Z" },
+ { url = "https://files.pythonhosted.org/packages/43/08/16525328d477e1fb427d47c0ccc14ce5b25f120871947374457a3267ae99/nostr_sdk-0.44.6-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:326526e6fd736c4dd6ad73b5cf7653d1a0ae46a3fb8d8ed4b4cb221ee64f7feb", size = 3482251, upload-time = "2026-07-26T09:02:23.623Z" },
+ { url = "https://files.pythonhosted.org/packages/65/a4/0f210f8490faf4c24dbc4bfbdc1943afc632d907c6fae48f88f0f3b55605/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:811637b021cfa338a38e37dda8df5dbeebe447458d567ad9b700a65199f6874c", size = 3611794, upload-time = "2026-07-26T09:02:24.758Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/73/ce525eed5f93969c62984f9397c80acf99883eab52bc055259e189eb1375/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:44cbec5c99a8a8c8e8beeb80ae7427a3ff20b943ca459bd0ba556e41c20dd246", size = 3359056, upload-time = "2026-07-26T09:02:26.101Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/ad/f700ddbbfcf2d0ff2285dec9b87b8b290d1f4359add21cb09b568bf52c0f/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_i686.whl", hash = "sha256:64e0304313bbbaa05226d9cac98618f94ab20e8e3f5e3a297179454e657d3446", size = 3607461, upload-time = "2026-07-26T09:02:27.393Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/ec/947f9fd4161a69da12bdbb8502a377c5ada2ab8e640ce5515c4a001cf81f/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:0234eae16b0fc11e3d72eb08c4c14b0c333a992e700d8fb88f191a42ef017a07", size = 3726683, upload-time = "2026-07-26T09:02:28.925Z" },
+ { url = "https://files.pythonhosted.org/packages/01/fe/448443ef9e23433f202c0362c2eb9e1b98dc0efffb5c3f9cae6f6252a5a8/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d16adc26a42cab37ae4ae8e3a8bed03dcedbe88c7862133c48cf9d99cb9e0cf3", size = 3605361, upload-time = "2026-07-26T09:02:30.308Z" },
+ { url = "https://files.pythonhosted.org/packages/df/02/b0e83f3f5066e525e5c1fd44c81f6711479cc6942aee298ebcd545fb3e59/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:dccebbc33500718ace5cf8e7ac6ed7fa41ec07f65f157896b392ac5f0b9ab2ed", size = 3360640, upload-time = "2026-07-26T09:02:31.615Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/01/7104eacda8609d52a148171354bca1095227a651860022984bf518ead1f2/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:e73a55e1f52dd4cb006f502725e65ab12b68609cb1b18d96b2ba74a3b245d264", size = 3493797, upload-time = "2026-07-26T09:02:32.973Z" },
+ { url = "https://files.pythonhosted.org/packages/00/80/e8de31cf0f1cf4c65ca5691a6c8baabbed19daccdccb427d73968e0335b9/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:512229272a68cc651bbe96b1d0ec78d12b899708d871ef92b49ce96eb33ba1fd", size = 3724890, upload-time = "2026-07-26T09:02:34.219Z" },
+ { url = "https://files.pythonhosted.org/packages/83/0f/6d4c364bd4f1ad1c76030aeddc43c5f6edd63d79cec289229de6afa5a72d/nostr_sdk-0.44.6-cp39-abi3-win32.whl", hash = "sha256:5eee3919224b653007e71a8e8a43465ee36156132839dfd15c120ee9b54d075c", size = 3164542, upload-time = "2026-07-26T09:02:35.291Z" },
+ { url = "https://files.pythonhosted.org/packages/90/f5/11141f5612f8fb361d39dbb95d6ec916059213a8d5625f8f98b58a7cfc70/nostr_sdk-0.44.6-cp39-abi3-win_amd64.whl", hash = "sha256:f89a13a4cec623283cd66218b8efedc8ec618b1b3e33a0e398240469f7b317e6", size = 3383380, upload-time = "2026-07-26T09:02:36.804Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/3e/552318b5c8307ab2f725de59b9bedbd06df3f031c252d11b15dcea302511/nostr_sdk-0.44.6-cp39-abi3-win_arm64.whl", hash = "sha256:c36845d218118dc0330f554fdea5c6e0c4a73bc54cb74dcf628750bf9260e01f", size = 3236001, upload-time = "2026-07-26T09:02:37.906Z" },
]
[[package]]
@@ -895,36 +904,36 @@ wheels = [
[[package]]
name = "pyln-client"
-version = "26.4.1"
+version = "26.6.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "pyln-bolt7" },
{ name = "pyln-proto" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/28/fe/e1e19c59dd7520dec2de992f0a3da6292db24162c9830be279616a7b8810/pyln_client-26.4.1.tar.gz", hash = "sha256:26dfb21ac39c61b7ab7a40db18798b002f3f19a179ff2ec40374a9419d032050", size = 92170, upload-time = "2026-04-24T04:53:08.46Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/25/5f/7e52fbe6b6d7d65651d2c908e1f68449256b3007a8259fa589282e9a4c0f/pyln_client-26.6.6.tar.gz", hash = "sha256:01c02021a62347d4d7dbaaa97bb627e9c2b60212a2e146107a782c1c156588ba", size = 92480, upload-time = "2026-07-20T12:39:51.278Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/65/90/d3b5e11f85cf076b1011a1ea6031ced3745abf451e47a1697216e1ea7c29/pyln_client-26.4.1-py3-none-any.whl", hash = "sha256:a9afba9b117818023bf4567a94c34633e9f2e89f0e1ca11e433329a2c678a685", size = 37673, upload-time = "2026-04-24T04:53:07.187Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/c0/2efddeec3dda9c915b02fc406bcc1f179d8c45cc9a2e8089608cbdde1a0e/pyln_client-26.6.6-py3-none-any.whl", hash = "sha256:6afa9019aef1e54fa01e185be160773ac4db2fdc7cf864a319e7374b71cd6a6d", size = 37975, upload-time = "2026-07-20T12:39:50.024Z" },
]
[[package]]
name = "pyln-proto"
-version = "26.4.1"
+version = "26.6.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "base58" },
{ name = "bitstring" },
- { name = "coincurve" },
+ { name = "coincurve-cp314-fix" },
{ name = "cryptography" },
{ name = "pysocks" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/8c/4b/c8d676ad84d6066553b203668c0e36f45cfae0a4d7140eb88aed6d65b38b/pyln_proto-26.4.1.tar.gz", hash = "sha256:d73f261bacc06a6a613dcece05fc429699b740a4673f24dffb7c41bd3542d589", size = 44864, upload-time = "2026-04-24T04:53:10.196Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/a8/97/219900f708391678165461e6b519c6272edb5966b2e20c62856e9c1f736a/pyln_proto-26.6.6.tar.gz", hash = "sha256:b6d424eb22d33de9fc21e4216502759e34a62eaf460a47cc45dbbb208096db8a", size = 44879, upload-time = "2026-07-20T12:40:07.68Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a3/f1/6541b6cd8a017d3505fcb49885d3f01b8e6bb09e40db18e686edb9edeb99/pyln_proto-26.4.1-py3-none-any.whl", hash = "sha256:b5d10d5e69cf3debd9b289e2ffa49713fca6c349a71cb0eaf9e733024f15b3da", size = 31833, upload-time = "2026-04-24T04:53:08.686Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/18/ed5d323f55350b175e5f8bbed7b0c8acb988eb48ee37dd5b44d9e7a41799/pyln_proto-26.6.6-py3-none-any.whl", hash = "sha256:b7b12769e2c37e6d1ce7c2063bbab67f5959e411459ff089d0dbc14109778e03", size = 31833, upload-time = "2026-07-20T12:40:06.677Z" },
]
[[package]]
name = "pyln-testing"
-version = "26.4.1"
+version = "26.6.6"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cheroot" },
@@ -939,9 +948,9 @@ dependencies = [
{ name = "python-bitcoinlib" },
{ name = "requests" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/64/73/d969847564591fe16633b11bf8be9f8184ccd885e367acee171e9fd6d2d8/pyln_testing-26.4.1.tar.gz", hash = "sha256:0a40d66ec2f0840df95bdbc4845c214aede01e9d7a89a422f5b6b00a89e63690", size = 52617, upload-time = "2026-04-24T04:53:10.904Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/6f/86/49b10e9317142f989dc03c7d42d512789a83000da7660177393a9d7e681b/pyln_testing-26.6.6.tar.gz", hash = "sha256:31caa503724d02bb736d8b1e11cd344cff15e0229bc6f709bd1571df5066b432", size = 53213, upload-time = "2026-07-20T12:39:37.337Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/c6/ad/603ff35f7b60bcc6cf364a101c58a73887132063f0773767108946361ed2/pyln_testing-26.4.1-py3-none-any.whl", hash = "sha256:dd0e9d8a865593ddc9a14ef43e9aaec0fe0d348ce9ec2fcd23807a35c98c9e8c", size = 54381, upload-time = "2026-04-24T04:53:09.599Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/28/58c3524d0d1c1e244580bd82730f7c0e72b60e5a52b0d34c4395e7f46a1d/pyln_testing-26.6.6-py3-none-any.whl", hash = "sha256:24b814f6977faa1e66f98a6a447b397d148ba683c53a73e595a429c53a88af78", size = 54976, upload-time = "2026-07-20T12:39:36.32Z" },
]
[[package]]
@@ -955,7 +964,7 @@ wheels = [
[[package]]
name = "pytest"
-version = "8.4.2"
+version = "9.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
@@ -966,23 +975,23 @@ dependencies = [
{ name = "pygments" },
{ name = "tomli", marker = "python_full_version < '3.11'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
+ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
]
[[package]]
name = "pytest-asyncio"
-version = "1.3.0"
+version = "1.4.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" },
{ name = "pytest" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" },
+ { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" },
]
[[package]]
@@ -1025,7 +1034,8 @@ version = "0.37.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
- { name = "rpds-py" },
+ { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
+ { name = "rpds-py", version = "2026.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" }
@@ -1035,7 +1045,7 @@ wheels = [
[[package]]
name = "requests"
-version = "2.34.0"
+version = "2.34.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
@@ -1043,15 +1053,18 @@ dependencies = [
{ name = "idna" },
{ name = "urllib3" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/43/b8/7a707d60fea4c49094e40262cc0e2ca6c768cca21587e34d3f705afec47e/requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a", size = 142436, upload-time = "2026-05-11T19:29:51.717Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ef/e6/e300fce5fe83c30520607a015dabd985df3251e188d234bfe9492e17a389/requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60", size = 73021, upload-time = "2026-05-11T19:29:49.923Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" },
]
[[package]]
name = "rpds-py"
version = "0.30.0"
source = { registry = "https://pypi.org/simple" }
+resolution-markers = [
+ "python_full_version < '3.11'",
+]
sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" },
@@ -1170,6 +1183,132 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" },
]
+[[package]]
+name = "rpds-py"
+version = "2026.6.3"
+source = { registry = "https://pypi.org/simple" }
+resolution-markers = [
+ "python_full_version >= '3.11'",
+]
+sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" },
+ { url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" },
+ { url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" },
+ { url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" },
+ { url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" },
+ { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" },
+ { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" },
+ { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" },
+ { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" },
+ { url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" },
+ { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" },
+ { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" },
+ { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" },
+ { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" },
+ { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" },
+ { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" },
+ { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" },
+ { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" },
+ { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" },
+ { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" },
+ { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" },
+ { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" },
+ { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" },
+ { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" },
+ { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" },
+ { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" },
+ { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" },
+ { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" },
+ { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" },
+ { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" },
+ { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" },
+ { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" },
+ { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" },
+ { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" },
+ { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" },
+ { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" },
+ { url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" },
+ { url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" },
+ { url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" },
+]
+
[[package]]
name = "tibs"
version = "0.5.7"
@@ -1264,11 +1403,11 @@ wheels = [
[[package]]
name = "typing-extensions"
-version = "4.15.0"
+version = "4.16.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
+ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
]
[[package]]
From 6d984a090094c8634aba96117e44f0cb8f792093 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 26 Jul 2026 15:02:51 +0200
Subject: [PATCH 24/56] CI: download hold binary
---
.github/workflows/ci.yml | 7 +
Cargo.lock | 346 +++++++++++++++++----------------------
2 files changed, 159 insertions(+), 194 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b15911b..cac47ea 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -153,6 +153,13 @@ jobs:
uv run python -m grpc_tools.protoc --proto_path="proto" --python_out="tests" --grpc_python_out="tests" proto/*.proto
fi
+ url=$(curl -f --retry 3 --retry-delay 3 -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/BoltzExchange/hold/releases/latest \
+ | jq '.assets[] | select(.name | endswith("linux-amd64.tar.gz")) | .browser_download_url' \
+ | tr -d '\"')
+ wget $url
+ tar -xvf ${url##*/} -C tests
+ mv "tests/build/hold-linux-amd64" "tests/hold"
+
cargo build
cargo test
fi
diff --git a/Cargo.lock b/Cargo.lock
index c693f75..7eb17b6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -34,25 +34,25 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.104"
+version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "arrayvec"
-version = "0.7.8"
+version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
+checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe"
[[package]]
name = "async-trait"
-version = "0.1.91"
+version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec"
+checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
- "syn 3.0.3",
+ "syn",
]
[[package]]
@@ -95,9 +95,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "base58ck"
-version = "0.1.101"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "365c0acd5b2e8dd0111a46c4faea83fb3cfb6e39a49a7c73a06e090db7b2eff0"
+checksum = "8f1cba749a07c1efb1f4d87518f39cea4aec25d0991fb97e80459c057238f0d2"
dependencies = [
"bitcoin_hashes",
]
@@ -127,73 +127,52 @@ dependencies = [
[[package]]
name = "bitcoin"
-version = "0.32.102"
+version = "0.32.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb0ce8bd5baaa0d303a19915a6d93afed161f528654e42da2a7a97d05c59499a"
+checksum = "a1a121ccf1177a09084bd6ce97c52119919aac08ea3649967958eae41beceebf"
dependencies = [
"base58ck",
"bech32",
"bitcoin-io",
"bitcoin-units",
"bitcoin_hashes",
- "hex-conservative 0.2.2",
+ "hex-conservative",
"hex_lit",
"secp256k1",
"serde",
]
-[[package]]
-name = "bitcoin-consensus-encoding"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "207311705279250ba465076a1bac4b1ac982855fff73fc5f67e22158ac58cdc9"
-dependencies = [
- "bitcoin-internals",
- "hex-conservative 1.2.0",
- "serde",
-]
-
-[[package]]
-name = "bitcoin-internals"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d573f4cf32996a8dce612e4348cece65a241f1882ed594047c9ba348e8869fa5"
-
[[package]]
name = "bitcoin-io"
-version = "0.1.101"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78"
-dependencies = [
- "bitcoin-consensus-encoding",
-]
+checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953"
[[package]]
name = "bitcoin-units"
-version = "0.1.101"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cb95693f371d089a4b5b6fc41c6f3ea6e01ee8c15388335dfac8ea685173b51"
+checksum = "c202276cab20ab02cf6cc9d4df0d4284f7c784031619d3842236de8bc2bd5c6c"
dependencies = [
- "bitcoin-consensus-encoding",
"serde",
]
[[package]]
name = "bitcoin_hashes"
-version = "0.14.101"
+version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2"
+checksum = "4ed83caece3afc59919481b33b472e1432d1abc4641ed9100be142ef5110b406"
dependencies = [
"bitcoin-io",
- "hex-conservative 0.2.2",
+ "hex-conservative",
"serde",
]
[[package]]
name = "bitflags"
-version = "2.13.1"
+version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]]
name = "block-buffer"
@@ -233,9 +212,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.12.1"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
+checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
[[package]]
name = "cbc"
@@ -248,9 +227,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.4.0"
+version = "1.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9"
+checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -403,14 +382,14 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
name = "either"
-version = "1.17.0"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
+checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]]
name = "equivalent"
@@ -440,9 +419,9 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.5.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
+checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "find-msvc-tools"
@@ -479,9 +458,9 @@ dependencies = [
[[package]]
name = "futures"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218"
+checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
@@ -494,9 +473,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae"
+checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
@@ -504,15 +483,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
+checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458"
+checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
@@ -521,38 +500,38 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"
+checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-macro"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
+checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
name = "futures-sink"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307"
+checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
+checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
-version = "0.3.33"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
+checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
@@ -696,15 +675,6 @@ dependencies = [
"arrayvec",
]
-[[package]]
-name = "hex-conservative"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35431185f361ccf3ffc58254628af5f1f5d5f28531da2e02e5d6c82bbc282a10"
-dependencies = [
- "arrayvec",
-]
-
[[package]]
name = "hex_lit"
version = "0.1.1"
@@ -723,9 +693,9 @@ dependencies = [
[[package]]
name = "http-body"
-version = "1.1.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
@@ -733,9 +703,9 @@ dependencies = [
[[package]]
name = "http-body-util"
-version = "0.1.4"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2"
+checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
@@ -758,9 +728,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
-version = "1.11.0"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72"
+checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
dependencies = [
"atomic-waker",
"bytes",
@@ -950,9 +920,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
-version = "0.3.103"
+version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
+checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
dependencies = [
"cfg-if",
"futures-util",
@@ -967,9 +937,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
-version = "0.2.189"
+version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "linux-raw-sys"
@@ -1024,15 +994,15 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.8.3"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
+checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "mio"
-version = "1.2.2"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
+checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
dependencies = [
"libc",
"wasi",
@@ -1203,7 +1173,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -1248,14 +1218,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
- "syn 2.0.119",
+ "syn",
]
[[package]]
name = "proc-macro2"
-version = "1.0.107"
+version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
@@ -1287,7 +1257,7 @@ dependencies = [
"pulldown-cmark",
"pulldown-cmark-to-cmark",
"regex",
- "syn 2.0.119",
+ "syn",
"tempfile",
]
@@ -1301,7 +1271,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -1399,9 +1369,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.47"
+version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
@@ -1420,9 +1390,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
-version = "0.9.5"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
+checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
dependencies = [
"rand_chacha",
"rand_core 0.9.5",
@@ -1474,9 +1444,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.13.1"
+version = "1.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
+checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
dependencies = [
"aho-corasick",
"memchr",
@@ -1486,9 +1456,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.16"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
@@ -1530,9 +1500,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.42"
+version = "0.23.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138"
+checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
dependencies = [
"log",
"once_cell",
@@ -1545,9 +1515,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.15.1"
+version = "1.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
+checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
dependencies = [
"zeroize",
]
@@ -1565,9 +1535,9 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.23"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "scopeguard"
@@ -1597,9 +1567,9 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.229"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
+checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
@@ -1607,29 +1577,29 @@ dependencies = [
[[package]]
name = "serde_core"
-version = "1.0.229"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
+checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.229"
+version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
+checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
- "syn 3.0.3",
+ "syn",
]
[[package]]
name = "serde_json"
-version = "1.0.151"
+version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
@@ -1640,9 +1610,9 @@ dependencies = [
[[package]]
name = "sha1"
-version = "0.10.7"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -1678,9 +1648,9 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
[[package]]
name = "socket2"
-version = "0.6.5"
+version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
+checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
dependencies = [
"libc",
"windows-sys 0.61.2",
@@ -1700,20 +1670,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.119"
+version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
-version = "3.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
+checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
@@ -1734,7 +1693,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -1761,11 +1720,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.19"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
+checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
- "thiserror-impl 2.0.19",
+ "thiserror-impl 2.0.18",
]
[[package]]
@@ -1776,25 +1735,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
name = "thiserror-impl"
-version = "2.0.19"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
+checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
- "syn 3.0.3",
+ "syn",
]
[[package]]
name = "thread_local"
-version = "1.1.10"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070"
+checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
"cfg-if",
]
@@ -1811,9 +1770,9 @@ dependencies = [
[[package]]
name = "tinyvec"
-version = "1.12.0"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
+checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
dependencies = [
"tinyvec_macros",
]
@@ -1826,9 +1785,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.53.1"
+version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
+checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes",
"libc",
@@ -1850,13 +1809,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.7.1"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
+checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -1883,9 +1842,9 @@ dependencies = [
[[package]]
name = "tokio-stream"
-version = "0.1.19"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b"
+checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -1911,14 +1870,13 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.19"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
+checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
- "libc",
"pin-project-lite",
"tokio",
]
@@ -1961,7 +1919,7 @@ dependencies = [
"prettyplease",
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -1986,7 +1944,7 @@ dependencies = [
"prost-build",
"prost-types",
"quote",
- "syn 2.0.119",
+ "syn",
"tempfile",
"tonic-build",
]
@@ -2042,7 +2000,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -2101,11 +2059,11 @@ dependencies = [
"http",
"httparse",
"log",
- "rand 0.9.5",
+ "rand 0.9.4",
"rustls",
"rustls-pki-types",
"sha1",
- "thiserror 2.0.19",
+ "thiserror 2.0.18",
"utf-8",
]
@@ -2185,9 +2143,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
-version = "1.24.0"
+version = "1.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
+checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
dependencies = [
"getrandom 0.4.3",
"js-sys",
@@ -2232,9 +2190,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen"
-version = "0.2.126"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
+checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
dependencies = [
"cfg-if",
"once_cell",
@@ -2245,9 +2203,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.76"
+version = "0.4.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d"
+checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2255,9 +2213,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.126"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
+checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2265,31 +2223,31 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.126"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
+checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.126"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
+checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
-version = "0.3.103"
+version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141"
+checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2301,14 +2259,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
- "webpki-roots 1.0.9",
+ "webpki-roots 1.0.8",
]
[[package]]
name = "webpki-roots"
-version = "1.0.9"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
+checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
dependencies = [
"rustls-pki-types",
]
@@ -2432,28 +2390,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
"synstructure",
]
[[package]]
name = "zerocopy"
-version = "0.8.55"
+version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb"
+checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.55"
+version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb"
+checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
@@ -2473,7 +2431,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
"synstructure",
]
@@ -2513,11 +2471,11 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
+ "syn",
]
[[package]]
name = "zmij"
-version = "1.0.23"
+version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
From edd95056abc975e39e553afffb5baaf2e8eae196 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 12:55:49 +0200
Subject: [PATCH 25/56] update for nostr 0.45 release version
---
Cargo.lock | 492 +++++++++++++++++++++++----------------
Cargo.toml | 4 +-
src/nwc.rs | 15 +-
src/nwc_hold.rs | 12 +-
src/nwc_lookups.rs | 2 +-
src/nwc_notifications.rs | 7 +-
src/rpc.rs | 6 +-
src/structs.rs | 14 +-
8 files changed, 323 insertions(+), 229 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 7eb17b6..20ea17f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -25,41 +25,41 @@ dependencies = [
[[package]]
name = "aho-corasick"
-version = "1.1.4"
+version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
-version = "1.0.102"
+version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "arrayvec"
-version = "0.7.7"
+version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe"
+checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
[[package]]
name = "async-trait"
-version = "0.1.89"
+version = "0.1.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
+checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
name = "async-utility"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a34a3b57207a7a1007832416c3e4862378c8451b4e8e093e436f48c2d3d2c151"
+checksum = "188f83b9a198af8c336e505611edb00d6d2ac5c694241c5a4f9a12316938cfe9"
dependencies = [
"futures-util",
"gloo-timers",
@@ -69,9 +69,9 @@ dependencies = [
[[package]]
name = "async-wsocket"
-version = "0.15.0"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c69f24cf7a798027c6b0801de5bfd05d01fe343e87a8329f7c8b46a6d3bc4a79"
+checksum = "2c713e1f14c7b82e32ea159af1c6e2f070cfadbdf23fb2512acce9af0a26f1a2"
dependencies = [
"futures",
"futures-util",
@@ -95,11 +95,11 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "base58ck"
-version = "0.1.1"
+version = "0.1.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1cba749a07c1efb1f4d87518f39cea4aec25d0991fb97e80459c057238f0d2"
+checksum = "365c0acd5b2e8dd0111a46c4faea83fb3cfb6e39a49a7c73a06e090db7b2eff0"
dependencies = [
- "bitcoin_hashes",
+ "bitcoin_hashes 0.14.101",
]
[[package]]
@@ -114,65 +114,104 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f"
+[[package]]
+name = "bech32"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "efbd3e1070bbdf4cd88a75264e18e8a26f7cb5c6949eadf0ceb85fb159cf08f8"
+
[[package]]
name = "bip39"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc"
dependencies = [
- "bitcoin_hashes",
+ "bitcoin_hashes 0.14.101",
"serde",
"unicode-normalization",
]
[[package]]
name = "bitcoin"
-version = "0.32.10"
+version = "0.32.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1a121ccf1177a09084bd6ce97c52119919aac08ea3649967958eae41beceebf"
+checksum = "bb0ce8bd5baaa0d303a19915a6d93afed161f528654e42da2a7a97d05c59499a"
dependencies = [
"base58ck",
- "bech32",
+ "bech32 0.11.1",
"bitcoin-io",
"bitcoin-units",
- "bitcoin_hashes",
- "hex-conservative",
+ "bitcoin_hashes 0.14.101",
+ "hex-conservative 0.2.2",
"hex_lit",
- "secp256k1",
+ "secp256k1 0.29.1",
"serde",
]
[[package]]
-name = "bitcoin-io"
-version = "0.1.4"
+name = "bitcoin-consensus-encoding"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953"
+checksum = "207311705279250ba465076a1bac4b1ac982855fff73fc5f67e22158ac58cdc9"
+dependencies = [
+ "bitcoin-internals",
+ "hex-conservative 1.2.0",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin-internals"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d573f4cf32996a8dce612e4348cece65a241f1882ed594047c9ba348e8869fa5"
+
+[[package]]
+name = "bitcoin-io"
+version = "0.1.101"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb5de036369d1ac59d3c1819ebc4d850f89466f5401c571a285b6ed564a4cb78"
+dependencies = [
+ "bitcoin-consensus-encoding",
+]
[[package]]
name = "bitcoin-units"
-version = "0.1.4"
+version = "0.1.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c202276cab20ab02cf6cc9d4df0d4284f7c784031619d3842236de8bc2bd5c6c"
+checksum = "9cb95693f371d089a4b5b6fc41c6f3ea6e01ee8c15388335dfac8ea685173b51"
dependencies = [
+ "bitcoin-consensus-encoding",
"serde",
]
[[package]]
name = "bitcoin_hashes"
-version = "0.14.2"
+version = "0.14.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ed83caece3afc59919481b33b472e1432d1abc4641ed9100be142ef5110b406"
+checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2"
dependencies = [
"bitcoin-io",
- "hex-conservative",
+ "hex-conservative 0.2.2",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin_hashes"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5304e53726dbe5f93141535e102ed97b5bf4714fbecefdda8f9fb98d7fdaff0e"
+dependencies = [
+ "bitcoin-consensus-encoding",
+ "bitcoin-internals",
+ "hex-conservative 1.2.0",
"serde",
]
[[package]]
name = "bitflags"
-version = "2.13.0"
+version = "2.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
[[package]]
name = "block-buffer"
@@ -192,12 +231,6 @@ dependencies = [
"generic-array",
]
-[[package]]
-name = "btreecap"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6160c957d8aa33d0a8ba1dbab98e3cb57023ad9374c501441e88559f99e6c4c9"
-
[[package]]
name = "bumpalo"
version = "3.20.3"
@@ -212,9 +245,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.12.0"
+version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
+checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04"
[[package]]
name = "cbc"
@@ -227,9 +260,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.65"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
+checksum = "5d262e149917187838d5b42777c8253bcb64500067342904e7d429499a6f277e"
dependencies = [
"find-msvc-tools",
"shlex",
@@ -360,9 +393,9 @@ dependencies = [
[[package]]
name = "data-encoding"
-version = "2.11.0"
+version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
+checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06"
[[package]]
name = "digest"
@@ -376,20 +409,20 @@ dependencies = [
[[package]]
name = "displaydoc"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
+checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
name = "either"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
[[package]]
name = "equivalent"
@@ -419,15 +452,15 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.4.1"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
+checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
[[package]]
name = "find-msvc-tools"
-version = "0.1.9"
+version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+checksum = "26b73573e6edcd2af0cdf47bd6cb58f0b3839491263c314eaad1ccf24430e1de"
[[package]]
name = "fixedbitset"
@@ -458,9 +491,9 @@ dependencies = [
[[package]]
name = "futures"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
+checksum = "a88cf1f829d945f548cf8fec32c61b1f202b6d93b45848602fc02af4b12ad218"
dependencies = [
"futures-channel",
"futures-core",
@@ -473,9 +506,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
+checksum = "262590f4fe6afeb0bc83be1daa64e52657fe185690a958af7f3ad0e92085c5ae"
dependencies = [
"futures-core",
"futures-sink",
@@ -483,15 +516,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
+checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
[[package]]
name = "futures-executor"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
+checksum = "6754879cc9f2c66f88c6e5c35344bb0bdb0708b0352b1201815667c7eabc7458"
dependencies = [
"futures-core",
"futures-task",
@@ -500,38 +533,38 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
+checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a"
[[package]]
name = "futures-macro"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
+checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "futures-sink"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
+checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307"
[[package]]
name = "futures-task"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
+checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109"
[[package]]
name = "futures-util"
-version = "0.3.32"
+version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
+checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
dependencies = [
"futures-channel",
"futures-core",
@@ -675,6 +708,15 @@ dependencies = [
"arrayvec",
]
+[[package]]
+name = "hex-conservative"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35431185f361ccf3ffc58254628af5f1f5d5f28531da2e02e5d6c82bbc282a10"
+dependencies = [
+ "arrayvec",
+]
+
[[package]]
name = "hex_lit"
version = "0.1.1"
@@ -683,9 +725,9 @@ checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
[[package]]
name = "http"
-version = "1.4.2"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
+checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
dependencies = [
"bytes",
"itoa",
@@ -693,9 +735,9 @@ dependencies = [
[[package]]
name = "http-body"
-version = "1.0.1"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
dependencies = [
"bytes",
"http",
@@ -703,9 +745,9 @@ dependencies = [
[[package]]
name = "http-body-util"
-version = "0.1.3"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
+checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2"
dependencies = [
"bytes",
"futures-core",
@@ -728,9 +770,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
-version = "1.10.1"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
+checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72"
dependencies = [
"atomic-waker",
"bytes",
@@ -920,9 +962,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
-version = "0.3.102"
+version = "0.3.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
+checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
dependencies = [
"cfg-if",
"futures-util",
@@ -937,9 +979,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
-version = "0.2.186"
+version = "0.2.189"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
[[package]]
name = "linux-raw-sys"
@@ -979,9 +1021,9 @@ dependencies = [
[[package]]
name = "lru"
-version = "0.18.1"
+version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b6180140927ee907000b0aa540091f6ea512ead4447c92b8fc35bc72788a5a6"
+checksum = "5d2f2f9b4ba7e6b24d95e7e899329d35be83bcded72c8540cdd5368932d1d90a"
[[package]]
name = "matchers"
@@ -994,15 +1036,15 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.8.2"
+version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "mio"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
+checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
dependencies = [
"libc",
"wasi",
@@ -1023,45 +1065,45 @@ checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d"
[[package]]
name = "nostr"
-version = "0.45.0-alpha.6"
+version = "0.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e90ba68fc04b87254ef574e10aef1fe92d44839043f42e37a7c4c4a1e7e4c82"
+checksum = "5dde8c76076d334409d86c2e1db3e97abe5deb8cb92744f939cbc1fa45bd69e7"
dependencies = [
"aes",
"base64",
- "bech32",
+ "bech32 0.12.0",
"bip39",
- "bitcoin_hashes",
+ "bitcoin_hashes 1.2.0",
"cbc",
"chacha20",
"chacha20poly1305",
"faster-hex",
"opaquerr",
"rand 0.10.2",
- "secp256k1",
+ "secp256k1 0.30.0",
"serde",
"serde_json",
"unicode-normalization",
"universal-time",
"url",
+ "zeroize",
]
[[package]]
name = "nostr-database"
-version = "0.45.0-alpha.6"
+version = "0.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77c37167c3f289fea43e82f8bb24bb2006a2fb803abaaa908b25f1d3ca0b2bcc"
+checksum = "4b1fdb9fcba732e32719662afad1b267e50322dbe89e506017ec13f24361bddf"
dependencies = [
- "btreecap",
"nostr",
"opaquerr",
]
[[package]]
name = "nostr-gossip"
-version = "0.45.0-alpha.6"
+version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb24a1f82e3fe9e3e9b4549e916ec168d4c21c2e55c61fa6be9f98218872cd37"
+checksum = "fa07539e52a71cb91fe0d693facaa298f03fcf9edcd66a521094e18e286e2336"
dependencies = [
"nostr",
"opaquerr",
@@ -1069,9 +1111,9 @@ dependencies = [
[[package]]
name = "nostr-sdk"
-version = "0.45.0-alpha.6"
+version = "0.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b197627792d5f02ab257c1bff30d4475e0ebc85229a82515b05d6717c6a4fbc"
+checksum = "26c86342f367bd9b173ec4a697e936e3a82d6dad5b4aa06c0d35d9b4f88a8e72"
dependencies = [
"async-utility",
"async-wsocket",
@@ -1083,6 +1125,7 @@ dependencies = [
"nostr-database",
"nostr-gossip",
"opaquerr",
+ "rand 0.10.2",
"tokio",
"tokio-stream",
"tracing",
@@ -1112,9 +1155,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "opaquerr"
-version = "0.1.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e55a7b7f0accc9fdd8e514f122a697adf824d55de481ca26c31ff8f9a8e813c5"
+checksum = "4f933a4265d5cdad61d19bbdfc972ea5726d56cd8d3d57b8f2d3c365dd42bee9"
[[package]]
name = "parking_lot"
@@ -1173,7 +1216,7 @@ checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1218,14 +1261,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "proc-macro2"
-version = "1.0.106"
+version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
+checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
@@ -1257,7 +1300,7 @@ dependencies = [
"pulldown-cmark",
"pulldown-cmark-to-cmark",
"regex",
- "syn",
+ "syn 2.0.119",
"tempfile",
]
@@ -1271,7 +1314,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1369,9 +1412,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.45"
+version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
+checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
@@ -1390,11 +1433,22 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
-version = "0.9.4"
+version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
+checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a"
dependencies = [
- "rand_chacha",
+ "libc",
+ "rand_chacha 0.3.1",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
+dependencies = [
+ "rand_chacha 0.9.0",
"rand_core 0.9.5",
]
@@ -1408,6 +1462,16 @@ dependencies = [
"rand_core 0.10.1",
]
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
[[package]]
name = "rand_chacha"
version = "0.9.0"
@@ -1418,6 +1482,15 @@ dependencies = [
"rand_core 0.9.5",
]
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.17",
+]
+
[[package]]
name = "rand_core"
version = "0.9.5"
@@ -1444,9 +1517,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.12.4"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
+checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
dependencies = [
"aho-corasick",
"memchr",
@@ -1456,9 +1529,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.14"
+version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
+checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
dependencies = [
"aho-corasick",
"memchr",
@@ -1500,9 +1573,9 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.40"
+version = "0.23.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
+checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
dependencies = [
"log",
"once_cell",
@@ -1515,9 +1588,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.14.1"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
+checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
dependencies = [
"zeroize",
]
@@ -1535,9 +1608,9 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.22"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
[[package]]
name = "scopeguard"
@@ -1551,11 +1624,22 @@ version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113"
dependencies = [
- "bitcoin_hashes",
+ "bitcoin_hashes 0.14.101",
"secp256k1-sys",
"serde",
]
+[[package]]
+name = "secp256k1"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252"
+dependencies = [
+ "bitcoin_hashes 0.14.101",
+ "rand 0.8.7",
+ "secp256k1-sys",
+]
+
[[package]]
name = "secp256k1-sys"
version = "0.10.1"
@@ -1567,9 +1651,9 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.228"
+version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
+checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
"serde_core",
"serde_derive",
@@ -1577,29 +1661,29 @@ dependencies = [
[[package]]
name = "serde_core"
-version = "1.0.228"
+version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
+checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.228"
+version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
+checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
name = "serde_json"
-version = "1.0.150"
+version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"itoa",
"memchr",
@@ -1610,9 +1694,9 @@ dependencies = [
[[package]]
name = "sha1"
-version = "0.10.6"
+version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -1648,9 +1732,9 @@ checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
[[package]]
name = "socket2"
-version = "0.6.4"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
+checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
dependencies = [
"libc",
"windows-sys 0.61.2",
@@ -1670,9 +1754,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.118"
+version = "2.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
+checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [
"proc-macro2",
"quote",
@@ -1693,7 +1788,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1720,11 +1815,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.18"
+version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
+checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
dependencies = [
- "thiserror-impl 2.0.18",
+ "thiserror-impl 2.0.20",
]
[[package]]
@@ -1735,25 +1830,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "thiserror-impl"
-version = "2.0.18"
+version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
name = "thread_local"
-version = "1.1.9"
+version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
+checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070"
dependencies = [
"cfg-if",
]
@@ -1770,9 +1865,9 @@ dependencies = [
[[package]]
name = "tinyvec"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
+checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
dependencies = [
"tinyvec_macros",
]
@@ -1785,9 +1880,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.52.3"
+version = "1.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
+checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
dependencies = [
"bytes",
"libc",
@@ -1809,13 +1904,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.7.0"
+version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
+checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 3.0.3",
]
[[package]]
@@ -1842,9 +1937,9 @@ dependencies = [
[[package]]
name = "tokio-stream"
-version = "0.1.18"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
+checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -1870,13 +1965,14 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.18"
+version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
+checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
+ "libc",
"pin-project-lite",
"tokio",
]
@@ -1919,7 +2015,7 @@ dependencies = [
"prettyplease",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -1944,7 +2040,7 @@ dependencies = [
"prost-build",
"prost-types",
"quote",
- "syn",
+ "syn 2.0.119",
"tempfile",
"tonic-build",
]
@@ -2000,7 +2096,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -2059,11 +2155,11 @@ dependencies = [
"http",
"httparse",
"log",
- "rand 0.9.4",
+ "rand 0.9.5",
"rustls",
"rustls-pki-types",
"sha1",
- "thiserror 2.0.18",
+ "thiserror 2.0.20",
"utf-8",
]
@@ -2106,9 +2202,9 @@ dependencies = [
[[package]]
name = "universal-time"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f942cacf37a673350e8f252dff4691fb8e525a5fff6e1f2c4b6c2f3b8349248d"
+checksum = "47a939edecc3c5a7b83c02e5f6b3c31d2bc69eabcc9a87ab12c6d37ee6dbc856"
[[package]]
name = "untrusted"
@@ -2143,9 +2239,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
-version = "1.23.3"
+version = "1.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
+checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
dependencies = [
"getrandom 0.4.3",
"js-sys",
@@ -2190,9 +2286,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen"
-version = "0.2.125"
+version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
+checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
dependencies = [
"cfg-if",
"once_cell",
@@ -2203,9 +2299,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.75"
+version = "0.4.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
+checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2213,9 +2309,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.125"
+version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
+checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -2223,31 +2319,31 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.125"
+version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
+checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.125"
+version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
+checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
-version = "0.3.102"
+version = "0.3.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
+checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2259,14 +2355,14 @@ version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
- "webpki-roots 1.0.8",
+ "webpki-roots 1.0.9",
]
[[package]]
name = "webpki-roots"
-version = "1.0.8"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf"
+checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a"
dependencies = [
"rustls-pki-types",
]
@@ -2390,28 +2486,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
"synstructure",
]
[[package]]
name = "zerocopy"
-version = "0.8.52"
+version = "0.8.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
+checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.52"
+version = "0.8.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
+checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
@@ -2431,7 +2527,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
"synstructure",
]
@@ -2471,11 +2567,11 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.119",
]
[[package]]
name = "zmij"
-version = "1.0.21"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
diff --git a/Cargo.toml b/Cargo.toml
index 484d61b..42419e6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,8 +24,8 @@ parking_lot = "0.12"
# "nip04",
# "nip44",
# ] }
-nostr = { version = "0.45.0-alpha.4", features = ["nip47", "nip04", "nip44"] }
-nostr-sdk = { version = "0.45.0-alpha.4" }
+nostr = { version = "0.45.1", features = ["nip47", "nip04", "nip44"] }
+nostr-sdk = { version = "0.45.1" }
futures = "0.3"
diff --git a/src/nwc.rs b/src/nwc.rs
index c381f94..68a1597 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -4,18 +4,11 @@ use anyhow::anyhow;
use cln_plugin::Plugin;
use futures::StreamExt;
use nostr::{
- Event,
- EventBuilder,
- EventId,
- Filter,
- Keys,
- Kind,
- PublicKey,
- SecretKey,
- Tag,
- Timestamp,
- event::FinalizeEventAsync,
+ event::{Event, EventBuilder, EventId, FinalizeEventAsync, Kind, Tag},
+ filter::Filter,
+ key::{Keys, PublicKey, SecretKey},
nips::{nip04, nip44, nip47},
+ types::Timestamp,
};
use nostr_sdk::{
client::{self, Client, ClientNotification},
diff --git a/src/nwc_hold.rs b/src/nwc_hold.rs
index d3b0d8f..c87ce50 100644
--- a/src/nwc_hold.rs
+++ b/src/nwc_hold.rs
@@ -2,10 +2,10 @@ use std::str::FromStr;
use cln_plugin::Plugin;
use cln_rpc::primitives::Sha256;
-use nostr::{nips::nip47, Timestamp};
+use nostr::{nips::nip47, types::Timestamp};
use crate::{
- hold::{invoice_request::Description, CancelRequest, InvoiceRequest, SettleRequest},
+ hold::{CancelRequest, InvoiceRequest, SettleRequest, invoice_request::Description},
nwc_notifications::holdinvoice_accepted_handler,
structs::PluginState,
};
@@ -66,7 +66,7 @@ async fn make_hold_invoice(
return Err(nip47::NIP47Error {
code: nip47::ErrorCode::Other,
message: "Could not convert description hash to bytes".to_owned(),
- })
+ });
}
};
Some(Description::Hash(desc_hash_bytes))
@@ -83,7 +83,7 @@ async fn make_hold_invoice(
return Err(nip47::NIP47Error {
code: nip47::ErrorCode::Other,
message: "Invalid payment hash".to_owned(),
- })
+ });
}
};
@@ -164,7 +164,7 @@ async fn cancel_hold_invoice(
return Err(nip47::NIP47Error {
code: nip47::ErrorCode::Other,
message: "Invalid payment hash".to_owned(),
- })
+ });
}
};
@@ -222,7 +222,7 @@ async fn settle_hold_invoice(
return Err(nip47::NIP47Error {
code: nip47::ErrorCode::Other,
message: "Invalid preimage".to_owned(),
- })
+ });
}
};
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index c75c079..a9dc343 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -16,7 +16,7 @@ use cln_rpc::{
},
primitives::Sha256,
};
-use nostr::{Timestamp, nips::nip47};
+use nostr::{nips::nip47, types::Timestamp};
use tonic::transport::Channel;
use crate::{
diff --git a/src/nwc_notifications.rs b/src/nwc_notifications.rs
index 164e246..04accbd 100644
--- a/src/nwc_notifications.rs
+++ b/src/nwc_notifications.rs
@@ -17,12 +17,9 @@ use cln_rpc::{
primitives::Sha256,
};
use nostr::{
- EventBuilder,
- Kind,
- Tag,
- Timestamp,
- event::FinalizeEventAsync,
+ event::{EventBuilder, FinalizeEventAsync, Kind, Tag},
nips::{nip04, nip44, nip47},
+ types::Timestamp,
};
use crate::{
diff --git a/src/rpc.rs b/src/rpc.rs
index 8b46ad0..fea29c7 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -6,7 +6,11 @@ use cln_rpc::model::requests::{
DeldatastoreRequest,
ListdatastoreRequest,
};
-use nostr::{Keys, SecretKey, Timestamp, nips::nip47::NostrWalletConnectUri};
+use nostr::{
+ key::{Keys, SecretKey},
+ nips::nip47::NostrWalletConnectUri,
+ types::Timestamp,
+};
use serde_json::json;
use crate::{
diff --git a/src/structs.rs b/src/structs.rs
index 8f3b86f..ff0ff59 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,8 +1,12 @@
use std::{collections::HashMap, path::PathBuf, str::FromStr, sync::Arc};
use cln_rpc::ClnRpc;
-use nostr::{nips::nip47::NostrWalletConnectUri, types::RelayUrl};
-use nostr_sdk::client;
+use nostr::{
+ key::{Keys, PublicKey},
+ nips::nip47::NostrWalletConnectUri,
+ types::RelayUrl,
+};
+use nostr_sdk::client::Client;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use tokio::sync::oneshot;
@@ -33,9 +37,9 @@ impl PluginState {
}
pub struct WalletService {
- pub client: client::Client,
- pub client_pubkey: nostr::PublicKey,
- pub wallet_secret: nostr::Keys,
+ pub client: Client,
+ pub client_pubkey: PublicKey,
+ pub wallet_secret: Keys,
}
#[derive(Clone, Debug)]
From f5b64586fc778027ef4f076c0ca9603656180bcc Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 14:36:42 +0200
Subject: [PATCH 26/56] tests: update to nostr sdk 0.45
---
tests/pyproject.toml | 2 +-
tests/test_cln-nip47.py | 333 +++++++++++++++++++---------------------
tests/uv.lock | 30 ++--
3 files changed, 176 insertions(+), 189 deletions(-)
diff --git a/tests/pyproject.toml b/tests/pyproject.toml
index 70483b9..bcde559 100644
--- a/tests/pyproject.toml
+++ b/tests/pyproject.toml
@@ -10,7 +10,7 @@ dev = [
"pytest-asyncio>=0.23.8,<2",
"pytest-xdist>=3.7,<4",
"pytest-timeout>=2.4,<3",
- "nostr-sdk>=0.44",
+ "nostr-sdk>=0.45",
"pyln-testing>=25.9",
"pyln-client>=25.9",
"pyln-proto>=25.9",
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
index 9b46a41..fbf4742 100644
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -18,7 +18,6 @@ from nostr_sdk import (
Event,
EventBuilder,
Filter,
- HandleNotification,
Keys,
KeysendTlvRecord,
Kind,
@@ -28,14 +27,14 @@ from nostr_sdk import (
Method,
NostrSdkError,
NostrSigner,
+ NostrWalletConnect,
NostrWalletConnectUri,
- Nwc,
PayInvoiceRequest,
PayKeysendRequest,
PublicKey,
RelayUrl,
+ ReqTarget,
Tag,
- TagKind,
TransactionType,
)
from pyln.testing.fixtures import *
@@ -45,23 +44,7 @@ from util import generate_random_label, get_hold, get_plugin # noqa: F401
LOGGER = logging.getLogger(__name__)
-class NotificationHandler(HandleNotification):
- def __init__(self, events_list, stop_after):
- self.events_list = events_list
- self.stop_after = stop_after
- self._done = asyncio.Event()
-
- async def handle(self, relay_url, subscription_id, event: Event):
- LOGGER.info(f"Received new event from {relay_url}: {event.as_json()}")
- self.events_list.append(event)
- if len(self.events_list) >= self.stop_after:
- self._done.set()
-
- async def handle_msg(self, relay_url, msg):
- _var = None
-
-
-Action = Union[
+Action = Union[ # noqa: UP007
Callable[[], Awaitable[None]],
Callable[[], None],
Awaitable[None],
@@ -78,15 +61,31 @@ async def fetch_event_responses(
) -> tuple[list[Event], Any]:
events = []
response_filter = Filter().kind(Kind(event_kind)).pubkey(client_pubkey)
+ target = ReqTarget.auto([response_filter])
- id = uuid.uuid4().hex
- LOGGER.info(f"Subscribing with id {id} to {response_filter}")
- await client.subscribe_with_id(id, response_filter)
+ subscription_id = uuid.uuid4().hex
+ LOGGER.info(f"Subscribing with id {subscription_id} to {response_filter}")
- handler = NotificationHandler(events, stop_after)
- task = asyncio.create_task(client.handle_notifications(handler))
+ await client.subscribe(target, subscription_id)
+
+ async def collect_events():
+ stream = client.notifications()
+
+ while len(events) < stop_after:
+ notification = await stream.next()
+
+ if notification.is_new_event():
+ event = notification.event
+ relay_url = notification.relay_url
+
+ LOGGER.info(f"Received new event from {relay_url}: {event.as_json()}")
+
+ events.append(event)
+
+ task = asyncio.create_task(collect_events())
await asyncio.sleep(1)
+
if inspect.iscoroutine(action):
action_result = await action
elif inspect.iscoroutinefunction(action):
@@ -97,10 +96,10 @@ async def fetch_event_responses(
raise TypeError("action must be a callable or an awaitable")
try:
- await asyncio.wait_for(handler._done.wait(), timeout=timeout)
+ await asyncio.wait_for(task, timeout=timeout)
except asyncio.TimeoutError:
print(
- f"Timeout reached after {timeout} seconds, collected {len(events)} events"
+ f"Timeout reached after {timeout} seconds, collected {len(events)} events",
)
finally:
task.cancel()
@@ -109,9 +108,10 @@ async def fetch_event_responses(
except asyncio.CancelledError:
pass
- await client.unsubscribe_all()
+ await client.unsubscribe_all()
+
assert len(events) == stop_after
- return (events, action_result)
+ return events, action_result
async def fetch_info_event(
@@ -119,20 +119,17 @@ async def fetch_info_event(
uri: NostrWalletConnectUri,
) -> Event:
response_filter = Filter().kind(Kind(13194)).author(uri.public_key())
- events = await client.fetch_events(
- response_filter, timeout=timedelta(seconds=TIMEOUT)
- )
+ target = ReqTarget.auto([response_filter])
+ events = await client.fetch_events(target, timeout=timedelta(seconds=TIMEOUT))
start_time = datetime.now()
- while events.len() < 1 and (datetime.now() - start_time) < timedelta(
+ while len(events) < 1 and (datetime.now() - start_time) < timedelta(
seconds=TIMEOUT
):
await asyncio.sleep(1)
- events = await client.fetch_events(
- response_filter, timeout=timedelta(seconds=1)
- )
- assert events.len() == 1
+ events = await client.fetch_events(target, timeout=timedelta(seconds=1))
+ assert len(events) == 1
- return events.first()
+ return events[0]
@pytest.mark.asyncio
@@ -155,38 +152,35 @@ async def test_get_balance(nostr_relay, node_factory, get_plugin): # noqa: F811
uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
balance = await nwc.get_balance()
- assert balance == 3000
+ assert balance.balance == 3000
uri_str = l1.rpc.call("nip47-create", ["test2"])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
balance = await nwc.get_balance()
- assert balance == node_balance
+ assert balance.balance == node_balance
uri_str = l1.rpc.call("nip47-create", ["test3", 0])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
balance = await nwc.get_balance()
- assert balance == 0
+ assert balance.balance == 0
with pytest.raises(RpcError, match="not an integer"):
uri_str = l1.rpc.call("nip47-create", ["test3", -1])["uri"]
@@ -207,24 +201,23 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
get_info = await nwc.get_info()
assert get_info.alias == node_get_info["alias"]
assert get_info.block_height == node_get_info["blockheight"]
assert get_info.color == node_get_info["color"]
assert get_info.methods == [
- Method.MAKE_INVOICE,
- Method.LOOKUP_INVOICE,
- Method.LIST_TRANSACTIONS,
- Method.GET_BALANCE,
- Method.GET_INFO,
- Method.PAY_INVOICE,
- Method.PAY_KEYSEND,
+ Method.MAKE_INVOICE(),
+ Method.LOOKUP_INVOICE(),
+ Method.LIST_TRANSACTIONS(),
+ Method.GET_BALANCE(),
+ Method.GET_INFO(),
+ Method.PAY_INVOICE(),
+ Method.PAY_KEYSEND(),
]
assert get_info.network == "regtest"
assert get_info.notifications == ["payment_received", "payment_sent"]
@@ -248,13 +241,13 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
assert get_info.block_height == node_get_info["blockheight"]
assert get_info.color == node_get_info["color"]
assert get_info.methods == [
- Method.MAKE_INVOICE,
- Method.LOOKUP_INVOICE,
- Method.LIST_TRANSACTIONS,
- Method.GET_BALANCE,
- Method.GET_INFO,
- Method.PAY_INVOICE,
- Method.PAY_KEYSEND,
+ Method.MAKE_INVOICE(),
+ Method.LOOKUP_INVOICE(),
+ Method.LIST_TRANSACTIONS(),
+ Method.GET_BALANCE(),
+ Method.GET_INFO(),
+ Method.PAY_INVOICE(),
+ Method.PAY_KEYSEND(),
]
assert get_info.network == "regtest"
assert get_info.notifications == []
@@ -264,28 +257,27 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
info_event.content()
== "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice pay_keysend"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
- == "nip44_v2 nip04"
+ encryption_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "encryption"
)
- assert info_event.tags().find(TagKind.UNKNOWN("notifications")) is None
+ assert encryption_tag.content() == "nip44_v2 nip04"
+ assert not any(tag.kind() == "notifications" for tag in info_event.tags())
uri_str = l1.rpc.call("nip47-create", ["test2", 0])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
get_info = await nwc.get_info()
assert get_info.methods == [
- Method.MAKE_INVOICE,
- Method.LOOKUP_INVOICE,
- Method.LIST_TRANSACTIONS,
- Method.GET_BALANCE,
- Method.GET_INFO,
+ Method.MAKE_INVOICE(),
+ Method.LOOKUP_INVOICE(),
+ Method.LIST_TRANSACTIONS(),
+ Method.GET_BALANCE(),
+ Method.GET_INFO(),
]
info_event = await fetch_info_event(client, uri)
@@ -293,11 +285,11 @@ async def test_get_info(nostr_relay, node_factory, get_plugin): # noqa: F811
info_event.content()
== "make_invoice lookup_invoice list_transactions get_balance get_info"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
- == "nip44_v2 nip04"
+ encryption_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "encryption"
)
- assert info_event.tags().find(TagKind.UNKNOWN("notifications")) is None
+ assert encryption_tag.content() == "nip44_v2 nip04"
+ assert not any(tag.kind() == "notifications" for tag in info_event.tags())
@pytest.mark.asyncio
@@ -314,12 +306,11 @@ async def test_make_invoice(nostr_relay, node_factory, get_plugin): # noqa: F81
uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
timestamp = int(time.time())
invoice = await nwc.make_invoice(
MakeInvoiceRequest(
@@ -407,12 +398,11 @@ async def test_pay_keysend(nostr_relay, node_factory, get_plugin): # noqa: F811
uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
result = await nwc.pay_keysend(
PayKeysendRequest(
id="id123", amount=1000, pubkey=l3.info["id"], preimage=None, tlv_records=[]
@@ -488,12 +478,11 @@ async def test_lookup_invoice(nostr_relay, node_factory, get_plugin): # noqa: F
uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
invoice = await nwc.make_invoice(
MakeInvoiceRequest(
amount=3000, description="test1", description_hash=None, expiry=None
@@ -715,12 +704,11 @@ async def test_list_transactions(nostr_relay, node_factory, get_plugin): # noqa
uri_str = l1.rpc.call("nip47-create", ["test1"])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
for i in range(10):
invoice = l2.rpc.call(
"invoice",
@@ -803,12 +791,12 @@ async def test_notifications(nostr_relay, node_factory, get_plugin): # noqa: F8
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ keys = Keys(uri.secret())
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
invoice = l3.rpc.call(
"invoice",
@@ -870,11 +858,10 @@ async def test_notifications(nostr_relay, node_factory, get_plugin): # noqa: F8
responses = responses1 + responses2
LOGGER.info(f"response1: {responses1} response2: {responses2}")
assert len(responses) == 2
- signer = NostrSigner.keys(Keys(uri.secret()))
received_events = []
sent_events = []
for event in responses:
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if content["notification_type"] == "payment_received":
@@ -973,8 +960,7 @@ async def test_pay_invoice(nostr_relay, node_factory, get_plugin): # noqa: F811
)
uri_str = l1.rpc.call("nip47-create", ["test1", 3001])["uri"]
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
@@ -983,7 +969,7 @@ async def test_pay_invoice(nostr_relay, node_factory, get_plugin): # noqa: F811
"invoice",
{"label": generate_random_label(), "description": "test1", "amount_msat": 3000},
)
- nwc = Nwc(NostrWalletConnectUri.parse(uri_str))
+ nwc = NostrWalletConnect(NostrWalletConnectUri.parse(uri_str))
result = await nwc.pay_invoice(
PayInvoiceRequest(id=None, amount=None, invoice=invoice["bolt11"])
)
@@ -1041,12 +1027,11 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
l1.daemon.wait_for_log("All NWC's loaded")
await asyncio.sleep(3)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
result = await nwc.pay_invoice(
PayInvoiceRequest(id=None, amount=None, invoice=invoice["bolt11"])
)
@@ -1082,12 +1067,11 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
uri_str = l1.rpc.call("nip47-create", ["test1", 3000, "10sec"])["uri"]
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
invoice = l2.rpc.call(
"invoice",
@@ -1179,14 +1163,13 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
{"label": generate_random_label(), "description": "test1", "amount_msat": 5000},
)
uri = NostrWalletConnectUri.parse(uri_str)
- signer = NostrSigner.keys(Keys(uri.secret()))
- client = Client(signer)
+ client = Client()
await client.add_relay(RelayUrl.parse(url))
await client.connect()
await fetch_info_event(client, uri)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
balance = await nwc.get_balance()
- assert balance == 3000
+ assert balance.balance == 3000
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
await nwc.pay_invoice(
@@ -1195,7 +1178,7 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
l1.rpc.call("nip47-budget", ["test1", 4000])
balance = await nwc.get_balance()
- assert balance == 4000
+ assert balance.balance == 4000
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
await nwc.pay_invoice(
@@ -1204,7 +1187,7 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
l1.rpc.call("nip47-budget", ["test1", 5000, "15s"])
balance = await nwc.get_balance()
- assert balance == 5000
+ assert balance.balance == 5000
with pytest.raises(
RpcError, match="`budget_msat` must be greater than 0 if you use `interval`"
@@ -1217,17 +1200,17 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
assert pay.preimage is not None
balance = await nwc.get_balance()
- assert balance == 0
+ assert balance.balance == 0
get_info = await nwc.get_info()
assert get_info.methods == [
- Method.MAKE_INVOICE,
- Method.LOOKUP_INVOICE,
- Method.LIST_TRANSACTIONS,
- Method.GET_BALANCE,
- Method.GET_INFO,
- Method.PAY_INVOICE,
- Method.PAY_KEYSEND,
+ Method.MAKE_INVOICE(),
+ Method.LOOKUP_INVOICE(),
+ Method.LIST_TRANSACTIONS(),
+ Method.GET_BALANCE(),
+ Method.GET_INFO(),
+ Method.PAY_INVOICE(),
+ Method.PAY_KEYSEND(),
]
info_event = await fetch_info_event(client, uri)
@@ -1236,31 +1219,31 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
info_event.content()
== "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice pay_keysend notifications"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
- == "nip44_v2 nip04"
+ encryption_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "encryption"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("notifications")).content()
- == "payment_received payment_sent"
+ assert encryption_tag.content() == "nip44_v2 nip04"
+ notification_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "notifications"
)
+ assert notification_tag.content() == "payment_received payment_sent"
await asyncio.sleep(18)
balance = await nwc.get_balance()
- assert balance == 5000
+ assert balance.balance == 5000
l1.rpc.call("nip47-budget", ["test1", 0])
balance = await nwc.get_balance()
- assert balance == 0
+ assert balance.balance == 0
get_info = await nwc.get_info()
assert get_info.methods == [
- Method.MAKE_INVOICE,
- Method.LOOKUP_INVOICE,
- Method.LIST_TRANSACTIONS,
- Method.GET_BALANCE,
- Method.GET_INFO,
+ Method.MAKE_INVOICE(),
+ Method.LOOKUP_INVOICE(),
+ Method.LIST_TRANSACTIONS(),
+ Method.GET_BALANCE(),
+ Method.GET_INFO(),
]
info_event = await fetch_info_event(client, uri)
@@ -1268,14 +1251,14 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
info_event.content()
== "make_invoice lookup_invoice list_transactions get_balance get_info notifications"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
- == "nip44_v2 nip04"
+ encryption_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "encryption"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("notifications")).content()
- == "payment_received payment_sent"
+ assert encryption_tag.content() == "nip44_v2 nip04"
+ notification_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "notifications"
)
+ assert notification_tag.content() == "payment_received payment_sent"
@pytest.mark.asyncio
@@ -1311,7 +1294,7 @@ async def test_hold_invoice(
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
preimage = secrets.token_hex(32)
payment_hash = hashlib.sha256(bytes.fromhex(preimage)).hexdigest()
@@ -1325,14 +1308,14 @@ async def test_hold_invoice(
},
}
content = json.dumps(content)
- signer = NostrSigner.keys(Keys(uri.secret()))
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ keys = Keys(uri.secret())
+ encrypted_content = keys.nip04_encrypt(uri.public_key(), content)
event = (
await EventBuilder(Kind(23194), encrypted_content)
.tags([Tag.public_key(uri.public_key())])
- .sign(signer)
+ .finalize_async(keys)
)
- client = Client(signer)
+ client = Client()
relay_url = RelayUrl.parse(url)
await client.add_relay(relay_url)
await client.connect()
@@ -1346,7 +1329,7 @@ async def test_hold_invoice(
success_events = []
for event in responses1:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if "result" in content and content["result"] is not None:
@@ -1403,7 +1386,7 @@ async def test_hold_invoice(
hold_events = []
for event in responses2:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if content["notification_type"] == "hold_invoice_accepted":
@@ -1427,7 +1410,7 @@ async def test_hold_invoice(
assert lookup_hold.preimage is None
assert lookup_hold.payment_hash == payment_hash
assert lookup_hold.transaction_type.name == "INCOMING"
- assert lookup_hold.state.name == "PENDING" # TODO ACCEPTED STATE
+ assert lookup_hold.state.name == "ACCEPTED"
assert lookup_hold.settled_at is None
content = {
@@ -1437,11 +1420,11 @@ async def test_hold_invoice(
},
}
content = json.dumps(content)
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ encrypted_content = keys.nip04_encrypt(uri.public_key(), content)
event = (
await EventBuilder(Kind(23194), encrypted_content)
.tags([Tag.public_key(uri.public_key())])
- .sign(signer)
+ .finalize_async(keys)
)
(responses3, _res) = await fetch_event_responses(
@@ -1451,7 +1434,7 @@ async def test_hold_invoice(
success_events = []
for event in responses3:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if (
@@ -1509,12 +1492,11 @@ async def test_hold_invoice(
},
}
content = json.dumps(content)
- signer = NostrSigner.keys(Keys(uri.secret()))
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ encrypted_content = keys.nip04_encrypt(uri.public_key(), content)
event = (
await EventBuilder(Kind(23194), encrypted_content)
.tags([Tag.public_key(uri.public_key())])
- .sign(signer)
+ .finalize_async(keys)
)
(responses4, _res) = await fetch_event_responses(
@@ -1524,7 +1506,7 @@ async def test_hold_invoice(
success_events = []
for event in responses4:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if (
@@ -1558,7 +1540,7 @@ async def test_hold_invoice(
hold_events = []
for event in responses5:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if (
@@ -1575,11 +1557,11 @@ async def test_hold_invoice(
},
}
content = json.dumps(content)
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ encrypted_content = keys.nip04_encrypt(uri.public_key(), content)
event = (
await EventBuilder(Kind(23194), encrypted_content)
.tags([Tag.public_key(uri.public_key())])
- .sign(signer)
+ .finalize_async(keys)
)
(responses6, _res) = await fetch_event_responses(
@@ -1593,7 +1575,7 @@ async def test_hold_invoice(
success_events = []
for event in responses6:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if (
@@ -1639,7 +1621,7 @@ async def test_hold_invoice(
)
)
- nwc = Nwc(uri)
+ nwc = NostrWalletConnect(uri)
invoice_lookup1 = await nwc.lookup_invoice(
LookupInvoiceRequest(
@@ -1699,11 +1681,11 @@ async def test_hold_invoice(
},
}
content = json.dumps(content)
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ encrypted_content = keys.nip04_encrypt(uri.public_key(), content)
event = (
await EventBuilder(Kind(23194), encrypted_content)
.tags([Tag.public_key(uri.public_key())])
- .sign(signer)
+ .finalize_async(keys)
)
await client.send_event(event)
@@ -1718,7 +1700,8 @@ async def test_hold_invoice(
)
)
break
- except Exception:
+ except Exception as e: # noqa: BLE001
+ LOGGER.error(e)
continue
lookup_hold = await nwc.lookup_invoice(
@@ -1750,11 +1733,11 @@ async def test_hold_invoice(
},
}
content = json.dumps(content)
- encrypted_content = await signer.nip04_encrypt(uri.public_key(), content)
+ encrypted_content = keys.nip04_encrypt(uri.public_key(), content)
event = (
await EventBuilder(Kind(23194), encrypted_content)
.tags([Tag.public_key(uri.public_key())])
- .sign(signer)
+ .finalize_async(keys)
)
await client.send_event(event)
@@ -1769,7 +1752,8 @@ async def test_hold_invoice(
)
)
break
- except Exception:
+ except Exception as e: # noqa: BLE001
+ LOGGER.error(e)
continue
lookup_hold = await nwc.lookup_invoice(
@@ -1793,12 +1777,15 @@ async def test_hold_invoice(
info_event.content()
== "make_invoice lookup_invoice list_transactions get_balance get_info pay_invoice pay_keysend make_hold_invoice cancel_hold_invoice settle_hold_invoice notifications"
)
- assert (
- info_event.tags().find(TagKind.UNKNOWN("encryption")).content()
- == "nip44_v2 nip04"
+ encryption_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "encryption"
+ )
+ assert encryption_tag.content() == "nip44_v2 nip04"
+ notification_tag = next(
+ tag for tag in info_event.tags() if tag.kind() == "notifications"
)
assert (
- info_event.tags().find(TagKind.UNKNOWN("notifications")).content()
+ notification_tag.content()
== "payment_received payment_sent hold_invoice_accepted"
)
@@ -1816,7 +1803,7 @@ async def test_hold_invoice(
hold_events = []
for event in responses7:
LOGGER.info(event)
- content = await signer.nip04_decrypt(uri.public_key(), event.content())
+ content = keys.nip04_decrypt(uri.public_key(), event.content())
content = json.loads(content)
LOGGER.info(content)
if (
diff --git a/tests/uv.lock b/tests/uv.lock
index d90c9ac..c2c260e 100644
--- a/tests/uv.lock
+++ b/tests/uv.lock
@@ -393,7 +393,7 @@ dev = [
[package.metadata.requires-dev]
dev = [
- { name = "nostr-sdk", specifier = ">=0.44" },
+ { name = "nostr-sdk", specifier = ">=0.45" },
{ name = "pyln-client", specifier = ">=25.9" },
{ name = "pyln-proto", specifier = ">=25.9" },
{ name = "pyln-testing", specifier = ">=25.9" },
@@ -748,22 +748,22 @@ wheels = [
[[package]]
name = "nostr-sdk"
-version = "0.44.6"
+version = "0.45.0"
source = { registry = "https://pypi.org/simple" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/61/c3/1fbcb47aff23b368b817e5f6e90f3284b4b299e9bcf08e9a4cd414b80020/nostr_sdk-0.44.6-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:41dabb2539513db0b354c4fd2a3391307e50eb913a60c9325b1565e80e98530f", size = 3365132, upload-time = "2026-07-26T09:02:22.234Z" },
- { url = "https://files.pythonhosted.org/packages/43/08/16525328d477e1fb427d47c0ccc14ce5b25f120871947374457a3267ae99/nostr_sdk-0.44.6-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:326526e6fd736c4dd6ad73b5cf7653d1a0ae46a3fb8d8ed4b4cb221ee64f7feb", size = 3482251, upload-time = "2026-07-26T09:02:23.623Z" },
- { url = "https://files.pythonhosted.org/packages/65/a4/0f210f8490faf4c24dbc4bfbdc1943afc632d907c6fae48f88f0f3b55605/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:811637b021cfa338a38e37dda8df5dbeebe447458d567ad9b700a65199f6874c", size = 3611794, upload-time = "2026-07-26T09:02:24.758Z" },
- { url = "https://files.pythonhosted.org/packages/f2/73/ce525eed5f93969c62984f9397c80acf99883eab52bc055259e189eb1375/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:44cbec5c99a8a8c8e8beeb80ae7427a3ff20b943ca459bd0ba556e41c20dd246", size = 3359056, upload-time = "2026-07-26T09:02:26.101Z" },
- { url = "https://files.pythonhosted.org/packages/c9/ad/f700ddbbfcf2d0ff2285dec9b87b8b290d1f4359add21cb09b568bf52c0f/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_i686.whl", hash = "sha256:64e0304313bbbaa05226d9cac98618f94ab20e8e3f5e3a297179454e657d3446", size = 3607461, upload-time = "2026-07-26T09:02:27.393Z" },
- { url = "https://files.pythonhosted.org/packages/c9/ec/947f9fd4161a69da12bdbb8502a377c5ada2ab8e640ce5515c4a001cf81f/nostr_sdk-0.44.6-cp39-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:0234eae16b0fc11e3d72eb08c4c14b0c333a992e700d8fb88f191a42ef017a07", size = 3726683, upload-time = "2026-07-26T09:02:28.925Z" },
- { url = "https://files.pythonhosted.org/packages/01/fe/448443ef9e23433f202c0362c2eb9e1b98dc0efffb5c3f9cae6f6252a5a8/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d16adc26a42cab37ae4ae8e3a8bed03dcedbe88c7862133c48cf9d99cb9e0cf3", size = 3605361, upload-time = "2026-07-26T09:02:30.308Z" },
- { url = "https://files.pythonhosted.org/packages/df/02/b0e83f3f5066e525e5c1fd44c81f6711479cc6942aee298ebcd545fb3e59/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:dccebbc33500718ace5cf8e7ac6ed7fa41ec07f65f157896b392ac5f0b9ab2ed", size = 3360640, upload-time = "2026-07-26T09:02:31.615Z" },
- { url = "https://files.pythonhosted.org/packages/9e/01/7104eacda8609d52a148171354bca1095227a651860022984bf518ead1f2/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:e73a55e1f52dd4cb006f502725e65ab12b68609cb1b18d96b2ba74a3b245d264", size = 3493797, upload-time = "2026-07-26T09:02:32.973Z" },
- { url = "https://files.pythonhosted.org/packages/00/80/e8de31cf0f1cf4c65ca5691a6c8baabbed19daccdccb427d73968e0335b9/nostr_sdk-0.44.6-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:512229272a68cc651bbe96b1d0ec78d12b899708d871ef92b49ce96eb33ba1fd", size = 3724890, upload-time = "2026-07-26T09:02:34.219Z" },
- { url = "https://files.pythonhosted.org/packages/83/0f/6d4c364bd4f1ad1c76030aeddc43c5f6edd63d79cec289229de6afa5a72d/nostr_sdk-0.44.6-cp39-abi3-win32.whl", hash = "sha256:5eee3919224b653007e71a8e8a43465ee36156132839dfd15c120ee9b54d075c", size = 3164542, upload-time = "2026-07-26T09:02:35.291Z" },
- { url = "https://files.pythonhosted.org/packages/90/f5/11141f5612f8fb361d39dbb95d6ec916059213a8d5625f8f98b58a7cfc70/nostr_sdk-0.44.6-cp39-abi3-win_amd64.whl", hash = "sha256:f89a13a4cec623283cd66218b8efedc8ec618b1b3e33a0e398240469f7b317e6", size = 3383380, upload-time = "2026-07-26T09:02:36.804Z" },
- { url = "https://files.pythonhosted.org/packages/d0/3e/552318b5c8307ab2f725de59b9bedbd06df3f031c252d11b15dcea302511/nostr_sdk-0.44.6-cp39-abi3-win_arm64.whl", hash = "sha256:c36845d218118dc0330f554fdea5c6e0c4a73bc54cb74dcf628750bf9260e01f", size = 3236001, upload-time = "2026-07-26T09:02:37.906Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/73/9401a17b0a43bf22542f31e5c5624db7f838f7690977ec786edd72b0880b/nostr_sdk-0.45.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:5bd1a6b972e9f5ae8c4f4448a148f668f124a3389b72eafb9de00f714e829059", size = 3835872, upload-time = "2026-08-05T13:14:21.43Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/5d/355adf2a676493101357080857cf7896880c6556fe84795281bc283513c5/nostr_sdk-0.45.0-cp39-abi3-macosx_11_0_x86_64.whl", hash = "sha256:a20cb90f4fa225e57118431fc05d1d567a78a047dab54d34897365fcc5b82498", size = 3901388, upload-time = "2026-08-05T13:14:22.92Z" },
+ { url = "https://files.pythonhosted.org/packages/a1/72/489cd53d491afe180f71d24c4f4f334f6da38d1bf683e8907771f436bffd/nostr_sdk-0.45.0-cp39-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:00da5e7e387515d1e12779eccfb2c794856f774b4534694200434aa0146a03ed", size = 4323888, upload-time = "2026-08-05T13:14:24.348Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/cb/9a5edbea9db9995704ebc44ec4fca153c5f7d9ea07d668cf7837f01ddf1e/nostr_sdk-0.45.0-cp39-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:e5cae5ef56411d6665de78c39822a4e80382231d44b4a6fc3db096b8b203ec26", size = 3867750, upload-time = "2026-08-05T13:14:26.066Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/d3/1a464004596e9ea0366a62e1671fc41adefde97b477bf60e69615dedec64/nostr_sdk-0.45.0-cp39-abi3-manylinux_2_17_i686.whl", hash = "sha256:9d91d519a93c48ab4d689f975f406d8ee96e39d6876d2aeaaee58de7e66ded93", size = 4393993, upload-time = "2026-08-05T13:14:27.766Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/57/1684e67051af3540666e6aeba4ed5bc9ea027cbe311789dce79863c85b48/nostr_sdk-0.45.0-cp39-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:8152945cb27b48bbf6f89d73d8560bfbadd202b8e5c165bf5b5532e91feed417", size = 4426295, upload-time = "2026-08-05T13:14:29.397Z" },
+ { url = "https://files.pythonhosted.org/packages/34/b0/526e134d23e2bdbac523bb38351d940a478cc2d7499c0ee9d1ee499ecfb4/nostr_sdk-0.45.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a7e0a886b427356dc94cd0b1bc8421b01eeb5aa9ea26e1b69c21f0a3cc1bc2ad", size = 4336015, upload-time = "2026-08-05T13:14:30.836Z" },
+ { url = "https://files.pythonhosted.org/packages/70/27/764af3a4bc1ec8542401616f11c41bbf9c42fbaef8659bf26bab4097ed6f/nostr_sdk-0.45.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:3b314b5160014bf70b39e95b3cf5cb059050e2fc2f782a0d9916c7ae1559e34f", size = 3864414, upload-time = "2026-08-05T13:14:32.352Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/31/1289150239dfce59c1c2afb8313dfd21411040103c68e6121f1ba4515fb7/nostr_sdk-0.45.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:15346b498f4df4bb42ef2987cecd9e97ba60294b9bc7bb486e1c4b6bee4f528e", size = 4205457, upload-time = "2026-08-05T13:14:33.858Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/63/3964d86ed2f36f691374813751fb342de0c169ea0d926609379e50fd761c/nostr_sdk-0.45.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:78ccdb4766ae627ac9e2c10a7bb224d1e00da48fc7b61c7f48935ae23241fd64", size = 4410510, upload-time = "2026-08-05T13:14:35.224Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/15/a9c8da6d37bbbbfe07cba889a3d149f030985e524758ba51b44ca7a29ca0/nostr_sdk-0.45.0-cp39-abi3-win32.whl", hash = "sha256:45ff1ae2f19fedfa9f91b0c81c1be755b706e2fd1e7865ea46612c2ad1d98a3e", size = 3549588, upload-time = "2026-08-05T13:14:36.642Z" },
+ { url = "https://files.pythonhosted.org/packages/99/f0/e03b7abb4dc016ea19dc2f311f367e472df47c187fbb69cee6df3ed2f323/nostr_sdk-0.45.0-cp39-abi3-win_amd64.whl", hash = "sha256:b3904abc4d7e4ac46ed66c8aa528e89748f3f25023708e4bbab58bc81d3a99f7", size = 3870530, upload-time = "2026-08-05T13:14:38.079Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/d0/f80080bd2aa73ed25c7a9d8d21020fc73eaa10591b39e13ec2b88228a8ce/nostr_sdk-0.45.0-cp39-abi3-win_arm64.whl", hash = "sha256:5a0fc63b69995bf2dac44e479aaec1ce1af71e687c9f4258891e429ed3db25e5", size = 3704095, upload-time = "2026-08-05T13:14:39.494Z" },
]
[[package]]
From 5c65a94c138265cb107ecf46bacdd77f8d4141bf Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 15:01:17 +0200
Subject: [PATCH 27/56] add retry logic for hold server connect
---
src/main.rs | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index f80d21a..c8136fa 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -285,11 +285,30 @@ async fn check_hold_support(plugin: Plugin) -> Result<(), anyhow::E
.identity(identity)
.domain_name("hold");
- let hold_channel = Endpoint::from_shared(format!("https://{hold_grpc_host}:{hold_grpc_port}"))?
+ let endpoint = Endpoint::from_shared(format!("https://{hold_grpc_host}:{hold_grpc_port}"))?
.tls_config(tls_config)?
.keep_alive_while_idle(true)
- .connect_lazy();
- *plugin.state().hold_client.lock() = Some(HoldClient::new(hold_channel));
+ .connect_timeout(Duration::from_secs(5));
+
+ let max_retries = 20;
+
+ let channel = loop {
+ match endpoint.connect().await {
+ Ok(channel) => break channel,
+ Err(e) if retries < max_retries => {
+ retries += 1;
+
+ log::debug!("Hold gRPC server not ready, retrying ({retries}/{max_retries}): {e}");
+
+ time::sleep(Duration::from_millis(500)).await;
+ }
+ Err(e) => {
+ return Err(anyhow!("Hold gRPC server did not become ready: {e}"));
+ }
+ }
+ };
+
+ *plugin.state().hold_client.lock() = Some(HoldClient::new(channel));
Ok(())
}
From 18c00d3442ac58184c1cfef526553f7e5054f5cf Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 15:08:16 +0200
Subject: [PATCH 28/56] SECURITY.md: init
---
SECURITY.md | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 SECURITY.md
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..9b5fbd8
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,27 @@
+# Security Policy
+
+## Supported Versions
+
+Only the latest version is supported.
+
+## Reporting a Vulnerability
+
+To report security vulnerabilities, please send an email to:
+- `daywalker990@gmx.de`
+
+Note: This email address is exclusively for vulnerability reporting.
+
+For all other inquiries/communication, please use the Github issues.
+
+## Signatures For Releases
+
+The following keys may be used to communicate sensitive information to
+developers:
+
+| Name | Email | Fingerprint |
+|------|-------|-------------|
+| daywalker90 | `daywalker990@gmx.de` | 8A07 9421 A871 D0B1 0835 1193 7AB4 802E D5A6 39F3 |
+
+You can import a key by running the following command with that individual’s fingerprint:
+`gpg --keyserver hkps://keys.openpgp.org --recv-keys ""`.
+Ensure that you put quotes around fingerprints containing spaces.
From 07bf8288f5ab2e72ad56d4f1e278eabcb34c76b0 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 8 Aug 2026 13:10:06 +0000
Subject: [PATCH 29/56] Bump actions/checkout from 6 to 7
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-version: '7'
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/ci.yml | 2 +-
.github/workflows/release.yml | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cac47ea..82b3448 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -40,7 +40,7 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Create cache paths
run: |
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6fef945..39f2ae2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -13,7 +13,7 @@ jobs:
rust-version: ${{ steps.versions.outputs.rust-version }}
steps:
- name: Checkout code
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
@@ -57,7 +57,7 @@ jobs:
macos-deployment-target: ${{ steps.build.outputs.macos-deployment-target }}
steps:
- name: Checkout code
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
@@ -135,7 +135,7 @@ jobs:
id: tag_name
run: echo "current_version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"
- name: Checkout code
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Get Changelog Entry
id: changelog_reader
uses: mindsers/changelog-reader-action@v2
From 0a078e0b76e5c7aa9c4816133688a381ff8af17e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 8 Aug 2026 13:10:20 +0000
Subject: [PATCH 30/56] Bump actions/cache from 5 to 6
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)
---
updated-dependencies:
- dependency-name: actions/cache
dependency-version: '6'
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/ci.yml | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 82b3448..b4b6a60 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -66,7 +66,7 @@ jobs:
- name: Restore CLN cache
id: cache-cln
- uses: actions/cache/restore@v5
+ uses: actions/cache/restore@v6
with:
path: |
/usr/local/bin/lightning*
@@ -75,7 +75,7 @@ jobs:
- name: Restore bitcoind cache
id: cache-bitcoind
- uses: actions/cache/restore@v5
+ uses: actions/cache/restore@v6
with:
path: /usr/local/bin/bitcoin*
key: cache-bitcoind-${{ matrix.bitcoind-version }}-${{ steps.exact_versions.outputs.os_version }}
@@ -99,7 +99,7 @@ jobs:
- name: Save bitcoind cache
id: save-cache-bitcoind
if : ${{ success() && steps.cache-bitcoind.outputs.cache-hit != 'true'}}
- uses: actions/cache/save@v5
+ uses: actions/cache/save@v6
with:
path: /usr/local/bin/bitcoin*
key: ${{ steps.cache-bitcoind.outputs.cache-primary-key }}
@@ -117,7 +117,7 @@ jobs:
- name: Save CLN cache
id: save-cache-cln
if : ${{ success() && steps.cache-cln.outputs.cache-hit != 'true' }}
- uses: actions/cache/save@v5
+ uses: actions/cache/save@v6
with:
path: |
/usr/local/bin/lightning*
From 66edfb7c5e4bc2e7574dd876be560f220f9b6823 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 8 Aug 2026 13:10:42 +0000
Subject: [PATCH 31/56] Bump actions/setup-python from 6 to 7
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v6...v7)
---
updated-dependencies:
- dependency-name: actions/setup-python
dependency-version: '7'
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/ci.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b4b6a60..71402f9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -50,7 +50,7 @@ jobs:
sudo chown -R $USER /usr/local/libexec
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v6
+ uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
From 76f10bc2c5ffbb44f91fe2d89782c49336d99fde Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 15:11:01 +0200
Subject: [PATCH 32/56] README: update CLN version
---
README.md | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
index eb2425b..59a8fe2 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,4 @@
From 6ff3069fa84a3faf8a69d6dedfba66dec8a8079d Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 15:14:39 +0200
Subject: [PATCH 33/56] README: update binaries notes
---
README.md | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 59a8fe2..2927042 100644
--- a/README.md
+++ b/README.md
@@ -64,11 +64,10 @@ Release binaries for
* x86_64-linux
* armv7-linux (Raspberry Pi 32bit)
* aarch64-linux (Raspberry Pi 64bit)
+* universal-apple-darwin (macOS)
can be found on the [release](https://github.com/daywalker90/cln-nip47/releases) page. If you are unsure about your architecture you can run ``uname -m``.
-They require ``glibc>=2.31``, which you can check with ``ldd --version``.
-
# Building
You can build the plugin yourself instead of using the release binaries.
First clone the repo:
@@ -85,7 +84,7 @@ cargo build --release
After that the binary will be here: ``target/release/cln-nip47``
-Note: Release binaries are built using ``cross`` and the ``optimized`` profile.
+Note: Release binaries are built with the ``optimized`` profile.
# Documentation
From 408b015d91305198772f4a0b3e0cfcda29415406 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 17:12:48 +0200
Subject: [PATCH 34/56] improve handling of stale or duplicate events
---
src/main.rs | 10 +++++
src/nwc.rs | 94 +++++++++++++++++++++++++++--------------
src/structs.rs | 2 +
src/tasks.rs | 46 ++++++++++++++++++--
src/util.rs | 23 ++++++++--
tests/test_cln-nip47.py | 1 -
6 files changed, 137 insertions(+), 39 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index c8136fa..b88c6e3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -157,6 +157,16 @@ async fn main() -> Result<(), anyhow::Error> {
}
}
+ let plugin_clone_cleanup = plugin.clone();
+ tokio::spawn(async move {
+ loop {
+ if let Err(e) = tasks::cleanup_event_ids(plugin_clone_cleanup.clone()).await {
+ log::warn!("Error in cleanup_event_ids thread: {e}");
+ }
+ time::sleep(Duration::from_secs(10)).await;
+ }
+ });
+
plugin.join().await
}
diff --git a/src/nwc.rs b/src/nwc.rs
index 68a1597..9677fa6 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -31,9 +31,9 @@ use crate::{
nwc_keysend::pay_keysend_response,
nwc_lookups::{list_transactions_response, lookup_invoice_response},
nwc_pay::pay_invoice_response,
- structs::{NwcStore, PluginState, WalletService},
+ structs::{ID_MAX_AGE, NwcStore, PluginState, WalletService},
tasks::budget_task,
- util::{build_capabilities, build_notifications_vec, is_read_only_nwc},
+ util::{build_capabilities, build_notifications_vec, is_read_only_nwc, save_event_id},
};
#[allow(clippy::too_many_lines)]
@@ -225,6 +225,7 @@ pub fn stop_nwc_budget_job(plugin: &Plugin, label: &String) {
}
}
+#[allow(clippy::too_many_lines)]
async fn nwc_request_handler(
notification: ClientNotification,
nostr_client: &client::Client,
@@ -246,44 +247,73 @@ async fn nwc_request_handler(
| ClientNotification::Shutdown => return Ok(()),
};
- if let Some(expi) = event.tags.expiration() {
- if expi < Timestamp::now() {
- return Ok(());
- }
- }
log::debug!("relay_url:{relay_url} subscription_id:{subscription_id} {event:?}");
let mut use_nip44 = check_nip44_support(&event);
let request = decrypt_request(&event.content, wallet_keys, &client_pubkey, &mut use_nip44)?;
- let responses = match request.params {
- nip47::RequestParams::PayInvoice(pay_invoice_request) => {
- pay_invoice_response(plugin.clone(), pay_invoice_request, label).await
+ let responses = if event.tags.expiration().is_some()
+ && event.tags.expiration().unwrap() < Timestamp::now()
+ {
+ vec![(
+ nip47::Response {
+ result_type: request.method,
+ error: Some(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Event expired".to_owned(),
+ }),
+ result: None,
+ },
+ None,
+ )]
+ } else if event.created_at.as_secs() < (Timestamp::now().as_secs() - ID_MAX_AGE) {
+ vec![(
+ nip47::Response {
+ result_type: request.method,
+ error: Some(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Event created too far in the past".to_owned(),
+ }),
+ result: None,
+ },
+ None,
+ )]
+ } else {
+ {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+ save_event_id(&mut rpc, event.id.to_hex(), event.created_at).await?;
}
- nip47::RequestParams::PayKeysend(pay_keysend_request) => {
- pay_keysend_response(plugin.clone(), pay_keysend_request, label).await
- }
- nip47::RequestParams::MakeInvoice(make_invoice_request) => {
- make_invoice_response(plugin.clone(), make_invoice_request).await
- }
- nip47::RequestParams::LookupInvoice(lookup_invoice_request) => {
- lookup_invoice_response(plugin.clone(), lookup_invoice_request).await
- }
- nip47::RequestParams::ListTransactions(list_transactions_request) => {
- list_transactions_response(plugin.clone(), list_transactions_request).await
- }
- nip47::RequestParams::GetBalance => get_balance_response(plugin.clone(), label).await,
- nip47::RequestParams::GetInfo => get_info_response(plugin.clone(), label).await,
- nip47::RequestParams::MakeHoldInvoice(make_hold_invoice_request) => {
- make_hold_invoice_response(plugin.clone(), make_hold_invoice_request).await
- }
- nip47::RequestParams::CancelHoldInvoice(cancel_hold_invoice_request) => {
- cancel_hold_invoice_response(plugin.clone(), cancel_hold_invoice_request).await
- }
- nip47::RequestParams::SettleHoldInvoice(settle_hold_invoice_request) => {
- settle_hold_invoice_response(plugin.clone(), settle_hold_invoice_request).await
+
+ match request.params {
+ nip47::RequestParams::PayInvoice(pay_invoice_request) => {
+ pay_invoice_response(plugin.clone(), pay_invoice_request, label).await
+ }
+ nip47::RequestParams::PayKeysend(pay_keysend_request) => {
+ pay_keysend_response(plugin.clone(), pay_keysend_request, label).await
+ }
+ nip47::RequestParams::MakeInvoice(make_invoice_request) => {
+ make_invoice_response(plugin.clone(), make_invoice_request).await
+ }
+ nip47::RequestParams::LookupInvoice(lookup_invoice_request) => {
+ lookup_invoice_response(plugin.clone(), lookup_invoice_request).await
+ }
+ nip47::RequestParams::ListTransactions(list_transactions_request) => {
+ list_transactions_response(plugin.clone(), list_transactions_request).await
+ }
+ nip47::RequestParams::GetBalance => get_balance_response(plugin.clone(), label).await,
+ nip47::RequestParams::GetInfo => get_info_response(plugin.clone(), label).await,
+ nip47::RequestParams::MakeHoldInvoice(make_hold_invoice_request) => {
+ make_hold_invoice_response(plugin.clone(), make_hold_invoice_request).await
+ }
+ nip47::RequestParams::CancelHoldInvoice(cancel_hold_invoice_request) => {
+ cancel_hold_invoice_response(plugin.clone(), cancel_hold_invoice_request).await
+ }
+ nip47::RequestParams::SettleHoldInvoice(settle_hold_invoice_request) => {
+ settle_hold_invoice_response(plugin.clone(), settle_hold_invoice_request).await
+ }
}
};
+
for (response, id) in responses {
let content =
match encrypt_response_content(&response, wallet_keys, &client_pubkey, use_nip44) {
diff --git a/src/structs.rs b/src/structs.rs
index ff0ff59..a60c49a 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -15,6 +15,8 @@ use tonic::transport::Channel;
use crate::hold::hold_client::HoldClient;
pub const NOT_INV_ERR: &str = "Not an invoice or invalid invoice";
+pub const ID_STORE: &str = "eventids";
+pub const ID_MAX_AGE: u64 = 7_200;
#[derive(Clone)]
pub struct PluginState {
diff --git a/src/tasks.rs b/src/tasks.rs
index e46ed40..3427834 100644
--- a/src/tasks.rs
+++ b/src/tasks.rs
@@ -1,13 +1,17 @@
-use std::{path::Path, time::Duration};
+use std::{path::Path, str::FromStr, time::Duration};
use anyhow::anyhow;
use cln_plugin::Plugin;
-use cln_rpc::ClnRpc;
+use cln_rpc::{
+ ClnRpc,
+ model::requests::{DeldatastoreRequest, ListdatastoreRequest},
+};
use nostr::types::Timestamp;
use tokio::{sync::oneshot, time};
use crate::{
- structs::PluginState,
+ PLUGIN_NAME,
+ structs::{ID_MAX_AGE, ID_STORE, PluginState},
util::{load_nwc_store, update_nwc_store},
};
@@ -57,3 +61,39 @@ pub async fn budget_task(
}
Ok(())
}
+
+pub async fn cleanup_event_ids(plugin: Plugin) -> Result<(), anyhow::Error> {
+ let mut rpc = ClnRpc::new(
+ Path::new(&plugin.configuration().lightning_dir).join(&plugin.configuration().rpc_file),
+ )
+ .await?;
+
+ loop {
+ {
+ let ids = rpc
+ .call_typed(&ListdatastoreRequest {
+ key: Some(vec![format!("{}-{}", PLUGIN_NAME, ID_STORE)]),
+ })
+ .await?
+ .datastore;
+
+ let now = Timestamp::now();
+ for id in ids {
+ if id.string.is_none() {
+ continue;
+ }
+ let timestamp = Timestamp::from_str(&id.string.unwrap())?;
+ if now.as_secs() - timestamp.as_secs() > ID_MAX_AGE {
+ rpc.call_typed(&DeldatastoreRequest {
+ generation: None,
+ key: id.key.clone(),
+ })
+ .await?;
+ log::debug!("Cleaned up event id: {}", id.key.last().unwrap());
+ }
+ }
+ }
+
+ tokio::time::sleep(Duration::from_secs(120)).await;
+ }
+}
diff --git a/src/util.rs b/src/util.rs
index 6d769ad..f6064f7 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -1,13 +1,12 @@
use anyhow::anyhow;
use cln_plugin::Plugin;
use cln_rpc::{
- model::requests::{DatastoreMode, DatastoreRequest, ListdatastoreRequest},
ClnRpc,
+ model::requests::{DatastoreMode, DatastoreRequest, ListdatastoreRequest},
};
-use nostr::nips::nip47;
+use nostr::{nips::nip47, types::Timestamp};
use crate::{
- structs::{NwcStore, PluginState},
OPT_NOTIFICATIONS,
PLUGIN_NAME,
WALLET_HOLD_METHODS,
@@ -15,6 +14,7 @@ use crate::{
WALLET_NOTIFICATIONS,
WALLET_PAY_METHODS,
WALLET_READ_METHODS,
+ structs::{ID_STORE, NwcStore, PluginState},
};
pub fn budget_amount_check(
@@ -97,6 +97,23 @@ pub fn is_read_only_nwc(nwc_store: &NwcStore) -> bool {
false
}
+pub async fn save_event_id(
+ rpc: &mut ClnRpc,
+ id: String,
+ timestamp: Timestamp,
+) -> Result<(), anyhow::Error> {
+ rpc.call_typed(&DatastoreRequest {
+ key: vec![format!("{}-{}", PLUGIN_NAME, ID_STORE), id.clone()],
+ generation: None,
+ hex: None,
+ mode: Some(DatastoreMode::MUST_CREATE),
+ string: Some(timestamp.to_string()),
+ })
+ .await?;
+ log::debug!("stored event id:{id}");
+ Ok(())
+}
+
pub fn at_or_above_version(my_version: &str, min_version: &str) -> Result {
let clean_start_my_version = my_version
.split_once('v')
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
index fbf4742..7e055ec 100644
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -26,7 +26,6 @@ from nostr_sdk import (
MakeInvoiceRequest,
Method,
NostrSdkError,
- NostrSigner,
NostrWalletConnect,
NostrWalletConnectUri,
PayInvoiceRequest,
From 651b11b229df231a9122f3c89832939f16532588 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sat, 8 Aug 2026 17:17:08 +0200
Subject: [PATCH 35/56] return error on unsupported invoice type lookup for
holdinvoices
---
src/nwc_lookups.rs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index a9dc343..32fe39e 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -288,7 +288,12 @@ async fn get_and_decode_holdinvoice(
let ph = match invoice_decoded.item_type {
DecodeType::BOLT12_INVOICE => invoice_decoded.invoice_payment_hash.unwrap(),
DecodeType::BOLT11_INVOICE => invoice_decoded.payment_hash.unwrap().to_string(),
- _ => todo!(),
+ _ => {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: "Not a supported invoice type".to_owned(),
+ });
+ }
};
let payment_hash_hash = match hex::decode(&ph) {
Ok(p) => p,
From b2078bab813e00e6e90c01ad22daf264ecaf94bd Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 9 Aug 2026 00:13:06 +0200
Subject: [PATCH 36/56] remove budget task, update budget on demand
---
src/nwc.rs | 21 +---------
src/nwc_balance.rs | 7 +++-
src/nwc_keysend.rs | 19 ++++++---
src/nwc_pay.rs | 38 +++++++++++-------
src/parse.rs | 4 +-
src/rpc.rs | 24 +++++++-----
src/structs.rs | 4 +-
src/tasks.rs | 50 ------------------------
src/util.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 157 insertions(+), 106 deletions(-)
diff --git a/src/nwc.rs b/src/nwc.rs
index 9677fa6..c761614 100644
--- a/src/nwc.rs
+++ b/src/nwc.rs
@@ -15,7 +15,7 @@ use nostr_sdk::{
error::Error,
relay::RelayStatus,
};
-use tokio::{sync::oneshot, time};
+use tokio::time;
use crate::{
OPT_NOTIFICATIONS,
@@ -32,7 +32,6 @@ use crate::{
nwc_lookups::{list_transactions_response, lookup_invoice_response},
nwc_pay::pay_invoice_response,
structs::{ID_MAX_AGE, NwcStore, PluginState, WalletService},
- tasks::budget_task,
util::{build_capabilities, build_notifications_vec, is_read_only_nwc, save_event_id},
};
@@ -57,7 +56,7 @@ pub async fn run_nwc(
}
if nwc_store.interval_config.is_some() {
- start_nwc_budget_job(&plugin, label.clone());
+ log::debug!("NWC {label} uses an interval budget");
}
let nostr_client_clone = nostr_client.clone();
@@ -207,22 +206,6 @@ pub async fn stop_nwc(plugin: Plugin, label: &String) {
if let Some(wallet_service) = locked_handles.remove(label) {
wallet_service.client.shutdown().await;
}
-
- stop_nwc_budget_job(&plugin, label);
-}
-
-pub fn start_nwc_budget_job(plugin: &Plugin, label: String) {
- let (tx, rx) = oneshot::channel::<()>();
- tokio::spawn(budget_task(rx, plugin.clone(), label.clone()));
- plugin.state().budget_jobs.lock().insert(label, tx);
-}
-
-pub fn stop_nwc_budget_job(plugin: &Plugin, label: &String) {
- let mut budget_jobs = plugin.state().budget_jobs.lock();
- let job = budget_jobs.remove(label);
- if let Some(j) = job {
- let _ = j.send(());
- }
}
#[allow(clippy::too_many_lines)]
diff --git a/src/nwc_balance.rs b/src/nwc_balance.rs
index 1c3c1ea..2fde546 100644
--- a/src/nwc_balance.rs
+++ b/src/nwc_balance.rs
@@ -2,7 +2,10 @@ use cln_plugin::Plugin;
use cln_rpc::{model::requests::ListpeerchannelsRequest, primitives::ChannelState};
use nostr::nips::nip47;
-use crate::{structs::PluginState, util::load_nwc_store};
+use crate::{
+ structs::PluginState,
+ util::{get_budget_msat, load_nwc_store},
+};
pub async fn get_balance_response(
plugin: Plugin,
@@ -40,7 +43,7 @@ async fn get_balance(
message: e.to_string(),
})?;
- let balance = if let Some(bdgt_amt) = nwc_store.budget_msat {
+ let balance = if let Some(bdgt_amt) = get_budget_msat(&nwc_store) {
bdgt_amt
} else {
let listpeerchannels = rpc
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index dc1ee5e..c53c88d 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -10,7 +10,14 @@ use nostr::nips::nip47::{self};
use crate::{
structs::{NwcStore, PluginState},
- util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
+ util::{
+ at_or_above_version,
+ budget_amount_check,
+ get_budget_msat,
+ load_nwc_store,
+ update_budget_msat,
+ update_nwc_store,
+ },
};
pub async fn pay_keysend_response(
@@ -65,7 +72,7 @@ async fn pay_keysend(
message: e.to_string(),
})?;
- budget_amount_check(Some(params.amount), None, nwc_store.budget_msat).map_err(|e| {
+ budget_amount_check(Some(params.amount), None, get_budget_msat(&nwc_store)).map_err(|e| {
nip47::NIP47Error {
code: nip47::ErrorCode::QuotaExceeded,
message: e.to_string(),
@@ -120,8 +127,8 @@ async fn xkeysend(
.await
{
Ok(o) => {
- if let Some(ref mut bdg) = nwc_store.budget_msat {
- *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
+ if nwc_store.budget_msat.is_some() {
+ update_budget_msat(&mut nwc_store, o.amount_sent_msat.msat());
update_nwc_store(rpc, label, nwc_store)
.await
.map_err(|e| nip47::NIP47Error {
@@ -200,8 +207,8 @@ async fn keysend(
.await
{
Ok(o) => {
- if let Some(ref mut bdg) = nwc_store.budget_msat {
- *bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
+ if nwc_store.budget_msat.is_some() {
+ update_budget_msat(&mut nwc_store, o.amount_sent_msat.msat());
update_nwc_store(rpc, label, nwc_store)
.await
.map_err(|e| nip47::NIP47Error {
diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs
index 4f4e859..d41210b 100644
--- a/src/nwc_pay.rs
+++ b/src/nwc_pay.rs
@@ -12,7 +12,14 @@ use nostr::nips::nip47;
use crate::{
structs::{NOT_INV_ERR, NwcStore, PluginState},
- util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
+ util::{
+ at_or_above_version,
+ budget_amount_check,
+ get_budget_msat,
+ load_nwc_store,
+ update_budget_msat,
+ update_nwc_store,
+ },
};
pub async fn pay_invoice_response(
@@ -172,17 +179,20 @@ async fn load_nwc_and_check_budget(
)
})?;
- budget_amount_check(params.amount, Some(invoice_amt_msat), nwc_store.budget_msat).map_err(
- |e| {
- (
- nip47::NIP47Error {
- code: nip47::ErrorCode::QuotaExceeded,
- message: e.to_string(),
- },
- Some(id.to_owned()),
- )
- },
- )?;
+ budget_amount_check(
+ params.amount,
+ Some(invoice_amt_msat),
+ get_budget_msat(&nwc_store),
+ )
+ .map_err(|e| {
+ (
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::QuotaExceeded,
+ message: e.to_string(),
+ },
+ Some(id.to_owned()),
+ )
+ })?;
Ok(nwc_store)
}
@@ -211,8 +221,8 @@ async fn update_budget_and_create_response(
preimage: Secret,
id: &str,
) -> Result<(nip47::PayInvoiceResponse, Option), (nip47::NIP47Error, Option)> {
- if let Some(ref mut bdg) = nwc_store.budget_msat {
- *bdg = bdg.saturating_sub(amount_sent_msat);
+ if nwc_store.budget_msat.is_some() {
+ update_budget_msat(nwc_store, amount_sent_msat);
update_nwc_store(rpc, label, nwc_store.clone())
.await
.map_err(|e| {
diff --git a/src/parse.rs b/src/parse.rs
index b1dffed..efd1e36 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -2,12 +2,12 @@ use std::path::Path;
use anyhow::anyhow;
use cln_plugin::ConfiguredPlugin;
-use cln_rpc::{model::requests::GetinfoRequest, ClnRpc};
+use cln_rpc::{ClnRpc, model::requests::GetinfoRequest};
use nostr::types::RelayUrl;
use crate::{
- structs::{PluginState, TimeUnit},
OPT_RELAYS,
+ structs::{PluginState, TimeUnit},
};
pub async fn read_startup_options(
diff --git a/src/rpc.rs b/src/rpc.rs
index fea29c7..1aba835 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -15,10 +15,16 @@ use serde_json::json;
use crate::{
PLUGIN_NAME,
- nwc::{run_nwc, send_nwc_info_event, start_nwc_budget_job, stop_nwc, stop_nwc_budget_job},
+ nwc::{run_nwc, send_nwc_info_event, stop_nwc},
parse::parse_time_period,
structs::{BudgetIntervalConfig, NwcStore, PluginState},
- util::{build_capabilities, is_read_only_nwc, load_nwc_store, update_nwc_store},
+ util::{
+ build_capabilities,
+ get_budget_msat,
+ is_read_only_nwc,
+ load_nwc_store,
+ update_nwc_store,
+ },
};
pub async fn nwc_create(
@@ -62,6 +68,7 @@ pub async fn nwc_create(
interval_secs: interval,
reset_budget_msat: bgt_msat,
last_reset: Timestamp::now().as_secs(),
+ spend_since_last_reset: 0,
};
result.insert("interval_config".to_owned(), serde_json::to_value(&conf)?);
Some(conf)
@@ -119,8 +126,6 @@ pub async fn nwc_budget(
let (label, budget_msat, interval_secs) = parse_full_args(args)?;
- stop_nwc_budget_job(&plugin, &label);
-
let mut nwc_store = load_nwc_store(&mut rpc, &label).await?;
let is_old_nwc_read_only = is_read_only_nwc(&nwc_store);
@@ -132,6 +137,7 @@ pub async fn nwc_budget(
interval_secs: interval,
reset_budget_msat: budget,
last_reset: Timestamp::now().as_secs(),
+ spend_since_last_reset: 0,
};
nwc_store.interval_config = Some(interval_config.clone());
} else {
@@ -146,10 +152,6 @@ pub async fn nwc_budget(
update_nwc_store(&mut rpc, &label, nwc_store.clone()).await?;
- if nwc_store.interval_config.is_some() {
- start_nwc_budget_job(&plugin, label.clone());
- }
-
if is_old_nwc_read_only != is_new_nwc_read_only {
let wallet_keys = Keys::new(SecretKey::from_hex(&nwc_store.walletkey)?);
let (method_capabilities, _) = build_capabilities(is_new_nwc_read_only, &plugin);
@@ -181,7 +183,8 @@ pub async fn nwc_list(
let mut nwcs = Vec::new();
if let Some(lbl) = label {
- let nwc_store = load_nwc_store(&mut rpc, &lbl).await?;
+ let mut nwc_store = load_nwc_store(&mut rpc, &lbl).await?;
+ nwc_store.budget_msat = get_budget_msat(&nwc_store);
let wallet_key = Keys::new(SecretKey::from_hex(&nwc_store.walletkey)?);
let client_key = Keys::new(nwc_store.uri.secret.clone());
let mut nwc_json = json!(nwc_store);
@@ -206,7 +209,8 @@ pub async fn nwc_list(
for datastore in all_stored_nwcs {
let label = datastore.key.last().unwrap().to_owned();
- let nwc_store = load_nwc_store(&mut rpc, &label).await?;
+ let mut nwc_store = load_nwc_store(&mut rpc, &label).await?;
+ nwc_store.budget_msat = get_budget_msat(&nwc_store);
let wallet_key = Keys::new(SecretKey::from_hex(&nwc_store.walletkey)?);
let client_key = Keys::new(nwc_store.uri.secret.clone());
let mut nwc_json = json!(nwc_store);
diff --git a/src/structs.rs b/src/structs.rs
index a60c49a..6018153 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -9,7 +9,6 @@ use nostr::{
use nostr_sdk::client::Client;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
-use tokio::sync::oneshot;
use tonic::transport::Channel;
use crate::hold::hold_client::HoldClient;
@@ -23,7 +22,6 @@ pub struct PluginState {
pub config: Arc>,
pub handles: Arc>>,
pub rpc_lock: Arc>,
- pub budget_jobs: Arc>>>,
pub hold_client: Arc>>>,
}
impl PluginState {
@@ -32,7 +30,6 @@ impl PluginState {
config: Arc::new(Mutex::new(Config::default())),
handles: Arc::new(tokio::sync::Mutex::new(HashMap::new())),
rpc_lock: Arc::new(tokio::sync::Mutex::new(ClnRpc::new(path).await?)),
- budget_jobs: Arc::new(Mutex::new(HashMap::new())),
hold_client: Arc::new(Mutex::new(None)),
})
}
@@ -86,6 +83,7 @@ pub struct BudgetIntervalConfig {
pub interval_secs: u64,
pub reset_budget_msat: u64,
pub last_reset: u64,
+ pub spend_since_last_reset: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/src/tasks.rs b/src/tasks.rs
index 3427834..42c9c61 100644
--- a/src/tasks.rs
+++ b/src/tasks.rs
@@ -1,67 +1,17 @@
use std::{path::Path, str::FromStr, time::Duration};
-use anyhow::anyhow;
use cln_plugin::Plugin;
use cln_rpc::{
ClnRpc,
model::requests::{DeldatastoreRequest, ListdatastoreRequest},
};
use nostr::types::Timestamp;
-use tokio::{sync::oneshot, time};
use crate::{
PLUGIN_NAME,
structs::{ID_MAX_AGE, ID_STORE, PluginState},
- util::{load_nwc_store, update_nwc_store},
};
-pub async fn budget_task(
- mut rx: oneshot::Receiver<()>,
- plugin: Plugin,
- label: String,
-) -> Result<(), anyhow::Error> {
- let mut rpc = ClnRpc::new(
- Path::new(&plugin.configuration().lightning_dir).join(&plugin.configuration().rpc_file),
- )
- .await?;
- loop {
- let mut nwc_store = load_nwc_store(&mut rpc, &label).await?;
- let interval_config = nwc_store
- .interval_config
- .as_mut()
- .ok_or_else(|| anyhow!("interval_config disappeared!"))?;
- let now = Timestamp::now().as_secs();
- log::debug!(
- "interval:{} now:{} prev:{}",
- interval_config.interval_secs,
- now,
- interval_config.last_reset
- );
- let next_reset = std::cmp::max(
- interval_config
- .interval_secs
- .saturating_sub(now.saturating_sub(interval_config.last_reset)),
- 1,
- );
- tokio::select! {
- _ = &mut rx => {
- log::info!("Stopping budget task for {label}");
- break;
- }
- () = time::sleep(Duration::from_secs(next_reset)) => {
- log::info!("Refreshing budget for {label}");
- *nwc_store.budget_msat
- .as_mut()
- .ok_or_else(||anyhow!("budget_msat missing"))? = interval_config.reset_budget_msat;
- interval_config.last_reset = Timestamp::now().as_secs();
- update_nwc_store(&mut rpc, &label, nwc_store).await?;
- log::info!("Done refreshing budget for {label}");
- }
- }
- }
- Ok(())
-}
-
pub async fn cleanup_event_ids(plugin: Plugin) -> Result<(), anyhow::Error> {
let mut rpc = ClnRpc::new(
Path::new(&plugin.configuration().lightning_dir).join(&plugin.configuration().rpc_file),
diff --git a/src/util.rs b/src/util.rs
index f6064f7..2012e6c 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -17,6 +17,46 @@ use crate::{
structs::{ID_STORE, NwcStore, PluginState},
};
+pub fn get_budget_msat(nwc_store: &NwcStore) -> Option {
+ match nwc_store.budget_msat {
+ Some(b) => {
+ if let Some(conf) = &nwc_store.interval_config {
+ let now = Timestamp::now().as_secs();
+ let spend = if now.saturating_sub(conf.last_reset) >= conf.interval_secs {
+ 0
+ } else {
+ conf.spend_since_last_reset
+ };
+ Some(conf.reset_budget_msat.saturating_sub(spend))
+ } else {
+ Some(b)
+ }
+ }
+ None => None,
+ }
+}
+
+pub fn update_budget_msat(nwc_store: &mut NwcStore, amount_spent_msat: u64) {
+ if let Some(bdg) = nwc_store.budget_msat.as_mut() {
+ if let Some(conf) = nwc_store.interval_config.as_mut() {
+ let now = Timestamp::now().as_secs();
+ if now.saturating_sub(conf.last_reset) >= conf.interval_secs {
+ conf.last_reset = now;
+ conf.spend_since_last_reset = amount_spent_msat;
+ } else {
+ conf.spend_since_last_reset = conf
+ .spend_since_last_reset
+ .saturating_add(amount_spent_msat);
+ }
+ *bdg = conf
+ .reset_budget_msat
+ .saturating_sub(conf.spend_since_last_reset);
+ } else {
+ *bdg = bdg.saturating_sub(amount_spent_msat);
+ }
+ }
+}
+
pub fn budget_amount_check(
request_amt_msat: Option,
invoice_amt_msat: Option,
@@ -224,3 +264,59 @@ fn test_budget_check() {
assert!(budget_amount_check(Some(0), Some(0), Some(1)).is_ok());
assert!(budget_amount_check(Some(0), Some(0), Some(0)).is_ok());
}
+
+#[test]
+fn test_budget_interval_helpers() {
+ use crate::structs::BudgetIntervalConfig;
+
+ let now = Timestamp::now().as_secs();
+ let conf = BudgetIntervalConfig {
+ interval_secs: 10,
+ reset_budget_msat: 1000,
+ last_reset: now,
+ spend_since_last_reset: 0,
+ };
+ let mut store = NwcStore {
+ uri: nostr::nips::nip47::NostrWalletConnectUri::new(
+ nostr::key::Keys::generate().public_key(),
+ vec![],
+ nostr::key::Keys::generate().secret_key().clone(),
+ None,
+ ),
+ walletkey: "test".to_owned(),
+ budget_msat: Some(1000),
+ interval_config: Some(conf),
+ };
+
+ assert_eq!(get_budget_msat(&store), Some(1000));
+
+ update_budget_msat(&mut store, 300);
+ assert_eq!(
+ store
+ .interval_config
+ .as_ref()
+ .unwrap()
+ .spend_since_last_reset,
+ 300
+ );
+ assert_eq!(get_budget_msat(&store), Some(700));
+
+ update_budget_msat(&mut store, 500);
+ assert_eq!(get_budget_msat(&store), Some(200));
+
+ store.interval_config.as_mut().unwrap().last_reset = now.saturating_sub(20);
+ let old_last_reset = store.interval_config.as_ref().unwrap().last_reset;
+ assert_eq!(get_budget_msat(&store), Some(1000));
+
+ update_budget_msat(&mut store, 400);
+ assert!(store.interval_config.as_ref().unwrap().last_reset > old_last_reset);
+ assert_eq!(
+ store
+ .interval_config
+ .as_ref()
+ .unwrap()
+ .spend_since_last_reset,
+ 400
+ );
+ assert_eq!(get_budget_msat(&store), Some(600));
+}
From f79db424cd12d38a96a8178ce902f25abac994b8 Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 9 Aug 2026 01:38:27 +0200
Subject: [PATCH 37/56] determine available methods from help rpc isntead of
version string
---
src/nwc_keysend.rs | 10 +++-------
src/nwc_pay.rs | 23 +++--------------------
src/parse.rs | 35 +++++++++++++++++++++++++++++++----
src/structs.rs | 13 ++++++++++---
src/util.rs | 28 ----------------------------
5 files changed, 47 insertions(+), 62 deletions(-)
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index c53c88d..1ef56f3 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -11,7 +11,6 @@ use nostr::nips::nip47::{self};
use crate::{
structs::{NwcStore, PluginState},
util::{
- at_or_above_version,
budget_amount_check,
get_budget_msat,
load_nwc_store,
@@ -20,6 +19,8 @@ use crate::{
},
};
+pub const XKEYSEND_COMMAND: &str = "xkeysend";
+
pub async fn pay_keysend_response(
plugin: Plugin,
params: nip47::PayKeysendRequest,
@@ -84,12 +85,7 @@ async fn pay_keysend(
message: e.to_string(),
})?;
- let my_cln_version = plugin.state().config.lock().my_cln_version.clone();
-
- if at_or_above_version(&my_cln_version, "26.06").map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: e.to_string(),
- })? {
+ if plugin.state().config.lock().has_xkeysend {
xkeysend(&mut rpc, params, pubkey, nwc_store, label).await
} else {
keysend(&mut rpc, params, pubkey, nwc_store, label).await
diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs
index d41210b..ffc348a 100644
--- a/src/nwc_pay.rs
+++ b/src/nwc_pay.rs
@@ -13,7 +13,6 @@ use nostr::nips::nip47;
use crate::{
structs::{NOT_INV_ERR, NwcStore, PluginState},
util::{
- at_or_above_version,
budget_amount_check,
get_budget_msat,
load_nwc_store,
@@ -22,6 +21,8 @@ use crate::{
},
};
+pub const XPAY_COMMAND: &str = "xpay";
+
pub async fn pay_invoice_response(
plugin: Plugin,
params: nip47::PayInvoiceRequest,
@@ -63,10 +64,7 @@ async fn pay_invoice(
let nwc_store =
load_nwc_and_check_budget(&mut rpc, label, ¶ms, invoice_amt_msat, &id).await?;
- let my_version = plugin.state().config.lock().clone().my_cln_version;
- let use_xpay = check_cln_version(&my_version, &id)?;
-
- if use_xpay {
+ if plugin.state().config.lock().has_xpay {
pay_with_xpay_full(&mut rpc, params, label, nwc_store, &id).await
} else {
pay_with_legacy_full(&mut rpc, params, label, nwc_store, &id).await
@@ -197,21 +195,6 @@ async fn load_nwc_and_check_budget(
Ok(nwc_store)
}
-fn check_cln_version(
- my_version: &str,
- id: &str,
-) -> Result)> {
- at_or_above_version(my_version, "24.11").map_err(|e| {
- (
- nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- },
- Some(id.to_owned()),
- )
- })
-}
-
async fn update_budget_and_create_response(
rpc: &mut ClnRpc,
label: &str,
diff --git a/src/parse.rs b/src/parse.rs
index efd1e36..1589944 100644
--- a/src/parse.rs
+++ b/src/parse.rs
@@ -1,12 +1,14 @@
-use std::path::Path;
+use std::{collections::HashSet, path::Path};
use anyhow::anyhow;
use cln_plugin::ConfiguredPlugin;
-use cln_rpc::{ClnRpc, model::requests::GetinfoRequest};
+use cln_rpc::{ClnRpc, model::requests::HelpRequest};
use nostr::types::RelayUrl;
use crate::{
OPT_RELAYS,
+ nwc_keysend::XKEYSEND_COMMAND,
+ nwc_pay::XPAY_COMMAND,
structs::{PluginState, TimeUnit},
};
@@ -33,9 +35,34 @@ pub async fn read_startup_options(
Path::new(&plugin.configuration().lightning_dir).join(&plugin.configuration().rpc_file),
)
.await?;
- let version = rpc.call_typed(&GetinfoRequest {}).await?.version;
+ let help = rpc.call_typed(&HelpRequest { command: None }).await?;
+
let mut config = state.config.lock();
- config.my_cln_version = version;
+
+ let mut available_commands = HashSet::new();
+ for command in &help.help {
+ if let Some(method) = command.command.split_ascii_whitespace().next() {
+ available_commands.insert(method);
+ }
+ }
+
+ log::debug!(
+ "Found {} commands available: {}",
+ available_commands.len(),
+ available_commands
+ .iter()
+ .copied()
+ .collect::>()
+ .join(" ")
+ );
+
+ config.has_xkeysend = available_commands.contains(XKEYSEND_COMMAND);
+ config.has_xpay = available_commands.contains(XPAY_COMMAND);
+ log::debug!(
+ "Using xpay:{} xkeysend:{}",
+ config.has_xpay,
+ config.has_xkeysend
+ );
for relay in relays_str {
log::debug!("RELAY:{relay}");
config.relays.push(RelayUrl::parse(&relay)?);
diff --git a/src/structs.rs b/src/structs.rs
index 6018153..1ebfb85 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,4 +1,9 @@
-use std::{collections::HashMap, path::PathBuf, str::FromStr, sync::Arc};
+use std::{
+ collections::{HashMap, HashSet},
+ path::PathBuf,
+ str::FromStr,
+ sync::Arc,
+};
use cln_rpc::ClnRpc;
use nostr::{
@@ -44,13 +49,15 @@ pub struct WalletService {
#[derive(Clone, Debug)]
pub struct Config {
pub relays: Vec,
- pub my_cln_version: String,
+ pub has_xkeysend: bool,
+ pub has_xpay: bool,
}
impl Config {
pub fn default() -> Config {
Config {
relays: Vec::new(),
- my_cln_version: String::new(),
+ has_xkeysend: false,
+ has_xpay: false,
}
}
}
diff --git a/src/util.rs b/src/util.rs
index 2012e6c..20fa53f 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -154,34 +154,6 @@ pub async fn save_event_id(
Ok(())
}
-pub fn at_or_above_version(my_version: &str, min_version: &str) -> Result {
- let clean_start_my_version = my_version
- .split_once('v')
- .ok_or_else(|| anyhow!("Could not find v in version string"))?
- .1;
- let full_clean_my_version: String = clean_start_my_version
- .chars()
- .take_while(|x| x.is_ascii_digit() || *x == '.')
- .collect();
-
- let my_version_parts: Vec<&str> = full_clean_my_version.split('.').collect();
- let min_version_parts: Vec<&str> = min_version.split('.').collect();
-
- if my_version_parts.len() <= 1 || my_version_parts.len() > 3 {
- return Err(anyhow!("Version string parse error: {my_version}"));
- }
- for (my, min) in my_version_parts.iter().zip(min_version_parts.iter()) {
- let my_num: u32 = my.parse()?;
- let min_num: u32 = min.parse()?;
-
- if my_num != min_num {
- return Ok(my_num > min_num);
- }
- }
-
- Ok(my_version_parts.len() >= min_version_parts.len())
-}
-
pub fn build_capabilities(is_read_only: bool, plugin: &Plugin) -> (String, String) {
let holdinvoice_support = plugin.state().hold_client.lock().is_some();
From c1bb7606cfa5662de65d56bd13517c6d0a5fc0aa Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 9 Aug 2026 12:12:32 +0200
Subject: [PATCH 38/56] reserve budget during in-flight payments, drop lock
while paying
---
src/main.rs | 11 ++
src/nwc_keysend.rs | 258 ++++++++++++++++++++++------------------
src/nwc_pay.rs | 205 ++++++++++++++++---------------
src/rpc.rs | 1 +
src/structs.rs | 10 +-
src/util.rs | 134 ++++++++++++++++++++-
tests/test_cln-nip47.py | 47 +++++---
7 files changed, 425 insertions(+), 241 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index b88c6e3..10c925c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -200,6 +200,17 @@ async fn load_nwcs(plugin: Plugin, rpc: &mut ClnRpc) -> Result<(),
}
}
+ // We don't keep track of inflight payments succeeding
+ // while the plugin is dynamically restarted
+ if nwc_store.reserved_msat != 0 {
+ log::warn!(
+ "Releasing {} msat leftover budget reservation for {label}",
+ nwc_store.reserved_msat
+ );
+ nwc_store.reserved_msat = 0;
+ update_nwc_store(rpc, label, nwc_store.clone()).await?;
+ }
+
run_nwc(plugin.clone(), label.clone(), nwc_store.clone()).await?;
}
Ok(())
diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs
index 1ef56f3..8cc8f39 100644
--- a/src/nwc_keysend.rs
+++ b/src/nwc_keysend.rs
@@ -3,19 +3,23 @@ use std::{collections::HashMap, str::FromStr};
use cln_plugin::Plugin;
use cln_rpc::{
ClnRpc,
+ RpcError,
model::requests::{KeysendRequest, XkeysendRequest},
- primitives::{Amount, PublicKey, TlvEntry, TlvStream},
+ primitives::{Amount, PublicKey, Secret, TlvEntry, TlvStream},
};
use nostr::nips::nip47::{self};
use crate::{
- structs::{NwcStore, PluginState},
+ structs::PluginState,
util::{
budget_amount_check,
get_budget_msat,
load_nwc_store,
- update_budget_msat,
- update_nwc_store,
+ payment_fee_reserve_msat,
+ refund_budget,
+ reserve_budget,
+ rpc_socket_path,
+ settle_budget,
},
};
@@ -57,8 +61,6 @@ async fn pay_keysend(
params: nip47::PayKeysendRequest,
label: &str,
) -> Result {
- let mut rpc = plugin.state().rpc_lock.lock().await;
-
if params.preimage.is_some() {
return Err(nip47::NIP47Error {
code: nip47::ErrorCode::Other,
@@ -66,42 +68,99 @@ async fn pay_keysend(
});
}
- let nwc_store = load_nwc_store(&mut rpc, label)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
-
- budget_amount_check(Some(params.amount), None, get_budget_msat(&nwc_store)).map_err(|e| {
- nip47::NIP47Error {
- code: nip47::ErrorCode::QuotaExceeded,
- message: e.to_string(),
- }
- })?;
-
let pubkey = PublicKey::from_str(¶ms.pubkey).map_err(|e| nip47::NIP47Error {
code: nip47::ErrorCode::Other,
message: e.to_string(),
})?;
- if plugin.state().config.lock().has_xkeysend {
- xkeysend(&mut rpc, params, pubkey, nwc_store, label).await
+ let reservation = {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+
+ let nwc_store = load_nwc_store(&mut rpc, label)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?;
+
+ budget_amount_check(Some(params.amount), None, get_budget_msat(&nwc_store)).map_err(
+ |e| nip47::NIP47Error {
+ code: nip47::ErrorCode::QuotaExceeded,
+ message: e.to_string(),
+ },
+ )?;
+
+ // Reserve amount plus worst case fee so concurrent payments can never
+ // exceed the budget.
+ if get_budget_msat(&nwc_store).unwrap_or(u64::MAX)
+ < params
+ .amount
+ .saturating_add(payment_fee_reserve_msat(params.amount))
+ {
+ return Err(nip47::NIP47Error {
+ code: nip47::ErrorCode::QuotaExceeded,
+ message: "Payment and estimated fees exceed the available budget".to_owned(),
+ });
+ }
+
+ reserve_budget(&mut rpc, label, &nwc_store, params.amount)
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ })?
+ };
+
+ let has_xkeysend = plugin.state().config.lock().has_xkeysend;
+ let mut pay_rpc =
+ ClnRpc::new(rpc_socket_path(&plugin))
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: format!("Could not connect to lightningd: {e}"),
+ })?;
+
+ let pay_result = if has_xkeysend {
+ xkeysend(&mut pay_rpc, ¶ms, pubkey).await
} else {
- keysend(&mut rpc, params, pubkey, nwc_store, label).await
+ keysend(&mut pay_rpc, ¶ms, pubkey).await
+ };
+
+ match pay_result {
+ Ok((amount_sent_msat, amount_msat, preimage)) => {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+ if let Err(e) = settle_budget(&mut rpc, label, reservation, amount_sent_msat).await {
+ log::error!("Error updating budget after successful keysend: {e}");
+ }
+
+ let preimage = hex::encode(preimage.to_vec());
+ let fees_paid = amount_sent_msat.saturating_sub(amount_msat);
+
+ Ok(nip47::PayKeysendResponse {
+ preimage,
+ fees_paid: Some(fees_paid),
+ })
+ }
+ Err(e) => {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+ if let Err(refund_err) = refund_budget(&mut rpc, label, reservation).await {
+ log::error!(
+ "Error refunding budget reservation after failed keysend: {refund_err}"
+ );
+ }
+ Err(map_keysend_error(&e, has_xkeysend))
+ }
}
}
async fn xkeysend(
- rpc: &mut ClnRpc,
- params: nip47::PayKeysendRequest,
+ pay_rpc: &mut ClnRpc,
+ params: &nip47::PayKeysendRequest,
pubkey: PublicKey,
- mut nwc_store: NwcStore,
- label: &str,
-) -> Result {
+) -> Result<(u64, u64, Secret), RpcError> {
let mut extratlvs = HashMap::with_capacity(params.tlv_records.len());
- for tlv in params.tlv_records {
- extratlvs.insert(tlv.tlv_type.to_string(), tlv.value);
+ for tlv in ¶ms.tlv_records {
+ extratlvs.insert(tlv.tlv_type.to_string(), tlv.value.clone());
}
let extratlvs = if extratlvs.is_empty() {
None
@@ -109,7 +168,7 @@ async fn xkeysend(
Some(extratlvs)
};
- match rpc
+ let o = pay_rpc
.call_typed(&XkeysendRequest {
extratlvs,
label: None,
@@ -120,62 +179,24 @@ async fn xkeysend(
amount_msat: Amount::from_msat(params.amount),
destination: pubkey,
})
- .await
- {
- Ok(o) => {
- if nwc_store.budget_msat.is_some() {
- update_budget_msat(&mut nwc_store, o.amount_sent_msat.msat());
- update_nwc_store(rpc, label, nwc_store)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
- }
+ .await?;
- let preimage = hex::encode(o.payment_preimage.to_vec());
-
- let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
-
- Ok(nip47::PayKeysendResponse {
- preimage,
- fees_paid: Some(fees_paid),
- })
- }
- Err(e) => match e.code {
- Some(c) => match c {
- 203 | 205 | 207 | 219 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::PaymentFailed,
- message: e.to_string(),
- }),
- 209 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Other,
- message: e.to_string(),
- }),
- _ => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- None => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- }
+ Ok((
+ o.amount_sent_msat.msat(),
+ o.amount_msat.msat(),
+ o.payment_preimage,
+ ))
}
async fn keysend(
- rpc: &mut ClnRpc,
- params: nip47::PayKeysendRequest,
+ pay_rpc: &mut ClnRpc,
+ params: &nip47::PayKeysendRequest,
pubkey: PublicKey,
- mut nwc_store: NwcStore,
- label: &str,
-) -> Result {
+) -> Result<(u64, u64, Secret), RpcError> {
let mut extratlvs = TlvStream {
entries: Vec::new(),
};
- for tlv in params.tlv_records {
+ for tlv in ¶ms.tlv_records {
extratlvs.entries.push(TlvEntry {
typ: tlv.tlv_type,
value: tlv.value.as_bytes().to_owned(),
@@ -187,7 +208,7 @@ async fn keysend(
Some(extratlvs)
};
- match rpc
+ let o = pay_rpc
.call_typed(&KeysendRequest {
exemptfee: None,
extratlvs,
@@ -200,47 +221,48 @@ async fn keysend(
amount_msat: Amount::from_msat(params.amount),
destination: pubkey,
})
- .await
- {
- Ok(o) => {
- if nwc_store.budget_msat.is_some() {
- update_budget_msat(&mut nwc_store, o.amount_sent_msat.msat());
- update_nwc_store(rpc, label, nwc_store)
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?;
- }
+ .await?;
- let preimage = hex::encode(o.payment_preimage.to_vec());
+ Ok((
+ o.amount_sent_msat.msat(),
+ o.amount_msat.msat(),
+ o.payment_preimage,
+ ))
+}
- let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
+fn map_keysend_error(e: &RpcError, is_xkeysend: bool) -> nip47::NIP47Error {
+ let Some(c) = e.code else {
+ return nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ };
+ };
- Ok(nip47::PayKeysendResponse {
- preimage,
- fees_paid: Some(fees_paid),
- })
+ let failed_codes = if is_xkeysend {
+ vec![203, 205, 207, 219]
+ } else {
+ vec![203, 205, 210]
+ };
+
+ if failed_codes.contains(&c) {
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::PaymentFailed,
+ message: e.to_string(),
+ }
+ } else if is_xkeysend && c == 209 {
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::Other,
+ message: e.to_string(),
+ }
+ } else if !is_xkeysend && c == 206 {
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::InsufficientBalance,
+ message: e.to_string(),
+ }
+ } else {
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
}
- Err(e) => match e.code {
- Some(c) => match c {
- 203 | 205 | 210 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::PaymentFailed,
- message: e.to_string(),
- }),
- 206 => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::InsufficientBalance,
- message: e.to_string(),
- }),
- _ => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
- None => Err(nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- }),
- },
}
}
diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs
index ffc348a..9ff8635 100644
--- a/src/nwc_pay.rs
+++ b/src/nwc_pay.rs
@@ -16,8 +16,11 @@ use crate::{
budget_amount_check,
get_budget_msat,
load_nwc_store,
- update_budget_msat,
- update_nwc_store,
+ payment_fee_reserve_msat,
+ refund_budget,
+ reserve_budget,
+ rpc_socket_path,
+ settle_budget,
},
};
@@ -53,21 +56,92 @@ async fn pay_invoice(
params: nip47::PayInvoiceRequest,
label: &str,
) -> Result<(nip47::PayInvoiceResponse, Option), (nip47::NIP47Error, Option)> {
- let mut rpc = plugin.state().rpc_lock.lock().await;
+ let (id, reservation) = {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
- let decoded_invoice = decode_and_validate_invoice(&mut rpc, ¶ms).await?;
+ let decoded_invoice = decode_and_validate_invoice(&mut rpc, ¶ms).await?;
- let id = get_payment_id(¶ms, &decoded_invoice)?;
+ let id = get_payment_id(¶ms, &decoded_invoice)?;
- let invoice_amt_msat = get_invoice_amount_msat(&decoded_invoice, &id)?;
+ let invoice_amt_msat = get_invoice_amount_msat(&decoded_invoice, &id)?;
- let nwc_store =
- load_nwc_and_check_budget(&mut rpc, label, ¶ms, invoice_amt_msat, &id).await?;
+ let nwc_store =
+ load_nwc_and_check_budget(&mut rpc, label, ¶ms, invoice_amt_msat, &id).await?;
- if plugin.state().config.lock().has_xpay {
- pay_with_xpay_full(&mut rpc, params, label, nwc_store, &id).await
+ // Reserve the invoice amount plus the worst case fee so that no
+ // combination of concurrent payments can exceed the budget and so that
+ // balance queries during the payment reflect the reserved amount.
+ if get_budget_msat(&nwc_store).unwrap_or(u64::MAX)
+ < invoice_amt_msat.saturating_add(payment_fee_reserve_msat(invoice_amt_msat))
+ {
+ return Err((
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::QuotaExceeded,
+ message: "Payment and estimated fees exceed the available budget".to_owned(),
+ },
+ Some(id),
+ ));
+ }
+
+ let reservation = reserve_budget(&mut rpc, label, &nwc_store, invoice_amt_msat)
+ .await
+ .map_err(|e| {
+ (
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: e.to_string(),
+ },
+ Some(id.clone()),
+ )
+ })?;
+
+ (id, reservation)
+ };
+
+ let has_xpay = plugin.state().config.lock().has_xpay;
+
+ let mut pay_rpc = ClnRpc::new(rpc_socket_path(&plugin)).await.map_err(|e| {
+ (
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: format!("Could not connect to lightningd: {e}"),
+ },
+ Some(id.clone()),
+ )
+ })?;
+
+ let pay_result = if has_xpay {
+ pay_with_xpay(&mut pay_rpc, ¶ms).await
} else {
- pay_with_legacy_full(&mut rpc, params, label, nwc_store, &id).await
+ pay_with_legacy(&mut pay_rpc, ¶ms).await
+ };
+
+ match pay_result {
+ Ok((amount_sent_msat, amount_msat, preimage)) => {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+ if let Err(e) = settle_budget(&mut rpc, label, reservation, amount_sent_msat).await {
+ log::error!("Error updating budget after successful payment: {e}");
+ }
+
+ let preimage_str = hex::encode(preimage.to_vec());
+ let fees_paid = amount_sent_msat.saturating_sub(amount_msat);
+ Ok((
+ nip47::PayInvoiceResponse {
+ preimage: preimage_str,
+ fees_paid: Some(fees_paid),
+ },
+ Some(id),
+ ))
+ }
+ Err(e) => {
+ let mut rpc = plugin.state().rpc_lock.lock().await;
+ if let Err(refund_err) = refund_budget(&mut rpc, label, reservation).await {
+ log::error!(
+ "Error refunding budget reservation after failed payment: {refund_err}"
+ );
+ }
+ Err(map_cln_error_to_nip47(&e, &id, has_xpay))
+ }
}
}
@@ -195,41 +269,6 @@ async fn load_nwc_and_check_budget(
Ok(nwc_store)
}
-async fn update_budget_and_create_response(
- rpc: &mut ClnRpc,
- label: &str,
- nwc_store: &mut NwcStore,
- amount_sent_msat: u64,
- amount_msat: u64,
- preimage: Secret,
- id: &str,
-) -> Result<(nip47::PayInvoiceResponse, Option), (nip47::NIP47Error, Option)> {
- if nwc_store.budget_msat.is_some() {
- update_budget_msat(nwc_store, amount_sent_msat);
- update_nwc_store(rpc, label, nwc_store.clone())
- .await
- .map_err(|e| {
- (
- nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- },
- Some(id.to_owned()),
- )
- })?;
- }
-
- let preimage_str = hex::encode(preimage.to_vec());
- let fees_paid = amount_sent_msat - amount_msat;
- Ok((
- nip47::PayInvoiceResponse {
- preimage: preimage_str,
- fees_paid: Some(fees_paid),
- },
- Some(id.to_owned()),
- ))
-}
-
fn map_cln_error_to_nip47(
e: &RpcError,
id: &str,
@@ -292,14 +331,11 @@ fn map_cln_error_to_nip47(
}
}
-async fn pay_with_xpay_full(
- rpc: &mut ClnRpc,
- params: nip47::PayInvoiceRequest,
- label: &str,
- mut nwc_store: NwcStore,
- id: &str,
-) -> Result<(nip47::PayInvoiceResponse, Option), (nip47::NIP47Error, Option)> {
- let payment_result = rpc
+async fn pay_with_xpay(
+ pay_rpc: &mut ClnRpc,
+ params: &nip47::PayInvoiceRequest,
+) -> Result<(u64, u64, Secret), RpcError> {
+ let payment_result = pay_rpc
.call_typed(&XpayRequest {
amount_msat: params.amount.map(Amount::from_msat),
maxdelay: None,
@@ -307,39 +343,26 @@ async fn pay_with_xpay_full(
partial_msat: None,
retry_for: None,
layers: None,
- invstring: params.invoice,
+ invstring: params.invoice.clone(),
payer_note: None,
dev_use_shadow: None,
label: None,
localinvreqid: None,
})
- .await
- .map_err(|e| map_cln_error_to_nip47(&e, id, true))?;
+ .await?;
- let amount_sent_msat = payment_result.amount_sent_msat.msat();
- let amount_msat = payment_result.amount_msat.msat();
- let preimage = payment_result.payment_preimage;
-
- update_budget_and_create_response(
- rpc,
- label,
- &mut nwc_store,
- amount_sent_msat,
- amount_msat,
- preimage,
- id,
- )
- .await
+ Ok((
+ payment_result.amount_sent_msat.msat(),
+ payment_result.amount_msat.msat(),
+ payment_result.payment_preimage,
+ ))
}
-async fn pay_with_legacy_full(
- rpc: &mut ClnRpc,
- params: nip47::PayInvoiceRequest,
- label: &str,
- mut nwc_store: NwcStore,
- id: &str,
-) -> Result<(nip47::PayInvoiceResponse, Option), (nip47::NIP47Error, Option)> {
- let payment_result = rpc
+async fn pay_with_legacy(
+ pay_rpc: &mut ClnRpc,
+ params: &nip47::PayInvoiceRequest,
+) -> Result<(u64, u64, Secret), RpcError> {
+ let payment_result = pay_rpc
.call_typed(&PayRequest {
amount_msat: params.amount.map(Amount::from_msat),
description: None,
@@ -353,23 +376,13 @@ async fn pay_with_legacy_full(
retry_for: None,
riskfactor: None,
exclude: None,
- bolt11: params.invoice,
+ bolt11: params.invoice.clone(),
})
- .await
- .map_err(|e| map_cln_error_to_nip47(&e, id, false))?;
+ .await?;
- let amount_sent_msat = payment_result.amount_sent_msat.msat();
- let amount_msat = payment_result.amount_msat.msat();
- let preimage = payment_result.payment_preimage;
-
- update_budget_and_create_response(
- rpc,
- label,
- &mut nwc_store,
- amount_sent_msat,
- amount_msat,
- preimage,
- id,
- )
- .await
+ Ok((
+ payment_result.amount_sent_msat.msat(),
+ payment_result.amount_msat.msat(),
+ payment_result.payment_preimage,
+ ))
}
diff --git a/src/rpc.rs b/src/rpc.rs
index 1aba835..f00cc04 100644
--- a/src/rpc.rs
+++ b/src/rpc.rs
@@ -83,6 +83,7 @@ pub async fn nwc_create(
walletkey: wallet_keys.secret_key().to_secret_hex(),
budget_msat,
interval_config,
+ reserved_msat: 0,
};
rpc.call_typed(&DatastoreRequest {
diff --git a/src/structs.rs b/src/structs.rs
index 1ebfb85..c66de4e 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,9 +1,4 @@
-use std::{
- collections::{HashMap, HashSet},
- path::PathBuf,
- str::FromStr,
- sync::Arc,
-};
+use std::{collections::HashMap, path::PathBuf, str::FromStr, sync::Arc};
use cln_rpc::ClnRpc;
use nostr::{
@@ -90,6 +85,7 @@ pub struct BudgetIntervalConfig {
pub interval_secs: u64,
pub reset_budget_msat: u64,
pub last_reset: u64,
+ #[serde(default)]
pub spend_since_last_reset: u64,
}
@@ -101,4 +97,6 @@ pub struct NwcStore {
pub budget_msat: Option,
#[serde(skip_serializing_if = "Option::is_none")]
pub interval_config: Option,
+ #[serde(default)]
+ pub reserved_msat: u64,
}
diff --git a/src/util.rs b/src/util.rs
index 20fa53f..2467ab1 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -1,3 +1,8 @@
+use std::{
+ cmp::max,
+ path::{Path, PathBuf},
+};
+
use anyhow::anyhow;
use cln_plugin::Plugin;
use cln_rpc::{
@@ -17,20 +22,29 @@ use crate::{
structs::{ID_STORE, NwcStore, PluginState},
};
+/// CLN's default maximum fee for a payment is `max(5000msat, 1% of amount)`,
+/// so reserving this much guarantees a settled payment never exceeds the budget.
+pub const MIN_FEE_RESERVE_MSAT: u64 = 5_000;
+
+pub fn payment_fee_reserve_msat(amount_msat: u64) -> u64 {
+ max(MIN_FEE_RESERVE_MSAT, amount_msat.saturating_div(100))
+}
+
pub fn get_budget_msat(nwc_store: &NwcStore) -> Option {
match nwc_store.budget_msat {
Some(b) => {
- if let Some(conf) = &nwc_store.interval_config {
+ let available = if let Some(conf) = &nwc_store.interval_config {
let now = Timestamp::now().as_secs();
let spend = if now.saturating_sub(conf.last_reset) >= conf.interval_secs {
0
} else {
conf.spend_since_last_reset
};
- Some(conf.reset_budget_msat.saturating_sub(spend))
+ conf.reset_budget_msat.saturating_sub(spend)
} else {
- Some(b)
- }
+ b
+ };
+ Some(available.saturating_sub(nwc_store.reserved_msat))
}
None => None,
}
@@ -128,6 +142,72 @@ pub async fn update_nwc_store(
Ok(())
}
+pub fn rpc_socket_path(plugin: &Plugin) -> PathBuf {
+ Path::new(&plugin.configuration().lightning_dir).join(&plugin.configuration().rpc_file)
+}
+
+/// Reserve the payment amount plus the worst case fee so that no combination
+/// of concurrent payments can exceed the budget. Must be called while holding
+/// the global rpc lock. Returns the reserved amount (0 if there is no budget).
+pub async fn reserve_budget(
+ rpc: &mut ClnRpc,
+ label: &str,
+ nwc_store: &NwcStore,
+ amount_msat: u64,
+) -> Result {
+ if nwc_store.budget_msat.is_none() {
+ return Ok(0);
+ }
+
+ let reservation = amount_msat.saturating_add(payment_fee_reserve_msat(amount_msat));
+ let mut new_store = nwc_store.clone();
+ new_store.reserved_msat = new_store.reserved_msat.saturating_add(reservation);
+ update_nwc_store(rpc, label, new_store).await?;
+
+ Ok(reservation)
+}
+
+/// Release the reservation of a payment that did not succeed. Must be called
+/// while holding the global rpc lock.
+pub async fn refund_budget(
+ rpc: &mut ClnRpc,
+ label: &str,
+ reservation: u64,
+) -> Result<(), anyhow::Error> {
+ if reservation == 0 {
+ return Ok(());
+ }
+
+ let mut nwc_store = load_nwc_store(rpc, label).await?;
+ nwc_store.reserved_msat = nwc_store.reserved_msat.saturating_sub(reservation);
+ update_nwc_store(rpc, label, nwc_store).await?;
+
+ Ok(())
+}
+
+/// Record the actual amount spent by a successful payment and release the
+/// remainder of the reservation. Must be called while holding the global rpc
+/// lock. Charges the real spend first so that an error leaves the budget
+/// conservatively low rather than too high.
+pub async fn settle_budget(
+ rpc: &mut ClnRpc,
+ label: &str,
+ reservation: u64,
+ amount_spent_msat: u64,
+) -> Result<(), anyhow::Error> {
+ // A zero reservation only happens when the nwc has no budget at all.
+ if reservation == 0 {
+ return Ok(());
+ }
+
+ let mut nwc_store = load_nwc_store(rpc, label).await?;
+ update_budget_msat(&mut nwc_store, amount_spent_msat);
+ nwc_store.reserved_msat = nwc_store.reserved_msat.saturating_sub(reservation);
+ update_nwc_store(rpc, label, nwc_store).await?;
+
+ Ok(())
+}
+
pub fn is_read_only_nwc(nwc_store: &NwcStore) -> bool {
if let Some(budget_msat) = nwc_store.budget_msat {
if budget_msat == 0 && nwc_store.interval_config.is_none() {
@@ -258,6 +338,7 @@ fn test_budget_interval_helpers() {
walletkey: "test".to_owned(),
budget_msat: Some(1000),
interval_config: Some(conf),
+ reserved_msat: 0,
};
assert_eq!(get_budget_msat(&store), Some(1000));
@@ -292,3 +373,48 @@ fn test_budget_interval_helpers() {
);
assert_eq!(get_budget_msat(&store), Some(600));
}
+
+#[test]
+fn test_payment_fee_reserve() {
+ // fee reserve is at least 5000msat
+ assert_eq!(payment_fee_reserve_msat(0), 5000);
+ assert_eq!(payment_fee_reserve_msat(1000), 5000);
+ assert_eq!(payment_fee_reserve_msat(499_999), 5000);
+ // and 1% of the amount above that
+ assert_eq!(payment_fee_reserve_msat(500_000), 5000);
+ assert_eq!(payment_fee_reserve_msat(1_000_000), 10_000);
+ assert_eq!(payment_fee_reserve_msat(123_456_789), 1_234_567);
+}
+
+#[test]
+fn test_budget_reservations() {
+ let store = NwcStore {
+ uri: nostr::nips::nip47::NostrWalletConnectUri::new(
+ nostr::key::Keys::generate().public_key(),
+ vec![],
+ nostr::key::Keys::generate().secret_key().clone(),
+ None,
+ ),
+ walletkey: "test".to_owned(),
+ budget_msat: Some(10_000),
+ interval_config: None,
+ reserved_msat: 0,
+ };
+
+ // reserving reduces the available budget
+ let mut stored = store.clone();
+ stored.reserved_msat = 1_500;
+ assert_eq!(get_budget_msat(&stored), Some(8_500));
+
+ // a full spend plus reservation can never be under budget
+ let full_reservation =
+ stored.clone().budget_msat.unwrap() + payment_fee_reserve_msat(store.budget_msat.unwrap());
+ stored.reserved_msat = full_reservation;
+ assert_eq!(get_budget_msat(&stored), Some(0));
+
+ // reservations do not affect a store without a budget
+ let mut no_budget = store;
+ no_budget.budget_msat = None;
+ no_budget.reserved_msat = 1_000;
+ assert_eq!(get_budget_msat(&no_budget), None);
+}
diff --git a/tests/test_cln-nip47.py b/tests/test_cln-nip47.py
index 7e055ec..cb2b6dd 100644
--- a/tests/test_cln-nip47.py
+++ b/tests/test_cln-nip47.py
@@ -394,7 +394,7 @@ async def test_pay_keysend(nostr_relay, node_factory, get_plugin): # noqa: F811
{"log-level": "debug"},
],
)
- uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
+ uri_str = l1.rpc.call("nip47-create", ["test1", 8000])["uri"]
LOGGER.info(uri_str)
uri = NostrWalletConnectUri.parse(uri_str)
client = Client()
@@ -416,7 +416,7 @@ async def test_pay_keysend(nostr_relay, node_factory, get_plugin): # noqa: F811
await nwc.pay_keysend(
PayKeysendRequest(
id="id123",
- amount=2001,
+ amount=7500,
pubkey=l2.info["id"],
preimage=None,
tlv_records=[KeysendTlvRecord(tlv_type=1234, value="a5c7e3d9b")],
@@ -428,7 +428,7 @@ async def test_pay_keysend(nostr_relay, node_factory, get_plugin): # noqa: F811
await nwc.pay_keysend(
PayKeysendRequest(
id="id123",
- amount=2001,
+ amount=7500,
pubkey=l2.info["id"],
preimage="or3ijro3ijroi",
tlv_records=[KeysendTlvRecord(tlv_type=1234, value="a5c7e3d9b")],
@@ -957,7 +957,7 @@ async def test_pay_invoice(nostr_relay, node_factory, get_plugin): # noqa: F811
{"log-level": "debug"},
],
)
- uri_str = l1.rpc.call("nip47-create", ["test1", 3001])["uri"]
+ uri_str = l1.rpc.call("nip47-create", ["test1", 9000])["uri"]
uri = NostrWalletConnectUri.parse(uri_str)
client = Client()
await client.add_relay(RelayUrl.parse(url))
@@ -985,7 +985,7 @@ async def test_pay_invoice(nostr_relay, node_factory, get_plugin): # noqa: F811
)
invoice = l2.rpc.call(
"invoice",
- {"label": generate_random_label(), "description": "test3", "amount_msat": 2},
+ {"label": generate_random_label(), "description": "test3", "amount_msat": 6500},
)
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
await nwc.pay_invoice(
@@ -1009,7 +1009,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
{"log-level": "debug"},
],
)
- uri_str = l1.rpc.call("nip47-create", ["test1", 3000])["uri"]
+ uri_str = l1.rpc.call("nip47-create", ["test1", 8000])["uri"]
LOGGER.info(uri_str)
invoice = l2.rpc.call(
"invoice",
@@ -1038,7 +1038,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
invoice = l2.rpc.call(
"invoice",
- {"label": generate_random_label(), "description": "test1", "amount_msat": 1},
+ {"label": generate_random_label(), "description": "test1", "amount_msat": 5500},
)
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
await nwc.pay_invoice(
@@ -1064,7 +1064,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
revoke = l1.rpc.call("nip47-revoke", ["test1"])
assert revoke["revoked"] == "test1"
- uri_str = l1.rpc.call("nip47-create", ["test1", 3000, "10sec"])["uri"]
+ uri_str = l1.rpc.call("nip47-create", ["test1", 8000, "10sec"])["uri"]
uri = NostrWalletConnectUri.parse(uri_str)
client = Client()
await client.add_relay(RelayUrl.parse(url))
@@ -1078,7 +1078,11 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
)
invoice_exceeded = l2.rpc.call(
"invoice",
- {"label": generate_random_label(), "description": "test1", "amount_msat": 3000},
+ {"label": generate_random_label(), "description": "test1", "amount_msat": 5500},
+ )
+ invoice_fee_exceeded = l2.rpc.call(
+ "invoice",
+ {"label": generate_random_label(), "description": "test1", "amount_msat": 1},
)
result = await nwc.pay_invoice(
PayInvoiceRequest(id=None, amount=None, invoice=invoice["bolt11"])
@@ -1086,17 +1090,26 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
assert result.preimage is not None
list = l1.rpc.call("nip47-list", ["test1"])[0]
- assert list["test1"]["budget_msat"] == 0
+ assert list["test1"]["budget_msat"] == 5000
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
await nwc.pay_invoice(
PayInvoiceRequest(id=None, amount=None, invoice=invoice_exceeded["bolt11"])
)
+ with pytest.raises(
+ NostrSdkError.Generic,
+ match="Payment and estimated fees exceed the available budget",
+ ):
+ await nwc.pay_invoice(
+ PayInvoiceRequest(
+ id=None, amount=None, invoice=invoice_fee_exceeded["bolt11"]
+ )
+ )
await asyncio.sleep(11)
list = l1.rpc.call("nip47-list", ["test1"])[0]
- assert list["test1"]["budget_msat"] == 3000
+ assert list["test1"]["budget_msat"] == 8000
invoice = l2.rpc.call(
"invoice",
@@ -1108,7 +1121,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
assert result.preimage is not None
list = l1.rpc.call("nip47-list", ["test1"])[0]
- assert list["test1"]["budget_msat"] == 0
+ assert list["test1"]["budget_msat"] == 5000
with pytest.raises(NostrSdkError.Generic, match="Payment exceeds budget"):
await nwc.pay_invoice(
@@ -1136,7 +1149,7 @@ async def test_persistency(nostr_relay, node_factory, get_plugin): # noqa: F811
await asyncio.sleep(11)
list = l1.rpc.call("nip47-list", ["test1"])[0]
- assert list["test1"]["budget_msat"] == 3000
+ assert list["test1"]["budget_msat"] == 8000
@pytest.mark.asyncio
@@ -1184,9 +1197,9 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
PayInvoiceRequest(id=None, amount=None, invoice=invoice["bolt11"])
)
- l1.rpc.call("nip47-budget", ["test1", 5000, "15s"])
+ l1.rpc.call("nip47-budget", ["test1", 10000, "15s"])
balance = await nwc.get_balance()
- assert balance.balance == 5000
+ assert balance.balance == 10000
with pytest.raises(
RpcError, match="`budget_msat` must be greater than 0 if you use `interval`"
@@ -1199,7 +1212,7 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
assert pay.preimage is not None
balance = await nwc.get_balance()
- assert balance.balance == 0
+ assert balance.balance == 5000
get_info = await nwc.get_info()
assert get_info.methods == [
@@ -1230,7 +1243,7 @@ async def test_budget_command(nostr_relay, node_factory, get_plugin): # noqa: F
await asyncio.sleep(18)
balance = await nwc.get_balance()
- assert balance.balance == 5000
+ assert balance.balance == 10000
l1.rpc.call("nip47-budget", ["test1", 0])
balance = await nwc.get_balance()
From 29c1ace33c1f052df6babed68f9dbbef06d0159b Mon Sep 17 00:00:00 2001
From: daywalker90
Date: Sun, 9 Aug 2026 13:31:41 +0200
Subject: [PATCH 39/56] bound list_transactions work to prevent DoS
list_transactions was a DoS vector: it loaded the full invoice and
payment history, made one decode rpc-call per entry, and re-serialized
the whole result set for every trimmed entry (O(n^2)), all while holding
the global rpc lock that serializes every other nwc request and command.
- run list_transactions on a dedicated rpc connection so it no longer
stalls the rest of the plugin
- page backwards through listinvoices by created_index instead of
fetching the whole history, using the wait rpc to get the newest index
- only decode the kept candidates and honor the from/until and unpaid
filters while collecting them
- cap work per request at MAX_TRANSACTIONS (500) regardless of node
history size
- limit pays and hold invoices to the same bound before decoding
- make trim_to_size a single serialization pass instead of O(n^2)
---
src/nwc_lookups.rs | 560 ++++++++++++++++++++++++++++++++-------------
1 file changed, 403 insertions(+), 157 deletions(-)
diff --git a/src/nwc_lookups.rs b/src/nwc_lookups.rs
index 32fe39e..80d76b8 100644
--- a/src/nwc_lookups.rs
+++ b/src/nwc_lookups.rs
@@ -4,7 +4,15 @@ use cln_plugin::Plugin;
use cln_rpc::{
ClnRpc,
model::{
- requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest},
+ requests::{
+ DecodeRequest,
+ ListinvoicesIndex,
+ ListinvoicesRequest,
+ ListpaysRequest,
+ WaitIndexname,
+ WaitRequest,
+ WaitSubsystem,
+ },
responses::{
DecodeResponse,
DecodeType,
@@ -22,8 +30,16 @@ use tonic::transport::Channel;
use crate::{
hold::{self, ListRequest, hold_client::HoldClient, list_request::Constraint},
structs::{NOT_INV_ERR, PluginState},
+ util::rpc_socket_path,
};
+#[allow(clippy::doc_markdown)]
+/// Hard bound on the number of transactions a single `list_transactions`
+/// request will fetch, decode and return (DoS protection).
+const MAX_TRANSACTIONS: usize = 500;
+/// Bound on the size of a `list_transactions` response in bytes.
+const RESPONSE_LIMIT_BYTES: usize = 127 * 1024;
+
pub async fn lookup_invoice_response(
plugin: Plugin,
params: nip47::LookupInvoiceRequest,
@@ -367,7 +383,37 @@ async fn list_transactions(
plugin: Plugin,
params: nip47::ListTransactionsRequest,
) -> Result, nip47::NIP47Error> {
- let mut rpc = plugin.state().rpc_lock.lock().await;
+ if params.limit == Some(0) {
+ return Ok(Vec::new());
+ }
+
+ let mut rpc = ClnRpc::new(rpc_socket_path(&plugin))
+ .await
+ .map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: format!("Could not connect to lightningd: {e}"),
+ })?;
+
+ let limit = usize::try_from(params.limit.unwrap_or(MAX_TRANSACTIONS as u64)).map_err(|e| {
+ nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: format!("32-bit usize limit exceeded: {e}"),
+ }
+ })?;
+ let offset = usize::try_from(params.offset.unwrap_or(0)).map_err(|e| nip47::NIP47Error {
+ code: nip47::ErrorCode::Internal,
+ message: format!("32-bit usize limit exceeded: {e}"),
+ })?;
+ let want = limit.saturating_add(offset);
+ // Enough candidates from each source to satisfy the requested window even
+ // if some get filtered out again by `from`/`until`/`unpaid`.
+ let per_source = want
+ .saturating_mul(2)
+ .saturating_add(16)
+ .min(MAX_TRANSACTIONS);
+ let from = params.from.map(|t| t.as_secs());
+ let until = params.until.map(|t| t.as_secs());
+ let unpaid = params.unpaid.unwrap_or(false);
let (query_invoices, query_payments) = match params.transaction_type {
Some(t) => match t {
@@ -377,70 +423,29 @@ async fn list_transactions(
None => (true, true),
};
- let unpaid = params.unpaid.unwrap_or(false);
-
let mut transactions: Vec = Vec::new();
+
if query_invoices {
- let list_invoices = rpc
- .call_typed(&ListinvoicesRequest {
- index: None,
- invstring: None,
- label: None,
- limit: None,
- offer_id: None,
- payment_hash: None,
- start: None,
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?
- .invoices;
+ let invoices = collect_invoices(&mut rpc, per_source, from, until, unpaid).await?;
+ transactions.extend(invoices);
- for list_invoice in list_invoices {
- if !unpaid && list_invoice.status == ListinvoicesInvoicesStatus::UNPAID {
- continue;
- }
-
- match make_lookup_response_from_listinvoices(&mut rpc, list_invoice).await {
- Ok(t) => transactions.push(t),
- Err(_e) => (),
- }
- }
-
- let holdinvoice_support = plugin.state().hold_client.lock().is_some();
-
- if holdinvoice_support {
- let mut hold_client = plugin.state().hold_client.lock().clone().unwrap();
- list_holdinvoices_to_transactions(&mut hold_client, &mut rpc, &mut transactions)
- .await?;
+ let hold_client = plugin.state().hold_client.lock().clone();
+ if let Some(mut hold_client) = hold_client {
+ list_holdinvoices_to_transactions(
+ &mut hold_client,
+ &mut rpc,
+ per_source,
+ from,
+ until,
+ &mut transactions,
+ )
+ .await?;
}
}
if query_payments {
- let list_pays = rpc
- .call_typed(&ListpaysRequest {
- bolt11: None,
- index: None,
- limit: None,
- payment_hash: None,
- start: None,
- status: None,
- })
- .await
- .map_err(|e| nip47::NIP47Error {
- code: nip47::ErrorCode::Internal,
- message: e.to_string(),
- })?
- .pays;
-
- for list_pay in list_pays {
- match make_lookup_response_from_listpays(&mut rpc, list_pay).await {
- Ok(t) => transactions.push(t),
- Err(_e) => (),
- }
- }
+ let pays = collect_pays(&mut rpc, per_source, from, until).await?;
+ transactions.extend(pays);
}
transactions.sort_by_key(|t| Reverse(t.created_at));
@@ -463,14 +468,211 @@ async fn list_transactions(
}
}
- transactions = trim_to_size(transactions, 127 * 1024);
+ transactions = trim_to_size(transactions, RESPONSE_LIMIT_BYTES);
Ok(transactions)
}
+async fn max_invoice_created_index(rpc: &mut ClnRpc) -> Result