cryptochief-crypto-processing-python 0.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.
Files changed (39) hide show
  1. cryptochief/__init__.py +336 -0
  2. cryptochief/_models.py +93 -0
  3. cryptochief/_version.py +3 -0
  4. cryptochief/amount.py +97 -0
  5. cryptochief/assets.py +32 -0
  6. cryptochief/chains.py +115 -0
  7. cryptochief/client.py +189 -0
  8. cryptochief/contract/__init__.py +69 -0
  9. cryptochief/contract/base58.py +40 -0
  10. cryptochief/contract/borsh.py +141 -0
  11. cryptochief/contract/evm_abi.py +321 -0
  12. cryptochief/contract/keccak.py +16 -0
  13. cryptochief/contract/tron_address.py +60 -0
  14. cryptochief/errors.py +111 -0
  15. cryptochief/pagination.py +32 -0
  16. cryptochief/poll.py +56 -0
  17. cryptochief/rsa.py +70 -0
  18. cryptochief/services/__init__.py +1 -0
  19. cryptochief/services/base.py +24 -0
  20. cryptochief/services/blockchain.py +76 -0
  21. cryptochief/services/currencies.py +55 -0
  22. cryptochief/services/payins.py +145 -0
  23. cryptochief/services/payouts.py +175 -0
  24. cryptochief/services/static_deposits.py +77 -0
  25. cryptochief/services/sweeps.py +85 -0
  26. cryptochief/services/transactions.py +470 -0
  27. cryptochief/services/wallets.py +86 -0
  28. cryptochief/services/withdrawals.py +51 -0
  29. cryptochief/sign.py +112 -0
  30. cryptochief/ton/__init__.py +19 -0
  31. cryptochief/ton/address.py +109 -0
  32. cryptochief/ton/messages.py +105 -0
  33. cryptochief/ton/rpc.py +159 -0
  34. cryptochief/transport.py +48 -0
  35. cryptochief/webhook.py +191 -0
  36. cryptochief_crypto_processing_python-0.1.0.dist-info/METADATA +346 -0
  37. cryptochief_crypto_processing_python-0.1.0.dist-info/RECORD +39 -0
  38. cryptochief_crypto_processing_python-0.1.0.dist-info/WHEEL +4 -0
  39. cryptochief_crypto_processing_python-0.1.0.dist-info/licenses/LICENSE +21 -0
cryptochief/webhook.py ADDED
@@ -0,0 +1,191 @@
1
+ """Webhook verification and typed event parsing.
2
+
3
+ The signature is ``hex(md5(base64(canonical_json(body)) + api_key))`` - the same
4
+ algorithm used for outgoing requests. The body is re-canonicalized before
5
+ hashing, so any key-order drift is normalized. Framework-agnostic: feed it the
6
+ raw request bytes and the ``Signature`` header.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import hmac
12
+ import json
13
+ from dataclasses import dataclass
14
+ from typing import Any, Dict, Optional, Union
15
+
16
+ from ._models import from_dict
17
+ from .errors import CryptoChiefError
18
+ from .sign import canonical_json, sign
19
+
20
+ #: Case-insensitive header name carrying the webhook signature.
21
+ WEBHOOK_HEADER = "Signature"
22
+
23
+ #: IP addresses Crypto Chief delivers webhooks from - whitelist for defense in depth.
24
+ WEBHOOK_SENDER_IPS = ("164.90.231.203", "104.248.248.64")
25
+
26
+
27
+ class WebhookSignatureError(CryptoChiefError):
28
+ """Raised when a webhook signature does not match the body."""
29
+
30
+ def __init__(self) -> None:
31
+ super().__init__("cryptochief: invalid webhook signature")
32
+
33
+
34
+ def _as_bytes(body: Union[str, bytes, bytearray]) -> bytes:
35
+ return body.encode("utf-8") if isinstance(body, str) else bytes(body)
36
+
37
+
38
+ def verify_webhook_signature(
39
+ api_key: str,
40
+ raw_body: Union[str, bytes, bytearray],
41
+ signature: Optional[str],
42
+ ) -> bool:
43
+ """Verify an incoming webhook against the merchant API key.
44
+
45
+ ``raw_body`` MUST be the exact bytes received - do not re-encode it first.
46
+ Returns ``True`` / ``False``; the comparison is constant-time.
47
+ """
48
+ if not api_key:
49
+ raise CryptoChiefError("cryptochief: api_key is required for webhook verification")
50
+ raw = _as_bytes(raw_body)
51
+ if len(raw) == 0 or not signature:
52
+ return False
53
+ try:
54
+ parsed = json.loads(raw.decode("utf-8"))
55
+ except ValueError:
56
+ return False # not JSON -> fail closed
57
+ expected = sign(canonical_json(parsed), api_key)
58
+ return hmac.compare_digest(expected, signature)
59
+
60
+
61
+ def parse_webhook_event(
62
+ api_key: str,
63
+ raw_body: Union[str, bytes, bytearray],
64
+ signature: Optional[str],
65
+ ) -> "WebhookEvent":
66
+ """Verify and parse a webhook in one step.
67
+
68
+ Raises :class:`WebhookSignatureError` if the signature is invalid; otherwise
69
+ returns the typed event (chosen by the ``event`` name prefix), or the raw
70
+ ``dict`` for an unrecognized prefix.
71
+ """
72
+ if not verify_webhook_signature(api_key, raw_body, signature):
73
+ raise WebhookSignatureError()
74
+ data = json.loads(_as_bytes(raw_body).decode("utf-8"))
75
+ return coerce_webhook_event(data)
76
+
77
+
78
+ def coerce_webhook_event(data: Dict[str, Any]) -> "WebhookEvent":
79
+ """Map a parsed webhook ``dict`` to its typed event by the ``event`` prefix."""
80
+ prefix = str(data.get("event") or "").split(".")[0]
81
+ cls = _EVENT_BY_PREFIX.get(prefix)
82
+ return from_dict(cls, data) if cls is not None else data
83
+
84
+
85
+ # -- Typed event payloads -----------------------------------------------------
86
+
87
+
88
+ @dataclass(kw_only=True)
89
+ class PayoutWebhookEvent:
90
+ """Payout webhook. Fires only on terminal status: ``payout.paid`` / ``payout.system_fail``."""
91
+
92
+ event: str = ""
93
+ uuid: str = ""
94
+ status: str = ""
95
+ order_id: Optional[str] = None
96
+ user_id: Optional[str] = None
97
+ amount_requested: Optional[str] = None
98
+ amount_to_receive: Optional[str] = None
99
+ to_address: Optional[str] = None
100
+ fee_info: Optional[Dict[str, Any]] = None
101
+ sources: Optional[Any] = None
102
+ service_operations: Optional[Any] = None
103
+ created_at: Optional[str] = None
104
+ completed_at: Optional[str] = None
105
+ error_reason: Optional[str] = None
106
+
107
+
108
+ @dataclass(kw_only=True)
109
+ class TransactionWebhookEvent:
110
+ """Transaction webhook. Fires only on terminal status (confirmed / failed / expired)."""
111
+
112
+ event: str = ""
113
+ uuid: str = ""
114
+ status: str = ""
115
+ network: Optional[str] = None
116
+ chain_family: Optional[str] = None
117
+ type: Optional[str] = None
118
+ from_address: Optional[str] = None
119
+ to_address: Optional[str] = None
120
+ value: Optional[str] = None
121
+ contract: Optional[str] = None
122
+ tx_hash: Optional[str] = None
123
+ created_at: Optional[str] = None
124
+ completed_at: Optional[str] = None
125
+ error_reason: Optional[str] = None
126
+
127
+
128
+ @dataclass(kw_only=True)
129
+ class PayInWebhookEvent:
130
+ """Pay-in webhook. Event names carry the ``invoice.`` prefix (e.g. ``invoice.paid``)."""
131
+
132
+ event: str = ""
133
+ uuid: str = ""
134
+ status: str = ""
135
+ order_id: Optional[str] = None
136
+ user_id: Optional[str] = None
137
+ prev_status: Optional[str] = None
138
+ mode: Optional[str] = None
139
+ amount_crypto: Optional[str] = None
140
+ amount_fiat: Optional[str] = None
141
+ fact_amount_crypto: Optional[str] = None
142
+ fact_amount_fiat: Optional[str] = None
143
+ currency: Optional[str] = None
144
+ payment_coin: Optional[str] = None
145
+ payment_network: Optional[str] = None
146
+ to_address: Optional[str] = None
147
+ txid: Optional[str] = None
148
+
149
+
150
+ @dataclass(kw_only=True)
151
+ class StaticDepositWebhookEvent:
152
+ """Static-deposit webhook. Event names carry the ``static_deposit.`` prefix."""
153
+
154
+ event: str = ""
155
+ uuid: str = ""
156
+ status: str = ""
157
+ network: Optional[str] = None
158
+ chain_family: Optional[str] = None
159
+ coin: Optional[str] = None
160
+ contract: Optional[str] = None
161
+ decimals: Optional[int] = None
162
+ to_address: Optional[str] = None
163
+ from_address: Optional[str] = None
164
+ tx_hash: Optional[str] = None
165
+ amount: Optional[str] = None
166
+ amount_fiat: Optional[str] = None
167
+ confirmations: Optional[int] = None
168
+ required_confirmations: Optional[int] = None
169
+ found_in_mempool: Optional[bool] = None
170
+ log_type: Optional[str] = None
171
+ block_number: Optional[int] = None
172
+ created_at: Optional[str] = None
173
+ updated_at: Optional[str] = None
174
+ confirmed_at: Optional[str] = None
175
+ paid_at: Optional[str] = None
176
+
177
+
178
+ WebhookEvent = Union[
179
+ PayoutWebhookEvent,
180
+ TransactionWebhookEvent,
181
+ PayInWebhookEvent,
182
+ StaticDepositWebhookEvent,
183
+ Dict[str, Any],
184
+ ]
185
+
186
+ _EVENT_BY_PREFIX = {
187
+ "payout": PayoutWebhookEvent,
188
+ "transaction": TransactionWebhookEvent,
189
+ "invoice": PayInWebhookEvent,
190
+ "static_deposit": StaticDepositWebhookEvent,
191
+ }
@@ -0,0 +1,346 @@
1
+ Metadata-Version: 2.4
2
+ Name: cryptochief-crypto-processing-python
3
+ Version: 0.1.0
4
+ Summary: Official async Python SDK for the Crypto Chief crypto payment gateway and crypto processing API. Accept crypto payments, send single and mass crypto payouts, sign on-chain transactions and smart-contract calls, manage wallets, convert fiat to crypto, and verify webhooks across Ethereum, BNB Smart Chain, Polygon, Tron, TON, Solana, Bitcoin, XRP and 20+ blockchains. USDT and USDC stablecoin support with int-precise amounts and asyncio/httpx.
5
+ Project-URL: Homepage, https://crypto-chief.com/processing/
6
+ Project-URL: Documentation, https://docs-sdk.crypto-chief.com/processing/python
7
+ Project-URL: Repository, https://github.com/crypto-chiefs/cryptochief-crypto-processing-python
8
+ Project-URL: Issues, https://github.com/crypto-chiefs/cryptochief-crypto-processing-python/issues
9
+ Author: Crypto Chief
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: accept-crypto-payments,async,asyncio,batch-payout,bep20,bitcoin,blockchain,bsc,crypto,crypto-invoice,crypto-payment-api,crypto-payment-gateway,crypto-payments,crypto-payout,crypto-processing,crypto-processing-api,cryptochief,cryptocurrency,dogecoin,erc20,ethereum,jetton,litecoin,mass-payout,payment-gateway,payment-processing,payments,payout,polygon,sdk,solana,stablecoin,ton,trc20,tron,usdc,usdt,wallet,web3,webhook,xrp
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Framework :: AsyncIO
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Topic :: Office/Business :: Financial
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Typing :: Typed
28
+ Requires-Python: >=3.10
29
+ Requires-Dist: cryptography>=41
30
+ Requires-Dist: httpx>=0.24
31
+ Requires-Dist: pycryptodomex>=3.19
32
+ Requires-Dist: pytoniq-core>=0.1.36
33
+ Provides-Extra: dev
34
+ Requires-Dist: mypy>=1.8; extra == 'dev'
35
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
36
+ Requires-Dist: pytest>=8; extra == 'dev'
37
+ Requires-Dist: ruff>=0.4; extra == 'dev'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # Crypto Chief Python SDK - Crypto Processing API Client
41
+
42
+ [![PyPI](https://img.shields.io/pypi/v/cryptochief-crypto-processing-python.svg)](https://pypi.org/project/cryptochief-crypto-processing-python/)
43
+ [![Python](https://img.shields.io/pypi/pyversions/cryptochief-crypto-processing-python.svg)](https://pypi.org/project/cryptochief-crypto-processing-python/)
44
+ [![SDK Docs](https://img.shields.io/badge/docs-SDK%20guide-2ea44f)](https://docs-sdk.crypto-chief.com/processing/python)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
46
+
47
+ **Crypto Chief Python SDK** is the official **asyncio** client library for the
48
+ [Crypto Chief](https://crypto-chief.com/processing/) **crypto processing API** -
49
+ a unified crypto payment gateway for accepting crypto payments, sending crypto
50
+ payouts (single and mass), signing on-chain transactions, managing wallets, and
51
+ verifying webhooks across **Ethereum, Tron, TON, Solana, Bitcoin and 20+ more
52
+ blockchains**.
53
+
54
+ Drop it into any async Python backend (FastAPI, aiohttp, Litestar, Django ASGI,
55
+ serverless ...) to add cryptocurrency payment processing - stablecoin
56
+ (USDT / USDC) payouts, pay-ins, swaps, and smart-contract calls - with typed
57
+ dataclass requests / responses, integer-precise amounts, and an `except`-friendly
58
+ error hierarchy.
59
+
60
+ - One-line setup; a reusable `CryptoChiefClient` you `await`.
61
+ - **Typed dataclasses** for every request and response - editor autocomplete and
62
+ attribute access (`est.amount_to_receive`), no dict juggling.
63
+ - **Contract calls without hand-encoded calldata** - Solidity ABI for EVM and
64
+ TRON, Anchor + Borsh for Solana, Jetton / NFT / comment helpers for TON.
65
+ - **Local RSA decryption** of generated wallet private keys.
66
+ - Stable error codes via `APIError.code`, automatic retry on transient failures.
67
+ - Arbitrary-precision amounts via native `int` - never `float`.
68
+ - Webhook verification + typed events, framework-agnostic.
69
+ - `await client.payouts.wait_for(uuid)` polling that resolves when a payout /
70
+ transaction / pay-in is final.
71
+
72
+ > The wire format is snake_case and so is Python - the public API uses the same
73
+ > field names the REST API does, with no translation layer in between.
74
+
75
+ ## Install
76
+
77
+ ```bash
78
+ pip install cryptochief-crypto-processing-python
79
+ ```
80
+
81
+ ```python
82
+ import cryptochief
83
+ from cryptochief import CryptoChiefClient, Chain
84
+ ```
85
+
86
+ Requires Python 3.10+.
87
+
88
+ ## Quick start
89
+
90
+ ```python
91
+ import asyncio
92
+ from cryptochief import CryptoChiefClient, Chain, EstimatePayoutRequest
93
+
94
+ async def main():
95
+ async with CryptoChiefClient(
96
+ merchant_id="YOUR_MERCHANT_ID",
97
+ api_key="YOUR_API_KEY", # signing secret - keep it server-side
98
+ ) as client:
99
+ est = await client.payouts.estimate(EstimatePayoutRequest(
100
+ network=Chain.ETH_SEPOLIA,
101
+ coin="ETH",
102
+ amount="0.0001",
103
+ to_address="0xRecipient...",
104
+ ))
105
+ print("amount to receive:", est.amount_to_receive)
106
+
107
+ asyncio.run(main())
108
+ ```
109
+
110
+ Both credentials come from the Dashboard -> Project.
111
+
112
+ ## What you can do with it
113
+
114
+ | Domain | Service | Key methods |
115
+ |---|---|---|
116
+ | Single payout (incl. auto-convert swap) | `client.payouts` | `estimate`, `execute`, `info`, `history`, `wait_for` |
117
+ | Mass payout (up to 50 items) | `client.payouts` | `batch_estimate`, `batch_execute` |
118
+ | Two-phase sign / broadcast for arbitrary txs | `client.transactions` | `sign`, `execute`, `info`, `history`, `wait_for` |
119
+ | EVM / TRON contract calls (incl. ERC-20 / TRC-20) | `client.transactions` | `sign_evm_call`, `sign_tron_call`, `erc20_transfer` |
120
+ | Solana programs | `client.transactions` | `sign_anchor_call`, `sign_solana_call` |
121
+ | TON contract calls (Jetton / NFT / text) | `client.transactions` | `jetton_transfer`, `nft_transfer`, `send_ton_comment`, `sign_ton_call` |
122
+ | Accept incoming payments | `client.pay_ins` | `create`, `select_asset`, `reset_asset`, `cancel`, `info`, `history`, `wait_for` |
123
+ | Wallet management + RSA decrypt | `client.wallets` | `generate`, `list`, `info`, `freeze`, `decrypt_private_key` |
124
+ | Treasury sweeps | `client.sweeps` | `force`, `history`, `wallet_history` |
125
+ | Withdrawals (read-only) | `client.withdrawals` | `info`, `history` |
126
+ | Static-deposit history | `client.static_deposits` | `info`, `history` |
127
+ | On-chain queries | `client.blockchain` | `contracts_available`, `wallet_balance`, `transaction_status` |
128
+ | Fiat <-> crypto rate quote | `client.currencies` | `fiat_to_crypto`, `crypto_to_fiat` |
129
+
130
+ ## Accept a crypto payment (pay-in)
131
+
132
+ Create an invoice, send the customer to the hosted `payment_link`, then settle it
133
+ when the `invoice.*` webhook arrives (recommended) or by polling `wait_for`.
134
+
135
+ ```python
136
+ from cryptochief import CryptoChiefClient, CreatePayInRequest, PayInMode
137
+
138
+ async def accept():
139
+ async with CryptoChiefClient(merchant_id="M", api_key="K") as client:
140
+ invoice = await client.pay_ins.create(CreatePayInRequest(
141
+ order_id="invoice-1001", # your id - idempotency key, safe to retry
142
+ user_id="user-7",
143
+ mode=PayInMode.FIAT, # fix a fiat price; the customer pays the crypto equivalent
144
+ amount_fiat="49.99",
145
+ currency="USD",
146
+ url_callback="https://example.com/webhooks/crypto-chief",
147
+ url_success="https://example.com/thanks",
148
+ ))
149
+ print("send the customer to:", invoice.payment_link)
150
+
151
+ final = await client.pay_ins.wait_for(invoice.uuid, timeout=1800)
152
+ print(final.status) # paid | expired | cancel
153
+ ```
154
+
155
+ For a fixed-crypto invoice use `mode=PayInMode.CRYPTO` with `amount_crypto` and
156
+ `asset=Asset(coin="USDT", network=Chain.TRON_MAINNET)`. For host-to-host flows
157
+ where the customer picks the coin in your own UI, create the order without a fixed
158
+ asset and commit the choice with `client.pay_ins.select_asset(...)`.
159
+
160
+ ## Send a payout (with confirmation)
161
+
162
+ ```python
163
+ from cryptochief import (
164
+ CryptoChiefClient, Chain, APIError, ErrorCode, ExecutePayoutRequest,
165
+ )
166
+
167
+ async def pay():
168
+ async with CryptoChiefClient(merchant_id="M", api_key="K") as client:
169
+ try:
170
+ payout = await client.payouts.execute(ExecutePayoutRequest(
171
+ order_id="order-42", # idempotency key - safe to retry
172
+ user_id="user-7",
173
+ network=Chain.ETH_SEPOLIA,
174
+ coin="ETH",
175
+ amount="0.0001",
176
+ to_address="0xRecipient...",
177
+ url_callback="https://example.com/webhooks/crypto-chief",
178
+ ))
179
+ final = await client.payouts.wait_for(payout.uuid, timeout=300)
180
+ print(final.status, final.txid)
181
+ except APIError as e:
182
+ if e.code == ErrorCode.INSUFFICIENT_FUNDS:
183
+ ... # top up and retry
184
+ raise
185
+ ```
186
+
187
+ ## Amounts: always integers, never floats
188
+
189
+ ```python
190
+ from cryptochief import human_to_base, base_to_human
191
+
192
+ human_to_base("1.5", 18) # 1500000000000000000
193
+ base_to_human(10_000, 8) # "0.0001"
194
+ ```
195
+
196
+ `int` is arbitrary-precision in Python, so token values never overflow and
197
+ decimal strings round-trip exactly. Discover an asset's decimals with
198
+ `client.blockchain.contracts_available()`.
199
+
200
+ ## Contract calls without hand-encoding
201
+
202
+ ```python
203
+ from cryptochief import EvmCallRequest, Erc20TransferRequest, Chain, human_to_base
204
+
205
+ # Any EVM/TRON method by Solidity signature - args are ABI-encoded for you.
206
+ await client.transactions.sign_evm_call(EvmCallRequest(
207
+ network=Chain.ETH_MAINNET,
208
+ from_address="0xYourWallet...",
209
+ contract="0xA0b8...", # Uniswap router, etc.
210
+ method="swapExactTokensForTokens(uint256,uint256,address[],address,uint256)",
211
+ args=[10**6, 0, ["0xTokenIn...", "0xTokenOut..."], "0xYourWallet...", 1750000000],
212
+ ))
213
+
214
+ # ERC-20 / TRC-20 transfer in one line (TRON base58 addresses accepted):
215
+ await client.transactions.erc20_transfer(Erc20TransferRequest(
216
+ network=Chain.TRON_MAINNET,
217
+ from_address="TYour...",
218
+ token_contract="TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", # USDT
219
+ recipient="TRecipient...",
220
+ amount=human_to_base("12.5", 6),
221
+ ))
222
+ ```
223
+
224
+ TON Jetton transfers resolve the sender's Jetton wallet automatically and pick a
225
+ sensible gas budget:
226
+
227
+ ```python
228
+ from cryptochief import JettonTransferRequest, Chain, human_to_base
229
+
230
+ await client.transactions.jetton_transfer(JettonTransferRequest(
231
+ network=Chain.TON_MAINNET,
232
+ from_address="UQYour...",
233
+ jetton_master="EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs", # USDT
234
+ recipient="UQRecipient...",
235
+ amount=human_to_base("5", 6),
236
+ memo="Order #4242",
237
+ ))
238
+ ```
239
+
240
+ Solana Anchor calls take explicitly-typed Borsh args:
241
+
242
+ ```python
243
+ from cryptochief import AnchorCallRequest, SolanaAccount, borsh_u64, borsh_string, Chain
244
+
245
+ await client.transactions.sign_anchor_call(AnchorCallRequest(
246
+ network=Chain.SOLANA_MAINNET,
247
+ from_address="YourPubkey...",
248
+ program="YourProgramId...",
249
+ method="initialize",
250
+ args=[borsh_u64(1_000), borsh_string("hello")],
251
+ accounts=[SolanaAccount(pubkey="...", is_signer=True, is_writable=True)],
252
+ ))
253
+ ```
254
+
255
+ ## Webhooks
256
+
257
+ `verify_webhook_signature` and `parse_webhook_event` are framework-agnostic - feed
258
+ them the raw request bytes and the `Signature` header. With FastAPI:
259
+
260
+ ```python
261
+ from fastapi import FastAPI, Request, HTTPException
262
+ from cryptochief import (
263
+ parse_webhook_event,
264
+ WebhookSignatureError,
265
+ PayInWebhookEvent,
266
+ PayoutWebhookEvent,
267
+ )
268
+
269
+ app = FastAPI()
270
+ API_KEY = "..."
271
+
272
+ @app.post("/webhooks/crypto-chief")
273
+ async def hook(request: Request):
274
+ raw = await request.body() # the EXACT bytes - do not re-encode
275
+ try:
276
+ event = parse_webhook_event(API_KEY, raw, request.headers.get("Signature"))
277
+ except WebhookSignatureError:
278
+ raise HTTPException(status_code=401, detail="bad signature")
279
+
280
+ if isinstance(event, PayInWebhookEvent):
281
+ if event.status == "paid":
282
+ ... # invoice.paid -> fulfill the order for event.order_id
283
+ elif isinstance(event, PayoutWebhookEvent):
284
+ ... # payout.paid / payout.system_fail -> reconcile your ledger
285
+ return {"ok": True}
286
+ ```
287
+
288
+ `parse_webhook_event` returns a typed event (`PayoutWebhookEvent`,
289
+ `TransactionWebhookEvent`, `PayInWebhookEvent`, `StaticDepositWebhookEvent`) chosen
290
+ by the event-name prefix, or the raw dict for an unrecognized prefix. Whitelist
291
+ the sender IPs in `WEBHOOK_SENDER_IPS` at your edge for defense in depth.
292
+
293
+ ## Errors
294
+
295
+ Everything the SDK raises derives from `CryptoChiefError`. API failures are
296
+ `APIError` with a stable `.code` (and `.http_status`); branch on `ErrorCode`
297
+ rather than parsing messages. 5xx and network errors are retried automatically;
298
+ 4xx is raised immediately.
299
+
300
+ ```python
301
+ from cryptochief import APIError, ErrorCode
302
+
303
+ try:
304
+ await client.payouts.execute(req)
305
+ except APIError as e:
306
+ if e.code == ErrorCode.DEBT_LIMIT_EXCEEDED:
307
+ ...
308
+ ```
309
+
310
+ ## Wallet private-key decryption
311
+
312
+ Generated wallets return `private_key_encrypted` (RSA-OAEP / SHA-256, base64).
313
+ Configure your project's RSA private key to decrypt locally - it never touches
314
+ the network:
315
+
316
+ ```python
317
+ client = CryptoChiefClient(
318
+ merchant_id="M", api_key="K",
319
+ rsa_private_key=open("project_private_key.pem").read(),
320
+ )
321
+ wallet = await client.wallets.generate(...)
322
+ priv = client.wallets.decrypt_private_key(wallet.private_key_encrypted)
323
+ ```
324
+
325
+ ## FAQ - common crypto-processing tasks in Python
326
+
327
+ - **How do I accept crypto payments in Python?** Create a pay-in with
328
+ `client.pay_ins.create(...)`, redirect the customer to `pay_in.payment_link`,
329
+ and confirm via webhook or `client.pay_ins.wait_for(uuid)`.
330
+ - **How do I send a USDT payout?** `client.payouts.execute(...)` with the
331
+ stablecoin's `coin` / `network`; poll `wait_for`.
332
+ - **How do I send many payouts at once?** `client.payouts.batch_execute(...)` -
333
+ up to 50 items, funds locked sequentially.
334
+ - **How do I do a crypto swap?** A swap is a payout with `auto_convert=True`.
335
+ - **How do I call a smart contract?** `client.transactions.sign_evm_call` /
336
+ `sign_anchor_call` / `jetton_transfer`, then `transactions.execute`.
337
+
338
+ ## Documentation
339
+
340
+ - SDK guide: https://docs-sdk.crypto-chief.com/processing/python
341
+ - REST API reference: https://docs-processing.crypto-chief.com
342
+ - Product: https://crypto-chief.com/processing/
343
+
344
+ ## License
345
+
346
+ MIT
@@ -0,0 +1,39 @@
1
+ cryptochief/__init__.py,sha256=q6qGaxOd6MUIKS_41CmY3xIt9PwBsf8EAB32nGgFWGY,8169
2
+ cryptochief/_models.py,sha256=I5jbRtC4Asnr0eZP1IUYcgQqXE-HMhXIq4zGabvMGO4,3195
3
+ cryptochief/_version.py,sha256=-UYTpK8lRuzcw9BEWkdBHyJiS_vjvg0P06Wo2xs--us,77
4
+ cryptochief/amount.py,sha256=UzIc1ZEJYYH8Zj5rUdnnLC01fS5ICKUSQ_rRxF0oeWI,3168
5
+ cryptochief/assets.py,sha256=f4PaC60qoYloLlegWa61bXeG0qmk8j3Hcq4YjVrUVHw,889
6
+ cryptochief/chains.py,sha256=FJ-QplCjf6qNc9frJYF7mJWMpB_DZ3SizI91kYTBNO0,3713
7
+ cryptochief/client.py,sha256=_nLV_shDLWAD9_YKP6GDAmRYdw9uo65gxGGFw-dK6nY,7270
8
+ cryptochief/errors.py,sha256=iFCiTpXbXwLa1nJTT57SKdtQEhUdbxAI-Lcnd8p3OA0,4052
9
+ cryptochief/pagination.py,sha256=pJIzZNjN2mCbmYz66l1E-rUz8fsShZyNZecUncbcXtU,771
10
+ cryptochief/poll.py,sha256=CfWb4OI1CN0gmS-ktt1SIN0yvNu9JQVhOlfi65WCsD8,1817
11
+ cryptochief/rsa.py,sha256=VvXJOJxE_GEdZ5cK4u0dRPkXWVs4GJnTnYHiFWpOhiM,2712
12
+ cryptochief/sign.py,sha256=ghILWz9AEe_jy2JSgdOU2CpYlWGKrsZxJWjg-P9mgcs,3687
13
+ cryptochief/transport.py,sha256=mGQ95JgVpRJposxmVXFhtI2Rkt-G2GRsBtQg2MlPEyw,1578
14
+ cryptochief/webhook.py,sha256=GAx94kf9Bkk5xKSNdQ1LNsM1BUyioAPnney5jfluB4A,6154
15
+ cryptochief/contract/__init__.py,sha256=LF3fAvJOv0pnFeK7XOA69CwnM8GM_McqUiRvmZGj7f8,1398
16
+ cryptochief/contract/base58.py,sha256=Rr-bcqBAHgr-q9_pV-KEwPrOjEGow3qiDUwZ_kicUH8,1172
17
+ cryptochief/contract/borsh.py,sha256=aSsumB5N19BK2eVi11s2nM715M9v_mkFwzcQ2HnXHII,4346
18
+ cryptochief/contract/evm_abi.py,sha256=YKGEdWbedNFZ7KMwmUCP9xqomi7jfIa3UlqIfbdMpko,11028
19
+ cryptochief/contract/keccak.py,sha256=2O467YjK_CWFoPdLhu8Jnv6nS30K4zl669Hu3-NrSxE,437
20
+ cryptochief/contract/tron_address.py,sha256=yLXneYvhbD9G8yIPcGMp-azl79C8brcmrknGE8VOVTA,2012
21
+ cryptochief/services/__init__.py,sha256=6Hn8aGX2dDLO1uK4tDIJ5f2HnADi4kamzSt2nwkk13s,87
22
+ cryptochief/services/base.py,sha256=EAhQxgXF_gokT7Tz5AFkJ2xPNVMbU9RiVua0qAtK1Tw,678
23
+ cryptochief/services/blockchain.py,sha256=Yiu4KBuxDz_XyZIsTpVRax9IoqIMJkMigjvfiSvxgm8,2418
24
+ cryptochief/services/currencies.py,sha256=sZ2JkZUqQMSuzpdRCY3HuuVY9TLLDOgAyCSmvuOm0-A,1611
25
+ cryptochief/services/payins.py,sha256=uPhY6ceRZe8eA5cmsrTfDOtH8N_5vKFWBeGTOgbv3ZY,4568
26
+ cryptochief/services/payouts.py,sha256=QkqnxyXgTqDnh7epZQCgcvhxWnalpxNSZdR1QMl7vI4,5586
27
+ cryptochief/services/static_deposits.py,sha256=8uVM7c4rXb5HPj5n7q0K8bri0Kbxa3d442Uwo4iAMuM,2329
28
+ cryptochief/services/sweeps.py,sha256=_OSfwY-wQcZPjeyThbAx1RNEtDqbfoeuRtJttyroKpA,2675
29
+ cryptochief/services/transactions.py,sha256=EnVWTlbu04GJovI8PMBkxpO438dOny7E58GX_65I9MQ,16788
30
+ cryptochief/services/wallets.py,sha256=g19wqwatVTRY-Zr_JFumQdbjY4Eit8hyEnZC2aerPpw,2956
31
+ cryptochief/services/withdrawals.py,sha256=8UEXSr1VpvYSJl11vTBDOHq9qN96jP-i9p5USezKLHc,1540
32
+ cryptochief/ton/__init__.py,sha256=z5VnZ5zXJkGaWUvOPdxC1YL6LJHz4TfhItVhBRVGKpA,392
33
+ cryptochief/ton/address.py,sha256=Xo9cASWxTAK5-BLZ7ZwZcPEgobnh5fcwGj_gPzK2jz0,3731
34
+ cryptochief/ton/messages.py,sha256=GCAn6TdyHewIwHb6V9HCjRx7BFHq9i1Cl243kDl6JNs,3341
35
+ cryptochief/ton/rpc.py,sha256=fccQG2hecmLDIXyZs_6SzUIVzPb9huJnFFLp3HMrOuc,6109
36
+ cryptochief_crypto_processing_python-0.1.0.dist-info/METADATA,sha256=qxMvCYV9oEyVMjXr6UGBHqZGKeW_ToNXne4PbK_QIWM,14683
37
+ cryptochief_crypto_processing_python-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
38
+ cryptochief_crypto_processing_python-0.1.0.dist-info/licenses/LICENSE,sha256=OkQRmg655nJmf2CYF2rYZNq-W961sWnsIPgYPJ5uuE4,1069
39
+ cryptochief_crypto_processing_python-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Crypto Chief
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.