hippius 0.2.20__py3-none-any.whl → 0.2.22__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.
- {hippius-0.2.20.dist-info → hippius-0.2.22.dist-info}/METADATA +1 -1
- {hippius-0.2.20.dist-info → hippius-0.2.22.dist-info}/RECORD +9 -9
- hippius_sdk/__init__.py +1 -1
- hippius_sdk/client.py +28 -6
- hippius_sdk/ipfs.py +153 -89
- hippius_sdk/key_storage.py +3 -3
- hippius_sdk/substrate.py +0 -23
- {hippius-0.2.20.dist-info → hippius-0.2.22.dist-info}/WHEEL +0 -0
- {hippius-0.2.20.dist-info → hippius-0.2.22.dist-info}/entry_points.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
|
-
hippius_sdk/__init__.py,sha256=
|
1
|
+
hippius_sdk/__init__.py,sha256=iVksJT4wiSP49OCa5MhECb_uiiL4zUJg6vGkdhd83J8,1474
|
2
2
|
hippius_sdk/cli.py,sha256=aqKOYSBSWt7UhcpFt7wf9yIPJ3bznpsJ6ehOnuZ4usI,18235
|
3
3
|
hippius_sdk/cli_assets.py,sha256=V3MX63QTiex6mCp0VDXQJ7cagm5v1s4xtsu8c1O4G_k,371
|
4
4
|
hippius_sdk/cli_handlers.py,sha256=TQNE9os87gRzRKLEO-SIwhFnBtEFMiaSESv-Bu7omfo,128909
|
5
5
|
hippius_sdk/cli_parser.py,sha256=z7UvgWvvy04ey-R56qZiCqYc_9RaNq1rVDkQyXoK3JU,21100
|
6
6
|
hippius_sdk/cli_rich.py,sha256=_jTBYMdHi2--fIVwoeNi-EtkdOb6Zy_O2TUiGvU3O7s,7324
|
7
|
-
hippius_sdk/client.py,sha256=
|
7
|
+
hippius_sdk/client.py,sha256=Hj87gu5kapNM0V0-EgwJBsuA63HTsVHFGr2VnmwFH6I,22298
|
8
8
|
hippius_sdk/config.py,sha256=Hf_aUYzG9ylzqauA_ABUSSB5mBTYbp-VtB36VQt2XDw,21981
|
9
9
|
hippius_sdk/db/README.md,sha256=okDeI1qgkaZqXSlJ8L0xIE4UpuxO-qEGPIbXUvSHQjU,2030
|
10
10
|
hippius_sdk/db/env.db.template,sha256=_6hEC3IvkzCDOAzG1_yJUKRUfCTMciNaJUicZpMCat4,217
|
@@ -12,12 +12,12 @@ hippius_sdk/db/migrations/20241201000001_create_key_storage_tables.sql,sha256=mi
|
|
12
12
|
hippius_sdk/db/setup_database.sh,sha256=bDeIiTnMuX0AYCdefAfEI1CyXho6A6kLzufsDZFSXpE,3118
|
13
13
|
hippius_sdk/db_utils.py,sha256=-x0rbN0as7Tn3PJPZBYCgreZe52FLH40ppA1TLxsg90,1851
|
14
14
|
hippius_sdk/errors.py,sha256=LScJJmawVAx7aRzqqQguYSkf9iazSjEQEBNlD_GXZ6Y,1589
|
15
|
-
hippius_sdk/ipfs.py,sha256=
|
15
|
+
hippius_sdk/ipfs.py,sha256=0ev7uRubsVDkr0003NVk4b9PnKAFSWVl4U9Yubs8kYk,93900
|
16
16
|
hippius_sdk/ipfs_core.py,sha256=eOOgLoyP9mvwndnCjldnTc7z94ImYCXY3nm7JU3e_Mo,12676
|
17
|
-
hippius_sdk/key_storage.py,sha256
|
18
|
-
hippius_sdk/substrate.py,sha256
|
17
|
+
hippius_sdk/key_storage.py,sha256=oxfRRQXu8XVncUjhKJJ8rsc81JAkaj9MqZEwQa96idc,9474
|
18
|
+
hippius_sdk/substrate.py,sha256=-lIavQkfE6Kw2KzllH9IMgNkzl2d6vEmU3RmwKNJQvc,48093
|
19
19
|
hippius_sdk/utils.py,sha256=rJ611yvwKSyiBpYU3w-SuyQxoghMGU-ePuslrPv5H5g,7388
|
20
|
-
hippius-0.2.
|
21
|
-
hippius-0.2.
|
22
|
-
hippius-0.2.
|
23
|
-
hippius-0.2.
|
20
|
+
hippius-0.2.22.dist-info/METADATA,sha256=bBkLq84px0hNLf4JXZKi1tGC1YrfN8dU_ZPzmDdHTUk,30088
|
21
|
+
hippius-0.2.22.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
22
|
+
hippius-0.2.22.dist-info/entry_points.txt,sha256=bFAZjW3vndretf9-8s587jA2ebMVI7puhn_lVs8jPc8,149
|
23
|
+
hippius-0.2.22.dist-info/RECORD,,
|
hippius_sdk/__init__.py
CHANGED
@@ -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.22"
|
30
30
|
__all__ = [
|
31
31
|
"HippiusClient",
|
32
32
|
"IPFSClient",
|
hippius_sdk/client.py
CHANGED
@@ -512,15 +512,26 @@ class HippiusClient:
|
|
512
512
|
)
|
513
513
|
|
514
514
|
async def s3_publish(
|
515
|
-
self,
|
515
|
+
self,
|
516
|
+
file_path: str,
|
517
|
+
encrypt: bool,
|
518
|
+
seed_phrase: str,
|
519
|
+
store_node: str = "http://localhost:5001",
|
520
|
+
pin_node: str = "https://store.hippius.network",
|
516
521
|
) -> S3PublishResult:
|
517
522
|
"""
|
518
523
|
Publish a file to IPFS and the Hippius marketplace in one operation.
|
519
524
|
|
525
|
+
Uses a two-node architecture for optimal performance:
|
526
|
+
1. Uploads to store_node (local) for immediate availability
|
527
|
+
2. Pins to pin_node (remote) for persistence and backup
|
528
|
+
|
520
529
|
Args:
|
521
530
|
file_path: Path to the file to publish
|
522
531
|
encrypt: Whether to encrypt the file before uploading
|
523
532
|
seed_phrase: Seed phrase for blockchain transaction signing
|
533
|
+
store_node: IPFS node URL for initial upload (default: local node)
|
534
|
+
pin_node: IPFS node URL for backup pinning (default: remote service)
|
524
535
|
|
525
536
|
Returns:
|
526
537
|
S3PublishResult: Object containing CID, file info, and transaction hash
|
@@ -531,16 +542,24 @@ class HippiusClient:
|
|
531
542
|
FileNotFoundError: If the file doesn't exist
|
532
543
|
ValueError: If encryption is requested but not available
|
533
544
|
"""
|
534
|
-
return await self.ipfs_client.s3_publish(
|
545
|
+
return await self.ipfs_client.s3_publish(
|
546
|
+
file_path, encrypt, seed_phrase, store_node, pin_node
|
547
|
+
)
|
535
548
|
|
536
549
|
async def s3_download(
|
537
|
-
self,
|
550
|
+
self,
|
551
|
+
cid: str,
|
552
|
+
output_path: str,
|
553
|
+
seed_phrase: str,
|
554
|
+
auto_decrypt: bool = True,
|
555
|
+
download_node: str = "http://localhost:5001",
|
538
556
|
) -> S3DownloadResult:
|
539
557
|
"""
|
540
558
|
Download a file from IPFS with automatic decryption.
|
541
559
|
|
542
|
-
This method
|
543
|
-
|
560
|
+
This method uses the download_node for immediate availability and automatically
|
561
|
+
manages decryption keys per seed phrase:
|
562
|
+
- Downloads the file from the specified download_node (local by default)
|
544
563
|
- If auto_decrypt=True, attempts to decrypt using stored keys for the seed phrase
|
545
564
|
- Falls back to client encryption key if key storage is not available
|
546
565
|
- Returns the file in decrypted form if decryption succeeds
|
@@ -550,6 +569,7 @@ class HippiusClient:
|
|
550
569
|
output_path: Path where the downloaded file will be saved
|
551
570
|
seed_phrase: Seed phrase to use for retrieving decryption keys
|
552
571
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
572
|
+
download_node: IPFS node URL for download (default: local node)
|
553
573
|
|
554
574
|
Returns:
|
555
575
|
S3DownloadResult: Object containing download info and decryption status
|
@@ -559,4 +579,6 @@ class HippiusClient:
|
|
559
579
|
FileNotFoundError: If the output directory doesn't exist
|
560
580
|
ValueError: If decryption fails
|
561
581
|
"""
|
562
|
-
return await self.ipfs_client.s3_download(
|
582
|
+
return await self.ipfs_client.s3_download(
|
583
|
+
cid, output_path, seed_phrase, auto_decrypt, download_node
|
584
|
+
)
|
hippius_sdk/ipfs.py
CHANGED
@@ -13,17 +13,18 @@ import tempfile
|
|
13
13
|
import time
|
14
14
|
import uuid
|
15
15
|
from typing import Any, Callable, Dict, List, Optional
|
16
|
-
|
17
|
-
generate_and_store_key_for_seed,
|
18
|
-
get_key_for_seed,
|
19
|
-
is_key_storage_enabled,
|
20
|
-
)
|
16
|
+
|
21
17
|
import httpx
|
22
18
|
from pydantic import BaseModel
|
23
19
|
|
24
20
|
from hippius_sdk.config import get_config_value, get_encryption_key
|
25
21
|
from hippius_sdk.errors import HippiusIPFSError, HippiusSubstrateError
|
26
22
|
from hippius_sdk.ipfs_core import AsyncIPFSClient
|
23
|
+
from hippius_sdk.key_storage import (
|
24
|
+
generate_and_store_key_for_seed,
|
25
|
+
get_key_for_seed,
|
26
|
+
is_key_storage_enabled,
|
27
|
+
)
|
27
28
|
from hippius_sdk.substrate import FileInput, SubstrateClient
|
28
29
|
from hippius_sdk.utils import format_cid, format_size
|
29
30
|
|
@@ -1805,9 +1806,6 @@ class IPFSClient:
|
|
1805
1806
|
"""
|
1806
1807
|
print(f"Starting deletion process for metadata CID: {metadata_cid}")
|
1807
1808
|
|
1808
|
-
# Try to download and process metadata file and chunks
|
1809
|
-
ipfs_failure = False
|
1810
|
-
metadata_error = False
|
1811
1809
|
chunks = []
|
1812
1810
|
|
1813
1811
|
try:
|
@@ -1929,11 +1927,21 @@ class IPFSClient:
|
|
1929
1927
|
return True
|
1930
1928
|
|
1931
1929
|
async def s3_publish(
|
1932
|
-
self,
|
1930
|
+
self,
|
1931
|
+
file_path: str,
|
1932
|
+
encrypt: bool,
|
1933
|
+
seed_phrase: str,
|
1934
|
+
store_node: str = "http://localhost:5001",
|
1935
|
+
pin_node: str = "https://store.hippius.network",
|
1933
1936
|
) -> S3PublishResult:
|
1934
1937
|
"""
|
1935
1938
|
Publish a file to IPFS and the Hippius marketplace in one operation.
|
1936
1939
|
|
1940
|
+
This method uses a two-node architecture for optimal performance:
|
1941
|
+
1. Uploads to store_node (local) for immediate availability
|
1942
|
+
2. Pins to pin_node (remote) for persistence and backup
|
1943
|
+
3. Publishes to substrate marketplace
|
1944
|
+
|
1937
1945
|
This method automatically manages encryption keys per seed phrase:
|
1938
1946
|
- If encrypt=True, it will get or generate an encryption key for the seed phrase
|
1939
1947
|
- Keys are stored in PostgreSQL and versioned (never deleted)
|
@@ -1943,6 +1951,8 @@ class IPFSClient:
|
|
1943
1951
|
file_path: Path to the file to publish
|
1944
1952
|
encrypt: Whether to encrypt the file before uploading
|
1945
1953
|
seed_phrase: Seed phrase for blockchain transaction signing
|
1954
|
+
store_node: IPFS node URL for initial upload (default: local node)
|
1955
|
+
pin_node: IPFS node URL for backup pinning (default: remote service)
|
1946
1956
|
|
1947
1957
|
Returns:
|
1948
1958
|
S3PublishResult: Object containing CID, file info, and transaction hash
|
@@ -2026,18 +2036,26 @@ class IPFSClient:
|
|
2026
2036
|
else None
|
2027
2037
|
)
|
2028
2038
|
|
2029
|
-
#
|
2039
|
+
# Step 1: Upload to store_node (local) for immediate availability
|
2030
2040
|
try:
|
2031
|
-
|
2041
|
+
store_client = AsyncIPFSClient(api_url=store_node)
|
2042
|
+
result = await store_client.add_file(file_path)
|
2032
2043
|
cid = result["Hash"]
|
2044
|
+
logger.info(f"File uploaded to store node {store_node} with CID: {cid}")
|
2033
2045
|
except Exception as e:
|
2034
|
-
raise HippiusIPFSError(
|
2046
|
+
raise HippiusIPFSError(
|
2047
|
+
f"Failed to upload file to store node {store_node}: {str(e)}"
|
2048
|
+
)
|
2035
2049
|
|
2036
|
-
#
|
2050
|
+
# Step 2: Pin to pin_node (remote) for persistence and backup
|
2037
2051
|
try:
|
2038
|
-
|
2052
|
+
pin_client = AsyncIPFSClient(api_url=pin_node)
|
2053
|
+
await pin_client.pin(cid)
|
2054
|
+
logger.info(f"File pinned to backup node {pin_node}")
|
2039
2055
|
except Exception as e:
|
2040
|
-
raise HippiusIPFSError(
|
2056
|
+
raise HippiusIPFSError(
|
2057
|
+
f"Failed to pin file to store node {store_node}: {str(e)}"
|
2058
|
+
)
|
2041
2059
|
|
2042
2060
|
# Publish to substrate marketplace
|
2043
2061
|
try:
|
@@ -2087,13 +2105,19 @@ class IPFSClient:
|
|
2087
2105
|
)
|
2088
2106
|
|
2089
2107
|
async def s3_download(
|
2090
|
-
self,
|
2108
|
+
self,
|
2109
|
+
cid: str,
|
2110
|
+
output_path: str,
|
2111
|
+
seed_phrase: str,
|
2112
|
+
auto_decrypt: bool = True,
|
2113
|
+
download_node: str = "http://localhost:5001",
|
2091
2114
|
) -> S3DownloadResult:
|
2092
2115
|
"""
|
2093
2116
|
Download a file from IPFS with automatic decryption.
|
2094
2117
|
|
2095
|
-
This method
|
2096
|
-
|
2118
|
+
This method uses the download_node for immediate availability and automatically
|
2119
|
+
manages decryption keys per seed phrase:
|
2120
|
+
- Downloads the file from the specified download_node (local by default)
|
2097
2121
|
- If auto_decrypt=True, attempts to decrypt using stored keys for the seed phrase
|
2098
2122
|
- Falls back to client encryption key if key storage is not available
|
2099
2123
|
- Returns the file in decrypted form if decryption succeeds
|
@@ -2103,6 +2127,7 @@ class IPFSClient:
|
|
2103
2127
|
output_path: Path where the downloaded file will be saved
|
2104
2128
|
seed_phrase: Seed phrase to use for retrieving decryption keys
|
2105
2129
|
auto_decrypt: Whether to attempt automatic decryption (default: True)
|
2130
|
+
download_node: IPFS node URL for download (default: local node)
|
2106
2131
|
|
2107
2132
|
Returns:
|
2108
2133
|
S3DownloadResult: Object containing download info and decryption status
|
@@ -2114,24 +2139,27 @@ class IPFSClient:
|
|
2114
2139
|
"""
|
2115
2140
|
start_time = time.time()
|
2116
2141
|
|
2117
|
-
# Download the file
|
2142
|
+
# Download the file directly from the specified download_node
|
2118
2143
|
try:
|
2119
2144
|
# Create parent directories if they don't exist
|
2120
2145
|
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
|
2121
2146
|
|
2122
|
-
|
2123
|
-
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2147
|
+
download_client = AsyncIPFSClient(api_url=download_node)
|
2148
|
+
|
2149
|
+
download_url = f"{download_node.rstrip('/')}/api/v0/cat?arg={cid}"
|
2150
|
+
async with download_client.client.stream("POST", download_url) as response:
|
2151
|
+
response.raise_for_status()
|
2152
|
+
|
2153
|
+
with open(output_path, "wb") as f:
|
2154
|
+
async for chunk in response.aiter_bytes(chunk_size=8192):
|
2155
|
+
f.write(chunk)
|
2129
2156
|
|
2130
|
-
|
2131
|
-
raise HippiusIPFSError("Download failed")
|
2157
|
+
logger.info(f"File downloaded from {download_node} with CID: {cid}")
|
2132
2158
|
|
2133
2159
|
except Exception as e:
|
2134
|
-
raise HippiusIPFSError(
|
2160
|
+
raise HippiusIPFSError(
|
2161
|
+
f"Failed to download file from {download_node}: {str(e)}"
|
2162
|
+
)
|
2135
2163
|
|
2136
2164
|
# Get file info after download
|
2137
2165
|
size_bytes = os.path.getsize(output_path)
|
@@ -2154,77 +2182,113 @@ class IPFSClient:
|
|
2154
2182
|
with open(output_path, "rb") as f:
|
2155
2183
|
file_data = f.read()
|
2156
2184
|
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
2185
|
+
# Check if file is empty - this indicates a problem
|
2186
|
+
if len(file_data) == 0:
|
2187
|
+
logger.error(f"Downloaded file is empty (0 bytes) for CID: {cid}")
|
2188
|
+
raise HippiusIPFSError(
|
2189
|
+
f"File not available: Downloaded 0 bytes for CID {cid}. "
|
2190
|
+
f"File may not exist on download node {download_node}. "
|
2191
|
+
f"Download URL: {download_url}"
|
2192
|
+
)
|
2193
|
+
elif (
|
2194
|
+
len(file_data) < 40
|
2195
|
+
): # PyNaCl encrypted data is at least 40 bytes (24-byte nonce + 16-byte auth tag + data)
|
2196
|
+
logger.info(
|
2197
|
+
f"File too small to be encrypted ({len(file_data)} bytes), treating as plaintext"
|
2198
|
+
)
|
2199
|
+
decrypted = False
|
2200
|
+
encryption_key_used = None
|
2201
|
+
else:
|
2202
|
+
# File has content, attempt decryption if requested
|
2203
|
+
decryption_attempted = False
|
2204
|
+
decryption_successful = False
|
2164
2205
|
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2206
|
+
if key_storage_available:
|
2207
|
+
# Try to get the encryption key for this seed phrase
|
2208
|
+
try:
|
2209
|
+
existing_key_b64 = await get_key_for_seed(seed_phrase)
|
2169
2210
|
|
2170
|
-
|
2171
|
-
|
2172
|
-
|
2211
|
+
if existing_key_b64:
|
2212
|
+
logger.debug(
|
2213
|
+
"Found encryption key for seed phrase, attempting decryption"
|
2214
|
+
)
|
2215
|
+
decryption_attempted = True
|
2216
|
+
encryption_key_used = existing_key_b64
|
2173
2217
|
|
2174
|
-
|
2175
|
-
|
2176
|
-
|
2218
|
+
# Attempt decryption with the stored key
|
2219
|
+
try:
|
2220
|
+
import nacl.secret
|
2177
2221
|
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2222
|
+
encryption_key_bytes = base64.b64decode(
|
2223
|
+
existing_key_b64
|
2224
|
+
)
|
2225
|
+
box = nacl.secret.SecretBox(encryption_key_bytes)
|
2226
|
+
decrypted_data = box.decrypt(file_data)
|
2227
|
+
|
2228
|
+
# Write the decrypted data back to the file
|
2229
|
+
with open(output_path, "wb") as f:
|
2230
|
+
f.write(decrypted_data)
|
2231
|
+
|
2232
|
+
decryption_successful = True
|
2233
|
+
decrypted = True
|
2234
|
+
size_bytes = len(
|
2235
|
+
decrypted_data
|
2236
|
+
) # Update size to decrypted size
|
2237
|
+
logger.info(
|
2238
|
+
"Successfully decrypted file using stored key"
|
2239
|
+
)
|
2181
2240
|
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2241
|
+
except Exception as decrypt_error:
|
2242
|
+
logger.debug(
|
2243
|
+
f"Decryption failed with stored key: {decrypt_error}"
|
2244
|
+
)
|
2245
|
+
# Continue to try fallback decryption
|
2246
|
+
else:
|
2247
|
+
logger.debug("No encryption key found for seed phrase")
|
2186
2248
|
|
2187
|
-
|
2188
|
-
|
2189
|
-
# Continue to try fallback decryption
|
2190
|
-
else:
|
2191
|
-
logger.debug("No encryption key found for seed phrase")
|
2249
|
+
except Exception as e:
|
2250
|
+
logger.debug(f"Error retrieving key from storage: {e}")
|
2192
2251
|
|
2193
|
-
|
2194
|
-
|
2252
|
+
# If key storage decryption failed or wasn't available, try client encryption key
|
2253
|
+
if not decryption_successful and self.encryption_available:
|
2254
|
+
logger.debug("Attempting decryption with client encryption key")
|
2255
|
+
decryption_attempted = True
|
2195
2256
|
|
2196
|
-
|
2197
|
-
|
2198
|
-
logger.debug("Attempting decryption with client encryption key")
|
2199
|
-
decryption_attempted = True
|
2257
|
+
try:
|
2258
|
+
decrypted_data = self.decrypt_data(file_data)
|
2200
2259
|
|
2201
|
-
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2260
|
+
# Write the decrypted data back to the file
|
2261
|
+
with open(output_path, "wb") as f:
|
2262
|
+
f.write(decrypted_data)
|
2263
|
+
|
2264
|
+
decryption_successful = True
|
2265
|
+
decrypted = True
|
2266
|
+
size_bytes = len(
|
2267
|
+
decrypted_data
|
2268
|
+
) # Update size to decrypted size
|
2269
|
+
|
2270
|
+
# Store the encryption key for the result
|
2271
|
+
encryption_key_used = (
|
2272
|
+
base64.b64encode(self.encryption_key).decode("utf-8")
|
2273
|
+
if self.encryption_key
|
2274
|
+
else None
|
2275
|
+
)
|
2276
|
+
logger.info(
|
2277
|
+
"Successfully decrypted file using client encryption key"
|
2278
|
+
)
|
2219
2279
|
|
2220
|
-
|
2221
|
-
|
2280
|
+
except Exception as decrypt_error:
|
2281
|
+
logger.debug(
|
2282
|
+
f"Decryption failed with client key: {decrypt_error}"
|
2283
|
+
)
|
2222
2284
|
|
2223
|
-
|
2224
|
-
|
2225
|
-
|
2226
|
-
|
2227
|
-
|
2285
|
+
# Log final decryption status
|
2286
|
+
if decryption_attempted and not decryption_successful:
|
2287
|
+
logger.info(
|
2288
|
+
"File may not be encrypted or decryption keys don't match"
|
2289
|
+
)
|
2290
|
+
elif not decryption_attempted:
|
2291
|
+
logger.debug("No decryption attempted - no keys available")
|
2228
2292
|
|
2229
2293
|
return S3DownloadResult(
|
2230
2294
|
cid=cid,
|
hippius_sdk/key_storage.py
CHANGED
@@ -234,7 +234,7 @@ _default_storage = None
|
|
234
234
|
def is_key_storage_enabled() -> bool:
|
235
235
|
"""
|
236
236
|
Check if key storage is enabled and available.
|
237
|
-
|
237
|
+
|
238
238
|
Returns True if:
|
239
239
|
1. Explicitly enabled in config, OR
|
240
240
|
2. asyncpg is available (key_storage extra installed) AND not explicitly disabled
|
@@ -243,11 +243,11 @@ def is_key_storage_enabled() -> bool:
|
|
243
243
|
config_value = get_config_value("key_storage", "enabled", None)
|
244
244
|
if config_value is False:
|
245
245
|
return False
|
246
|
-
|
246
|
+
|
247
247
|
# If explicitly enabled, return True
|
248
248
|
if config_value is True:
|
249
249
|
return True
|
250
|
-
|
250
|
+
|
251
251
|
# If not set in config, auto-detect based on asyncpg availability
|
252
252
|
# This allows users who install [key_storage] extra to use it without manual config
|
253
253
|
return ASYNCPG_AVAILABLE
|
hippius_sdk/substrate.py
CHANGED
@@ -1223,29 +1223,6 @@ class SubstrateClient:
|
|
1223
1223
|
Returns:
|
1224
1224
|
str: Transaction hash or status message
|
1225
1225
|
"""
|
1226
|
-
# First check if this CID exists in the user's storage requests
|
1227
|
-
try:
|
1228
|
-
cid_exists = await self.check_storage_request_exists(cid)
|
1229
|
-
if not cid_exists:
|
1230
|
-
raise HippiusAlreadyDeletedError(
|
1231
|
-
f"CID {cid} is not found in storage requests - may already be deleted"
|
1232
|
-
)
|
1233
|
-
except Exception as e:
|
1234
|
-
if not isinstance(e, HippiusAlreadyDeletedError):
|
1235
|
-
# If there was an error checking, but not our custom exception, wrap it
|
1236
|
-
raise HippiusSubstrateConnectionError(
|
1237
|
-
f"Error checking if CID exists: {str(e)}"
|
1238
|
-
)
|
1239
|
-
else:
|
1240
|
-
# Re-raise our custom exception
|
1241
|
-
raise
|
1242
|
-
|
1243
|
-
# Continue with cancellation if it exists
|
1244
|
-
if not self._ensure_keypair(seed_phrase):
|
1245
|
-
raise HippiusSubstrateAuthError(
|
1246
|
-
"Valid seed phrase must be provided or available in config"
|
1247
|
-
)
|
1248
|
-
|
1249
1226
|
# Initialize Substrate connection with seed phrase if needed
|
1250
1227
|
if not self._substrate:
|
1251
1228
|
self.connect(seed_phrase)
|
File without changes
|
File without changes
|