neuronum 10.0.0__py3-none-any.whl → 10.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of neuronum might be problematic. Click here for more details.

cli/main.py CHANGED
@@ -64,6 +64,25 @@ def derive_keys_from_mnemonic(mnemonic: str):
64
64
  click.echo(f"❌ Error generating keys from mnemonic: {e}")
65
65
  return None, None, None, None
66
66
 
67
+ def base64url_encode(data: bytes) -> str:
68
+ """Base64url encodes bytes (no padding, URL-safe characters)."""
69
+ return base64.urlsafe_b64encode(data).rstrip(b'=').decode('utf-8')
70
+
71
+ def create_dns_challenge_value(public_key_pem: bytes) -> str:
72
+ """
73
+ Creates a DNS TXT challenge value from the public key.
74
+
75
+ This simulates creating an ACME-style key authorization by hashing
76
+ the public key (a proxy for account key) and then base64url encoding it.
77
+ """
78
+ try:
79
+ # A simple, secure challenge value: SHA256(PublicKey_PEM) base64url encoded
80
+ key_hash = hashlib.sha256(public_key_pem).digest()
81
+ challenge_value = base64url_encode(key_hash)
82
+ return challenge_value
83
+ except Exception as e:
84
+ click.echo(f"❌ Error creating DNS challenge value: {e}")
85
+ return ""
67
86
 
68
87
  def save_credentials(host: str, mnemonic: str, pem_public: bytes, pem_private: bytes):
69
88
  """Saves host, mnemonic, and keys to the .neuronum directory."""
@@ -131,52 +150,152 @@ def cli():
131
150
 
132
151
  # --- CLI Commands ---
133
152
 
153
+ # ... (existing CLI Group and Commands)
154
+
134
155
  @click.command()
135
156
  def create_cell():
136
- """Creates a new Community Cell with a randomly generated key pair."""
137
-
138
- # 1. Generate Mnemonic and Keys
157
+ """Creates a new Cell with a randomly generated key pair."""
158
+ cell_type = questionary.select(
159
+ "Choose Cell type:",
160
+ choices=["business", "community"]
161
+ ).ask()
162
+
163
+ if not cell_type:
164
+ click.echo("Cell creation canceled.")
165
+ return
166
+
167
+ # 1. Generate Mnemonic and Keys for both types
139
168
  mnemonic = Bip39MnemonicGenerator().FromWordsNumber(12)
140
169
  private_key, public_key, pem_private, pem_public = derive_keys_from_mnemonic(mnemonic)
141
170
 
142
171
  if not private_key:
143
172
  return
144
173
 
145
- # 2. Call API to Create Cell
146
- click.echo("🔗 Requesting new cell creation from server...")
147
- url = f"{API_BASE_URL}/create_cell"
148
- create_data = {"public_key": pem_public.decode("utf-8")}
149
-
150
- try:
151
- response = requests.post(url, json=create_data, timeout=10)
152
- response.raise_for_status()
153
- host = response.json().get("host")
154
-
155
- except requests.exceptions.RequestException as e:
156
- click.echo(f"❌ Error communicating with the server: {e}")
157
- return
174
+ public_key_pem_str = pem_public.decode("utf-8")
175
+
176
+ # --- Business Cell Logic (DNS Challenge) ---
177
+ if cell_type == "business":
178
+ company_name = questionary.text("Enter your full Company Name e.g., Neuronum Cybernetics UG").ask()
179
+ domain = questionary.text("Enter your FQDN (e.g., mycompany.com):").ask()
180
+ if not domain:
181
+ click.echo("Business cell creation canceled. Host is required.")
182
+ return
183
+
184
+ # Generate the DNS challenge value
185
+ challenge_value = create_dns_challenge_value(pem_public)
186
+
187
+ if not challenge_value:
188
+ return
189
+
190
+ # 2. Instruct User on DNS TXT Record
191
+ click.echo("\n" + "=" * 60)
192
+ click.echo("⚠️ DNS TXT Challenge Required")
193
+ click.echo("=" * 60)
194
+ click.echo(f"To prove ownership of '{domain}', please create a **DNS TXT record**.")
195
+ click.echo(f"This record must be placed on the subdomain **_neuronum.{domain}**.")
196
+ click.echo(f"\nName: **_neuronum.{domain}**")
197
+ click.echo(f"Type: **TXT**")
198
+ click.echo(f"Value: **{challenge_value}**")
199
+ click.echo("-" * 60)
200
+
201
+ # Pause for user action
202
+ questionary.press_any_key_to_continue("Press any key to continue once the DNS record is published...").ask()
203
+ click.echo("Attempting verification...")
204
+
205
+ # 3. Call API to Create/Verify Cell (Pass public_key, host, and challenge)
206
+ url = f"{API_BASE_URL}/create_business_cell"
207
+ create_data = {
208
+ "public_key": public_key_pem_str,
209
+ "domain": domain,
210
+ "challenge_value": challenge_value,
211
+ "company_name": company_name # Optional: Server might re-calculate but good to send
212
+ }
213
+
214
+ try:
215
+ # Server will check DNS for the TXT record, then create the cell
216
+ response = requests.post(url, json=create_data, timeout=30) # Increased timeout for DNS propagation
217
+ response.raise_for_status()
218
+ response_data = response.json()
219
+
220
+ # Check if server confirmed verification and creation
221
+ if response_data.get("status") == "verified" and response_data.get("host"):
222
+ # 4. Save Credentials
223
+ host = response_data.get("host")
224
+ if host:
225
+ if save_credentials(host, mnemonic, pem_public, pem_private):
226
+ click.echo("\n" + "=" * 50)
227
+ click.echo(" ✅ BUSINESS CELL CREATED! DNS verified and keys saved.")
228
+ click.echo(f" Host: {host}")
229
+ click.echo(f" Mnemonic (CRITICAL! Back this up!):")
230
+ click.echo(f" {mnemonic}")
231
+ click.echo("-" * 50)
232
+ click.echo(f"Credentials saved to: {NEURONUM_PATH}")
233
+ # else: Error saving already echoed in helper
234
+ else:
235
+ click.echo(f"❌ Verification failed. Server response: {response_data.get('detail', 'Unknown failure.')}")
236
+ return
237
+
238
+ except requests.exceptions.HTTPError as e:
239
+ # This catches all 4xx and 5xx errors.
240
+ try:
241
+ # Attempt to parse the server's detailed JSON error body (FastAPI format)
242
+ error_data = e.response.json()
243
+ error_detail = error_data.get("detail", "Unknown server error.")
244
+
245
+ # Print the specific detail message provided by the server
246
+ click.echo(f"❌ Verification failed. HTTP {e.response.status_code} Error: {error_detail}")
247
+
248
+ # Specific handling for the DNS verification failure (403)
249
+ if e.response.status_code == 403:
250
+ click.echo("\n👉 Please double-check that the TXT record is published and correctly set.")
251
+
252
+ except:
253
+ # If the response isn't JSON or doesn't have a 'detail' field
254
+ click.echo(f"❌ Server Error ({e.response.status_code}): {e.response.text}")
255
+ return
256
+
257
+ except requests.exceptions.RequestException as e:
258
+ # This catches network issues (DNS failure, connection refused, timeout, etc.)
259
+ click.echo(f"❌ Network Error: Could not communicate with the server. Details: {e}")
260
+ return
261
+
262
+ # --- Community Cell Logic (Existing Logic) ---
263
+ if cell_type == "community":
264
+ # 2. Call API to Create Cell
265
+ click.echo("🔗 Requesting new cell creation from server...")
266
+ url = f"{API_BASE_URL}/create_cell"
267
+ create_data = {"public_key": public_key_pem_str}
158
268
 
159
- # 3. Save Credentials
160
- if host:
161
- if save_credentials(host, mnemonic, pem_public, pem_private):
162
- click.echo("\n" + "=" * 50)
163
- click.echo(" ✅ WELCOME TO NEURONUM! Cell Created Successfully.")
164
- click.echo("=" * 50)
165
- click.echo(f" Host: {host}")
166
- click.echo(f" Mnemonic (CRITICAL! Back this up!):")
167
- click.echo(f" {mnemonic}")
168
- click.echo("-" * 50)
169
- click.echo(f"Credentials saved to: {NEURONUM_PATH}")
269
+ try:
270
+ response = requests.post(url, json=create_data, timeout=10)
271
+ response.raise_for_status()
272
+ host = response.json().get("host")
273
+
274
+ except requests.exceptions.RequestException as e:
275
+ click.echo(f"❌ Error communicating with the server: {e}")
276
+ return
277
+
278
+ # 3. Save Credentials
279
+ if host:
280
+ if save_credentials(host, mnemonic, pem_public, pem_private):
281
+ click.echo("\n" + "=" * 50)
282
+ click.echo(" ✅ WELCOME TO NEURONUM! Cell Created Successfully.")
283
+ click.echo("=" * 50)
284
+ click.echo(f" Host: {host}")
285
+ click.echo(f" Mnemonic (CRITICAL! Back this up!):")
286
+ click.echo(f" {mnemonic}")
287
+ click.echo("-" * 50)
288
+ click.echo(f"Credentials saved to: {NEURONUM_PATH}")
289
+ else:
290
+ # Error saving credentials already echoed in helper
291
+ pass
170
292
  else:
171
- # Error saving credentials already echoed in helper
172
- pass
173
- else:
174
- click.echo("❌ Error: Server did not return a host. Cell creation failed.")
293
+ click.echo("❌ Error: Server did not return a host. Cell creation failed.")
175
294
 
176
295
 
177
296
  @click.command()
178
297
  def connect_cell():
179
- """Connects to an existing Community Cell using a 12-word mnemonic."""
298
+ """Connects to an existing Cell using a 12-word mnemonic."""
180
299
 
181
300
  # 1. Get and Validate Mnemonic
182
301
  mnemonic = questionary.text("Enter your 12-word BIP-39 mnemonic (space separated):").ask()
neuronum/__init__.py CHANGED
@@ -1 +1 @@
1
- from neuronum import Cell
1
+ from .neuronum import Cell
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuronum
3
- Version: 10.0.0
3
+ Version: 10.1.0
4
4
  Summary: An E2EE Data Engine
5
5
  Home-page: https://neuronum.net
6
6
  Author: Neuronum Cybernetics
@@ -108,10 +108,12 @@ async def main():
108
108
  }
109
109
 
110
110
  # Use activate_tx() if you expect a response from the other cell
111
+ # Replace id with the actual Cell ID
111
112
  tx_response = await cell.activate_tx("id::cell", data)
112
113
  print(tx_response)
113
114
 
114
115
  # Stream data to another cell (no response expected)
116
+ # Replace id with the actual Cell ID
115
117
  await cell.stream("id::cell", data)
116
118
 
117
119
  if __name__ == '__main__':
@@ -0,0 +1,10 @@
1
+ cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ cli/main.py,sha256=c8K_gfcg3hT8xQ0yckX2uhrxUcbBkN9H24f_Sn5qRT0,16459
3
+ neuronum/__init__.py,sha256=yjm4pci0EGNN01F6soBxYa8HAhljCM20klbEORPbWbc,26
4
+ neuronum/neuronum.py,sha256=_LSl0x2DkZLd_bblFHy1ptJnWC-res00a0cjSu3Ngrs,28212
5
+ neuronum-10.1.0.dist-info/licenses/LICENSE.md,sha256=m7pw_FktMNCs4tcy2UXP3QQP2S_je28P1SepdYoo0Xo,1961
6
+ neuronum-10.1.0.dist-info/METADATA,sha256=CYJp8-EtbBuvHKrXGTMauNuAYpBim2FU1nAjrJyDEWc,4773
7
+ neuronum-10.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ neuronum-10.1.0.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
9
+ neuronum-10.1.0.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
10
+ neuronum-10.1.0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- cli/main.py,sha256=Xw3iK0BdWqN89EryBw2k3uWwLrYWxdIt_d0sJKNnErk,10878
3
- neuronum/__init__.py,sha256=_ankCAWkh9ef-rUGf4yl4SF2jTGiftLEa6y551cK780,25
4
- neuronum/neuronum.py,sha256=_LSl0x2DkZLd_bblFHy1ptJnWC-res00a0cjSu3Ngrs,28212
5
- neuronum-10.0.0.dist-info/licenses/LICENSE.md,sha256=m7pw_FktMNCs4tcy2UXP3QQP2S_je28P1SepdYoo0Xo,1961
6
- neuronum-10.0.0.dist-info/METADATA,sha256=xxwoQTW8uk3RywgRuRYvmy06FhkAGmmLYJskfpehquE,4683
7
- neuronum-10.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
- neuronum-10.0.0.dist-info/entry_points.txt,sha256=XKYBcRNxGeJpZZkDPsa8HA_RaJ7Km_R_JaUq5T9Nk2U,42
9
- neuronum-10.0.0.dist-info/top_level.txt,sha256=ru8Fr84cHm6oHr_DcJ8-uaq3RTiuCRFIr6AC8V0zPu4,13
10
- neuronum-10.0.0.dist-info/RECORD,,