hippius 0.2.35__tar.gz → 0.2.37__tar.gz
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.
- {hippius-0.2.35 → hippius-0.2.37}/PKG-INFO +1 -1
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/__init__.py +1 -1
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/client.py +10 -4
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/ipfs.py +35 -16
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/ipfs_core.py +5 -3
- {hippius-0.2.35 → hippius-0.2.37}/pyproject.toml +1 -1
- {hippius-0.2.35 → hippius-0.2.37}/README.md +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/cli.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/cli_assets.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/cli_handlers.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/cli_parser.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/cli_rich.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/config.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/db/README.md +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/db/env.db.template +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/db/migrations/20241201000001_create_key_storage_tables.sql +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/db/migrations/20241202000001_switch_to_subaccount_encryption.sql +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/db/setup_database.sh +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/db_utils.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/errors.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/key_storage.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/substrate.py +0 -0
- {hippius-0.2.35 → hippius-0.2.37}/hippius_sdk/utils.py +0 -0
@@ -26,7 +26,7 @@ from hippius_sdk.config import (
|
|
26
26
|
from hippius_sdk.ipfs import IPFSClient, S3PublishResult, S3DownloadResult
|
27
27
|
from hippius_sdk.utils import format_cid, format_size, hex_to_ipfs_cid
|
28
28
|
|
29
|
-
__version__ = "0.2.
|
29
|
+
__version__ = "0.2.37"
|
30
30
|
__all__ = [
|
31
31
|
"HippiusClient",
|
32
32
|
"IPFSClient",
|
@@ -521,6 +521,7 @@ class HippiusClient:
|
|
521
521
|
encrypt: bool,
|
522
522
|
seed_phrase: str,
|
523
523
|
subaccount_id: str,
|
524
|
+
bucket_name: str,
|
524
525
|
store_node: str = "http://localhost:5001",
|
525
526
|
pin_node: str = "https://store.hippius.network",
|
526
527
|
substrate_url: str = "wss://rpc.hippius.network",
|
@@ -536,6 +537,8 @@ class HippiusClient:
|
|
536
537
|
file_path: Path to the file to publish
|
537
538
|
encrypt: Whether to encrypt the file before uploading
|
538
539
|
seed_phrase: Seed phrase for blockchain transaction signing
|
540
|
+
subaccount_id: The subaccount/account identifier
|
541
|
+
bucket_name: The bucket name for key isolation
|
539
542
|
store_node: IPFS node URL for initial upload (default: local node)
|
540
543
|
pin_node: IPFS node URL for backup pinning (default: remote service)
|
541
544
|
substrate_url: substrate url to use for the storage request.
|
@@ -554,6 +557,7 @@ class HippiusClient:
|
|
554
557
|
encrypt,
|
555
558
|
seed_phrase,
|
556
559
|
subaccount_id,
|
560
|
+
bucket_name,
|
557
561
|
store_node,
|
558
562
|
pin_node,
|
559
563
|
substrate_url,
|
@@ -564,6 +568,7 @@ class HippiusClient:
|
|
564
568
|
cid: str,
|
565
569
|
output_path: str,
|
566
570
|
subaccount_id: str,
|
571
|
+
bucket_name: str,
|
567
572
|
auto_decrypt: bool = True,
|
568
573
|
download_node: str = "http://localhost:5001",
|
569
574
|
) -> S3DownloadResult:
|
@@ -571,16 +576,17 @@ class HippiusClient:
|
|
571
576
|
Download a file from IPFS with automatic decryption.
|
572
577
|
|
573
578
|
This method uses the download_node for immediate availability and automatically
|
574
|
-
manages decryption keys per
|
579
|
+
manages decryption keys per account+bucket combination:
|
575
580
|
- Downloads the file from the specified download_node (local by default)
|
576
|
-
- If auto_decrypt=True, attempts to decrypt using stored keys for the
|
581
|
+
- If auto_decrypt=True, attempts to decrypt using stored keys for the account+bucket
|
577
582
|
- Falls back to client encryption key if key storage is not available
|
578
583
|
- Returns the file in decrypted form if decryption succeeds
|
579
584
|
|
580
585
|
Args:
|
581
586
|
cid: Content Identifier (CID) of the file to download
|
582
587
|
output_path: Path where the downloaded file will be saved
|
583
|
-
subaccount_id: The subaccount
|
588
|
+
subaccount_id: The subaccount/account identifier
|
589
|
+
bucket_name: The bucket name for key isolation
|
584
590
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
585
591
|
download_node: IPFS node URL for download (default: local node)
|
586
592
|
|
@@ -593,5 +599,5 @@ class HippiusClient:
|
|
593
599
|
ValueError: If decryption fails
|
594
600
|
"""
|
595
601
|
return await self.ipfs_client.s3_download(
|
596
|
-
cid, output_path, subaccount_id, auto_decrypt, download_node
|
602
|
+
cid, output_path, subaccount_id, bucket_name, auto_decrypt, download_node
|
597
603
|
)
|
@@ -1954,6 +1954,7 @@ class IPFSClient:
|
|
1954
1954
|
encrypt: bool,
|
1955
1955
|
seed_phrase: str,
|
1956
1956
|
subaccount_id: str,
|
1957
|
+
bucket_name: str,
|
1957
1958
|
store_node: str = "http://localhost:5001",
|
1958
1959
|
pin_node: str = "https://store.hippius.network",
|
1959
1960
|
substrate_url: str = "wss://rpc.hippius.network",
|
@@ -1966,15 +1967,17 @@ class IPFSClient:
|
|
1966
1967
|
2. Pins to pin_node (remote) for persistence and backup
|
1967
1968
|
3. Publishes to substrate marketplace
|
1968
1969
|
|
1969
|
-
This method automatically manages encryption keys per
|
1970
|
-
- If encrypt=True, it will get or generate an encryption key for the
|
1970
|
+
This method automatically manages encryption keys per account+bucket combination:
|
1971
|
+
- If encrypt=True, it will get or generate an encryption key for the account+bucket
|
1971
1972
|
- Keys are stored in PostgreSQL and versioned (never deleted)
|
1972
|
-
- Always uses the most recent key for
|
1973
|
+
- Always uses the most recent key for an account+bucket combination
|
1973
1974
|
|
1974
1975
|
Args:
|
1975
1976
|
file_path: Path to the file to publish
|
1976
1977
|
encrypt: Whether to encrypt the file before uploading
|
1977
1978
|
seed_phrase: Seed phrase for blockchain transaction signing
|
1979
|
+
subaccount_id: The subaccount/account identifier
|
1980
|
+
bucket_name: The bucket name for key isolation
|
1978
1981
|
store_node: IPFS node URL for initial upload (default: local node)
|
1979
1982
|
pin_node: IPFS node URL for backup pinning (default: remote service)
|
1980
1983
|
substrate_url: the substrate url to connect to for the storage request.
|
@@ -2008,19 +2011,26 @@ class IPFSClient:
|
|
2008
2011
|
key_storage_available = False
|
2009
2012
|
|
2010
2013
|
if key_storage_available:
|
2011
|
-
#
|
2012
|
-
|
2014
|
+
# Create combined key identifier from account+bucket
|
2015
|
+
account_bucket_key = f"{subaccount_id}:{bucket_name}"
|
2016
|
+
|
2017
|
+
# Try to get existing key for this account+bucket combination
|
2018
|
+
existing_key_b64 = await get_key_for_subaccount(account_bucket_key)
|
2013
2019
|
|
2014
2020
|
if existing_key_b64:
|
2015
2021
|
# Use existing key
|
2016
|
-
logger.debug(
|
2022
|
+
logger.debug(
|
2023
|
+
"Using existing encryption key for account+bucket combination"
|
2024
|
+
)
|
2017
2025
|
encryption_key_bytes = base64.b64decode(existing_key_b64)
|
2018
2026
|
encryption_key_used = existing_key_b64
|
2019
2027
|
else:
|
2020
|
-
# Generate and store new key for this
|
2021
|
-
logger.info(
|
2028
|
+
# Generate and store new key for this account+bucket combination
|
2029
|
+
logger.info(
|
2030
|
+
"Generating new encryption key for account+bucket combination"
|
2031
|
+
)
|
2022
2032
|
new_key_b64 = await generate_and_store_key_for_subaccount(
|
2023
|
-
|
2033
|
+
account_bucket_key
|
2024
2034
|
)
|
2025
2035
|
encryption_key_bytes = base64.b64decode(new_key_b64)
|
2026
2036
|
encryption_key_used = new_key_b64
|
@@ -2138,6 +2148,7 @@ class IPFSClient:
|
|
2138
2148
|
cid: str,
|
2139
2149
|
output_path: str,
|
2140
2150
|
subaccount_id: str,
|
2151
|
+
bucket_name: str,
|
2141
2152
|
auto_decrypt: bool = True,
|
2142
2153
|
download_node: str = "http://localhost:5001",
|
2143
2154
|
) -> S3DownloadResult:
|
@@ -2145,16 +2156,17 @@ class IPFSClient:
|
|
2145
2156
|
Download a file from IPFS with automatic decryption.
|
2146
2157
|
|
2147
2158
|
This method uses the download_node for immediate availability and automatically
|
2148
|
-
manages decryption keys per
|
2159
|
+
manages decryption keys per account+bucket combination:
|
2149
2160
|
- Downloads the file from the specified download_node (local by default)
|
2150
|
-
- If auto_decrypt=True, attempts to decrypt using stored keys for the
|
2161
|
+
- If auto_decrypt=True, attempts to decrypt using stored keys for the account+bucket
|
2151
2162
|
- Falls back to client encryption key if key storage is not available
|
2152
2163
|
- Returns the file in decrypted form if decryption succeeds
|
2153
2164
|
|
2154
2165
|
Args:
|
2155
2166
|
cid: Content Identifier (CID) of the file to download
|
2156
2167
|
output_path: Path where the downloaded file will be saved
|
2157
|
-
subaccount_id: The subaccount
|
2168
|
+
subaccount_id: The subaccount/account identifier
|
2169
|
+
bucket_name: The bucket name for key isolation
|
2158
2170
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
2159
2171
|
download_node: IPFS node URL for download (default: local node)
|
2160
2172
|
|
@@ -2233,13 +2245,18 @@ class IPFSClient:
|
|
2233
2245
|
decryption_successful = False
|
2234
2246
|
|
2235
2247
|
if key_storage_available:
|
2236
|
-
#
|
2248
|
+
# Create combined key identifier from account+bucket
|
2249
|
+
account_bucket_key = f"{subaccount_id}:{bucket_name}"
|
2250
|
+
|
2251
|
+
# Try to get the encryption key for this account+bucket combination
|
2237
2252
|
try:
|
2238
|
-
existing_key_b64 = await get_key_for_subaccount(
|
2253
|
+
existing_key_b64 = await get_key_for_subaccount(
|
2254
|
+
account_bucket_key
|
2255
|
+
)
|
2239
2256
|
|
2240
2257
|
if existing_key_b64:
|
2241
2258
|
logger.debug(
|
2242
|
-
"Found encryption key for
|
2259
|
+
"Found encryption key for account+bucket combination, attempting decryption"
|
2243
2260
|
)
|
2244
2261
|
decryption_attempted = True
|
2245
2262
|
encryption_key_used = existing_key_b64
|
@@ -2273,7 +2290,9 @@ class IPFSClient:
|
|
2273
2290
|
)
|
2274
2291
|
# Continue to try fallback decryption
|
2275
2292
|
else:
|
2276
|
-
logger.debug(
|
2293
|
+
logger.debug(
|
2294
|
+
"No encryption key found for account+bucket combination"
|
2295
|
+
)
|
2277
2296
|
|
2278
2297
|
except Exception as e:
|
2279
2298
|
logger.debug(f"Error retrieving key from storage: {e}")
|
@@ -65,7 +65,8 @@ class AsyncIPFSClient:
|
|
65
65
|
files = {"file": (filename, file_content, "application/octet-stream")}
|
66
66
|
# Explicitly set wrap-with-directory=false to prevent wrapping in directory
|
67
67
|
response = await self.client.post(
|
68
|
-
f"{self.api_url}/api/v0/add?wrap-with-directory=false",
|
68
|
+
f"{self.api_url}/api/v0/add?wrap-with-directory=false&cid-version=1",
|
69
|
+
files=files,
|
69
70
|
)
|
70
71
|
response.raise_for_status()
|
71
72
|
return response.json()
|
@@ -85,7 +86,8 @@ class AsyncIPFSClient:
|
|
85
86
|
files = {"file": (filename, data, "application/octet-stream")}
|
86
87
|
# Explicitly set wrap-with-directory=false to prevent wrapping in directory
|
87
88
|
response = await self.client.post(
|
88
|
-
f"{self.api_url}/api/v0/add?wrap-with-directory=false",
|
89
|
+
f"{self.api_url}/api/v0/add?wrap-with-directory=false&cid-version=1",
|
90
|
+
files=files,
|
89
91
|
)
|
90
92
|
response.raise_for_status()
|
91
93
|
return response.json()
|
@@ -346,7 +348,7 @@ class AsyncIPFSClient:
|
|
346
348
|
|
347
349
|
# Make the request with directory flags
|
348
350
|
response = await self.client.post(
|
349
|
-
f"{self.api_url}/api/v0/add?recursive=true&wrap-with-directory=true",
|
351
|
+
f"{self.api_url}/api/v0/add?recursive=true&wrap-with-directory=true&cid-version=1",
|
350
352
|
files=files,
|
351
353
|
timeout=300.0, # 5 minute timeout for directory uploads
|
352
354
|
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|