weil-wallet 0.1.0__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.
- weil_wallet-0.1.0/PKG-INFO +11 -0
- weil_wallet-0.1.0/__init__.py +52 -0
- weil_wallet-0.1.0/api/__init__.py +6 -0
- weil_wallet-0.1.0/api/platform_api.py +75 -0
- weil_wallet-0.1.0/api/request.py +76 -0
- weil_wallet-0.1.0/client.py +957 -0
- weil_wallet-0.1.0/constants.py +9 -0
- weil_wallet-0.1.0/contract.py +65 -0
- weil_wallet-0.1.0/derived_wallet.py +169 -0
- weil_wallet-0.1.0/errors.py +26 -0
- weil_wallet-0.1.0/pensieve.py +242 -0
- weil_wallet-0.1.0/py.typed +1 -0
- weil_wallet-0.1.0/pyproject.toml +30 -0
- weil_wallet-0.1.0/secure_native/CMakeLists.txt +26 -0
- weil_wallet-0.1.0/secure_native/JAVA.md +39 -0
- weil_wallet-0.1.0/secure_native/README.md +63 -0
- weil_wallet-0.1.0/secure_native/jsmn.h +43 -0
- weil_wallet-0.1.0/secure_native/python_binding.c +52 -0
- weil_wallet-0.1.0/secure_native/weil_secure_wallet.c +275 -0
- weil_wallet-0.1.0/secure_native/weil_secure_wallet.h +75 -0
- weil_wallet-0.1.0/secure_wallet.py +191 -0
- weil_wallet-0.1.0/setup.cfg +4 -0
- weil_wallet-0.1.0/setup.py +20 -0
- weil_wallet-0.1.0/streaming.py +16 -0
- weil_wallet-0.1.0/transaction.py +114 -0
- weil_wallet-0.1.0/utils.py +55 -0
- weil_wallet-0.1.0/wallet.py +716 -0
- weil_wallet-0.1.0/weil_wallet.egg-info/PKG-INFO +11 -0
- weil_wallet-0.1.0/weil_wallet.egg-info/SOURCES.txt +80 -0
- weil_wallet-0.1.0/weil_wallet.egg-info/dependency_links.txt +1 -0
- weil_wallet-0.1.0/weil_wallet.egg-info/requires.txt +7 -0
- weil_wallet-0.1.0/weil_wallet.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: weil-wallet
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for building clients that interact with smart contracts on WeilChain
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Requires-Dist: httpx>=0.27.0
|
|
7
|
+
Requires-Dist: coincurve>=21.0.0
|
|
8
|
+
Requires-Dist: bip_utils>=2.9.0
|
|
9
|
+
Requires-Dist: eth-hash[pycryptodome]>=0.5.0
|
|
10
|
+
Provides-Extra: agents
|
|
11
|
+
Requires-Dist: langchain>=0.1.0; extra == "agents"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Weil Wallet SDK for Python — initialize wallet and sign transactions on WeilChain."""
|
|
2
|
+
|
|
3
|
+
from .client import WeilClient, WeilContractClient
|
|
4
|
+
from .constants import (
|
|
5
|
+
AUDIT_APPLET_SVC_NAME,
|
|
6
|
+
IDENTITY_APPLET_SVC_PREFIX,
|
|
7
|
+
PENSIEVE_APPLET_SVC_NAME,
|
|
8
|
+
PUBLISHER_APPLET_SVC_NAME,
|
|
9
|
+
)
|
|
10
|
+
from .contract import ContractId, contract_id_from_str
|
|
11
|
+
from .derived_wallet import (
|
|
12
|
+
MnemonicWallet,
|
|
13
|
+
WalletAccount,
|
|
14
|
+
create_wallet,
|
|
15
|
+
load_wallet,
|
|
16
|
+
pubkey_to_derived_address,
|
|
17
|
+
)
|
|
18
|
+
from .errors import InvalidContractIdError, WalletNotPermittedError
|
|
19
|
+
from .pensieve import Pensieve
|
|
20
|
+
from .streaming import ByteStream
|
|
21
|
+
from .transaction import BaseTransaction, TransactionResult, TransactionStatus, TransactionHeader
|
|
22
|
+
from .wallet import OrgInfo, OrgMembership, SelectedAccount, Wallet
|
|
23
|
+
from .secure_wallet import harden_process
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"WeilClient",
|
|
27
|
+
"WeilContractClient",
|
|
28
|
+
"ContractId",
|
|
29
|
+
"contract_id_from_str",
|
|
30
|
+
"InvalidContractIdError",
|
|
31
|
+
"WalletNotPermittedError",
|
|
32
|
+
"Pensieve",
|
|
33
|
+
"PENSIEVE_APPLET_SVC_NAME",
|
|
34
|
+
"AUDIT_APPLET_SVC_NAME",
|
|
35
|
+
"IDENTITY_APPLET_SVC_PREFIX",
|
|
36
|
+
"PUBLISHER_APPLET_SVC_NAME",
|
|
37
|
+
"ByteStream",
|
|
38
|
+
"BaseTransaction",
|
|
39
|
+
"TransactionResult",
|
|
40
|
+
"TransactionStatus",
|
|
41
|
+
"TransactionHeader",
|
|
42
|
+
"OrgInfo",
|
|
43
|
+
"OrgMembership",
|
|
44
|
+
"SelectedAccount",
|
|
45
|
+
"Wallet",
|
|
46
|
+
"harden_process",
|
|
47
|
+
"MnemonicWallet",
|
|
48
|
+
"WalletAccount",
|
|
49
|
+
"create_wallet",
|
|
50
|
+
"load_wallet",
|
|
51
|
+
"pubkey_to_derived_address",
|
|
52
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Platform API: submit transaction (normal and streaming)."""
|
|
2
|
+
|
|
3
|
+
from typing import AsyncIterator
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ..transaction import TransactionResult
|
|
8
|
+
from ..utils import compress
|
|
9
|
+
from .request import SubmitTxnRequest
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PlatformApi:
|
|
13
|
+
"""Submit transactions to the WeilChain platform."""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
async def _submit_transaction_inner(
|
|
17
|
+
payload: SubmitTxnRequest,
|
|
18
|
+
client: httpx.AsyncClient,
|
|
19
|
+
*,
|
|
20
|
+
is_non_blocking: bool,
|
|
21
|
+
) -> httpx.Response:
|
|
22
|
+
"""GZIP-compress and POST the transaction payload; raise on HTTP error."""
|
|
23
|
+
payload_dict = payload.to_payload_dict()
|
|
24
|
+
tx_payload = compress(payload_dict)
|
|
25
|
+
|
|
26
|
+
files = {
|
|
27
|
+
"transaction": ("transaction_data", tx_payload, "application/octet-stream")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
headers = {}
|
|
31
|
+
|
|
32
|
+
if is_non_blocking:
|
|
33
|
+
headers["x-non-blocking"] = "true"
|
|
34
|
+
|
|
35
|
+
response = await client.post(
|
|
36
|
+
"/contracts/execute_smartcontract", files=files, headers=headers
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
if not response.is_success:
|
|
40
|
+
body = response.text[:500] if response.text else ""
|
|
41
|
+
|
|
42
|
+
raise RuntimeError(
|
|
43
|
+
f"failed to submit the transaction: HTTP {response.status_code} {body}"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return response
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
async def submit_transaction(
|
|
50
|
+
payload: SubmitTxnRequest,
|
|
51
|
+
client: httpx.AsyncClient,
|
|
52
|
+
*,
|
|
53
|
+
is_non_blocking: bool = False,
|
|
54
|
+
) -> TransactionResult:
|
|
55
|
+
"""Submit and return the parsed TransactionResult."""
|
|
56
|
+
response = await PlatformApi._submit_transaction_inner(
|
|
57
|
+
payload, client, is_non_blocking=is_non_blocking
|
|
58
|
+
)
|
|
59
|
+
data = response.json()
|
|
60
|
+
return TransactionResult.from_dict(data)
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
async def submit_transaction_with_streaming(
|
|
64
|
+
payload: SubmitTxnRequest,
|
|
65
|
+
client: httpx.AsyncClient,
|
|
66
|
+
*,
|
|
67
|
+
is_non_blocking: bool = False,
|
|
68
|
+
) -> AsyncIterator[bytes]:
|
|
69
|
+
"""Submit and return an async iterator of response body chunks."""
|
|
70
|
+
response = await PlatformApi._submit_transaction_inner(
|
|
71
|
+
payload, client, is_non_blocking=is_non_blocking
|
|
72
|
+
)
|
|
73
|
+
async for chunk in response.aiter_bytes():
|
|
74
|
+
if chunk:
|
|
75
|
+
yield chunk
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Request types for the platform API (submit transaction)."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Optional
|
|
5
|
+
|
|
6
|
+
from ..contract import ContractId
|
|
7
|
+
from ..transaction import TransactionHeader
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class Verifier:
|
|
12
|
+
"""Signature verifier strategy tag sent with every transaction."""
|
|
13
|
+
|
|
14
|
+
ty: str = "DefaultVerifier"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class UserTransaction:
|
|
19
|
+
"""The user-visible part of a transaction: which contract method to call and with what args."""
|
|
20
|
+
|
|
21
|
+
ty: str = "SmartContractExecutor"
|
|
22
|
+
contract_address: Optional[ContractId] = None
|
|
23
|
+
contract_method: str = ""
|
|
24
|
+
contract_input_bytes: Optional[str] = None
|
|
25
|
+
should_hide_args: bool = True
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class Transaction:
|
|
30
|
+
"""Full transaction envelope: header, verifier, and user payload."""
|
|
31
|
+
|
|
32
|
+
is_xpod: bool = False
|
|
33
|
+
txn_header: Optional[TransactionHeader] = None
|
|
34
|
+
verifier: Optional[Verifier] = None
|
|
35
|
+
user_txn: Optional[UserTransaction] = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class SubmitTxnRequest:
|
|
40
|
+
"""Top-level request wrapper submitted to the platform API."""
|
|
41
|
+
|
|
42
|
+
transaction: Optional[Transaction] = None
|
|
43
|
+
|
|
44
|
+
def to_payload_dict(self) -> dict[str, Any]:
|
|
45
|
+
"""Build the JSON-serializable payload (with 'type' for serde compatibility)."""
|
|
46
|
+
txn = self.transaction
|
|
47
|
+
if not txn or not txn.txn_header or not txn.verifier or not txn.user_txn:
|
|
48
|
+
raise ValueError("incomplete transaction")
|
|
49
|
+
h = txn.txn_header
|
|
50
|
+
return {
|
|
51
|
+
"transaction": {
|
|
52
|
+
"is_xpod": txn.is_xpod,
|
|
53
|
+
"txn_header": {
|
|
54
|
+
"nonce": h.nonce,
|
|
55
|
+
"public_key": h.public_key,
|
|
56
|
+
"from_addr": h.from_addr,
|
|
57
|
+
"to_addr": h.to_addr,
|
|
58
|
+
"signature": h.signature,
|
|
59
|
+
"weilpod_counter": h.weilpod_counter,
|
|
60
|
+
"creation_time": h.creation_time,
|
|
61
|
+
"salt": h.salt,
|
|
62
|
+
# Covered by the signature -- the node rebuilds the digest
|
|
63
|
+
# from what actually arrives, so omitting this would make
|
|
64
|
+
# every org-bearing transaction fail verification.
|
|
65
|
+
"org": h.org.to_dict() if h.org else None,
|
|
66
|
+
},
|
|
67
|
+
"verifier": {"type": txn.verifier.ty},
|
|
68
|
+
"user_txn": {
|
|
69
|
+
"type": txn.user_txn.ty,
|
|
70
|
+
"contract_address": str(txn.user_txn.contract_address),
|
|
71
|
+
"contract_method": txn.user_txn.contract_method,
|
|
72
|
+
"contract_input_bytes": txn.user_txn.contract_input_bytes,
|
|
73
|
+
"should_hide_args": txn.user_txn.should_hide_args,
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|