cryptochief-crypto-processing-python 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.
- cryptochief_crypto_processing_python-0.1.0/.gitignore +15 -0
- cryptochief_crypto_processing_python-0.1.0/LICENSE +21 -0
- cryptochief_crypto_processing_python-0.1.0/PKG-INFO +346 -0
- cryptochief_crypto_processing_python-0.1.0/README.md +307 -0
- cryptochief_crypto_processing_python-0.1.0/pyproject.toml +114 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/__init__.py +336 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/_models.py +93 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/_version.py +3 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/amount.py +97 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/assets.py +32 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/chains.py +115 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/client.py +189 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/contract/__init__.py +69 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/contract/base58.py +40 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/contract/borsh.py +141 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/contract/evm_abi.py +321 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/contract/keccak.py +16 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/contract/tron_address.py +60 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/errors.py +111 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/pagination.py +32 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/poll.py +56 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/rsa.py +70 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/__init__.py +1 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/base.py +24 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/blockchain.py +76 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/currencies.py +55 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/payins.py +145 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/payouts.py +175 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/static_deposits.py +77 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/sweeps.py +85 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/transactions.py +470 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/wallets.py +86 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/withdrawals.py +51 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/sign.py +112 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/ton/__init__.py +19 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/ton/address.py +109 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/ton/messages.py +105 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/ton/rpc.py +159 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/transport.py +48 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/webhook.py +191 -0
|
@@ -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.
|
|
@@ -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
|
+
[](https://pypi.org/project/cryptochief-crypto-processing-python/)
|
|
43
|
+
[](https://pypi.org/project/cryptochief-crypto-processing-python/)
|
|
44
|
+
[](https://docs-sdk.crypto-chief.com/processing/python)
|
|
45
|
+
[](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,307 @@
|
|
|
1
|
+
# Crypto Chief Python SDK - Crypto Processing API Client
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/cryptochief-crypto-processing-python/)
|
|
4
|
+
[](https://pypi.org/project/cryptochief-crypto-processing-python/)
|
|
5
|
+
[](https://docs-sdk.crypto-chief.com/processing/python)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
**Crypto Chief Python SDK** is the official **asyncio** client library for the
|
|
9
|
+
[Crypto Chief](https://crypto-chief.com/processing/) **crypto processing API** -
|
|
10
|
+
a unified crypto payment gateway for accepting crypto payments, sending crypto
|
|
11
|
+
payouts (single and mass), signing on-chain transactions, managing wallets, and
|
|
12
|
+
verifying webhooks across **Ethereum, Tron, TON, Solana, Bitcoin and 20+ more
|
|
13
|
+
blockchains**.
|
|
14
|
+
|
|
15
|
+
Drop it into any async Python backend (FastAPI, aiohttp, Litestar, Django ASGI,
|
|
16
|
+
serverless ...) to add cryptocurrency payment processing - stablecoin
|
|
17
|
+
(USDT / USDC) payouts, pay-ins, swaps, and smart-contract calls - with typed
|
|
18
|
+
dataclass requests / responses, integer-precise amounts, and an `except`-friendly
|
|
19
|
+
error hierarchy.
|
|
20
|
+
|
|
21
|
+
- One-line setup; a reusable `CryptoChiefClient` you `await`.
|
|
22
|
+
- **Typed dataclasses** for every request and response - editor autocomplete and
|
|
23
|
+
attribute access (`est.amount_to_receive`), no dict juggling.
|
|
24
|
+
- **Contract calls without hand-encoded calldata** - Solidity ABI for EVM and
|
|
25
|
+
TRON, Anchor + Borsh for Solana, Jetton / NFT / comment helpers for TON.
|
|
26
|
+
- **Local RSA decryption** of generated wallet private keys.
|
|
27
|
+
- Stable error codes via `APIError.code`, automatic retry on transient failures.
|
|
28
|
+
- Arbitrary-precision amounts via native `int` - never `float`.
|
|
29
|
+
- Webhook verification + typed events, framework-agnostic.
|
|
30
|
+
- `await client.payouts.wait_for(uuid)` polling that resolves when a payout /
|
|
31
|
+
transaction / pay-in is final.
|
|
32
|
+
|
|
33
|
+
> The wire format is snake_case and so is Python - the public API uses the same
|
|
34
|
+
> field names the REST API does, with no translation layer in between.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install cryptochief-crypto-processing-python
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
import cryptochief
|
|
44
|
+
from cryptochief import CryptoChiefClient, Chain
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Requires Python 3.10+.
|
|
48
|
+
|
|
49
|
+
## Quick start
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import asyncio
|
|
53
|
+
from cryptochief import CryptoChiefClient, Chain, EstimatePayoutRequest
|
|
54
|
+
|
|
55
|
+
async def main():
|
|
56
|
+
async with CryptoChiefClient(
|
|
57
|
+
merchant_id="YOUR_MERCHANT_ID",
|
|
58
|
+
api_key="YOUR_API_KEY", # signing secret - keep it server-side
|
|
59
|
+
) as client:
|
|
60
|
+
est = await client.payouts.estimate(EstimatePayoutRequest(
|
|
61
|
+
network=Chain.ETH_SEPOLIA,
|
|
62
|
+
coin="ETH",
|
|
63
|
+
amount="0.0001",
|
|
64
|
+
to_address="0xRecipient...",
|
|
65
|
+
))
|
|
66
|
+
print("amount to receive:", est.amount_to_receive)
|
|
67
|
+
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Both credentials come from the Dashboard -> Project.
|
|
72
|
+
|
|
73
|
+
## What you can do with it
|
|
74
|
+
|
|
75
|
+
| Domain | Service | Key methods |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| Single payout (incl. auto-convert swap) | `client.payouts` | `estimate`, `execute`, `info`, `history`, `wait_for` |
|
|
78
|
+
| Mass payout (up to 50 items) | `client.payouts` | `batch_estimate`, `batch_execute` |
|
|
79
|
+
| Two-phase sign / broadcast for arbitrary txs | `client.transactions` | `sign`, `execute`, `info`, `history`, `wait_for` |
|
|
80
|
+
| EVM / TRON contract calls (incl. ERC-20 / TRC-20) | `client.transactions` | `sign_evm_call`, `sign_tron_call`, `erc20_transfer` |
|
|
81
|
+
| Solana programs | `client.transactions` | `sign_anchor_call`, `sign_solana_call` |
|
|
82
|
+
| TON contract calls (Jetton / NFT / text) | `client.transactions` | `jetton_transfer`, `nft_transfer`, `send_ton_comment`, `sign_ton_call` |
|
|
83
|
+
| Accept incoming payments | `client.pay_ins` | `create`, `select_asset`, `reset_asset`, `cancel`, `info`, `history`, `wait_for` |
|
|
84
|
+
| Wallet management + RSA decrypt | `client.wallets` | `generate`, `list`, `info`, `freeze`, `decrypt_private_key` |
|
|
85
|
+
| Treasury sweeps | `client.sweeps` | `force`, `history`, `wallet_history` |
|
|
86
|
+
| Withdrawals (read-only) | `client.withdrawals` | `info`, `history` |
|
|
87
|
+
| Static-deposit history | `client.static_deposits` | `info`, `history` |
|
|
88
|
+
| On-chain queries | `client.blockchain` | `contracts_available`, `wallet_balance`, `transaction_status` |
|
|
89
|
+
| Fiat <-> crypto rate quote | `client.currencies` | `fiat_to_crypto`, `crypto_to_fiat` |
|
|
90
|
+
|
|
91
|
+
## Accept a crypto payment (pay-in)
|
|
92
|
+
|
|
93
|
+
Create an invoice, send the customer to the hosted `payment_link`, then settle it
|
|
94
|
+
when the `invoice.*` webhook arrives (recommended) or by polling `wait_for`.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from cryptochief import CryptoChiefClient, CreatePayInRequest, PayInMode
|
|
98
|
+
|
|
99
|
+
async def accept():
|
|
100
|
+
async with CryptoChiefClient(merchant_id="M", api_key="K") as client:
|
|
101
|
+
invoice = await client.pay_ins.create(CreatePayInRequest(
|
|
102
|
+
order_id="invoice-1001", # your id - idempotency key, safe to retry
|
|
103
|
+
user_id="user-7",
|
|
104
|
+
mode=PayInMode.FIAT, # fix a fiat price; the customer pays the crypto equivalent
|
|
105
|
+
amount_fiat="49.99",
|
|
106
|
+
currency="USD",
|
|
107
|
+
url_callback="https://example.com/webhooks/crypto-chief",
|
|
108
|
+
url_success="https://example.com/thanks",
|
|
109
|
+
))
|
|
110
|
+
print("send the customer to:", invoice.payment_link)
|
|
111
|
+
|
|
112
|
+
final = await client.pay_ins.wait_for(invoice.uuid, timeout=1800)
|
|
113
|
+
print(final.status) # paid | expired | cancel
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For a fixed-crypto invoice use `mode=PayInMode.CRYPTO` with `amount_crypto` and
|
|
117
|
+
`asset=Asset(coin="USDT", network=Chain.TRON_MAINNET)`. For host-to-host flows
|
|
118
|
+
where the customer picks the coin in your own UI, create the order without a fixed
|
|
119
|
+
asset and commit the choice with `client.pay_ins.select_asset(...)`.
|
|
120
|
+
|
|
121
|
+
## Send a payout (with confirmation)
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from cryptochief import (
|
|
125
|
+
CryptoChiefClient, Chain, APIError, ErrorCode, ExecutePayoutRequest,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
async def pay():
|
|
129
|
+
async with CryptoChiefClient(merchant_id="M", api_key="K") as client:
|
|
130
|
+
try:
|
|
131
|
+
payout = await client.payouts.execute(ExecutePayoutRequest(
|
|
132
|
+
order_id="order-42", # idempotency key - safe to retry
|
|
133
|
+
user_id="user-7",
|
|
134
|
+
network=Chain.ETH_SEPOLIA,
|
|
135
|
+
coin="ETH",
|
|
136
|
+
amount="0.0001",
|
|
137
|
+
to_address="0xRecipient...",
|
|
138
|
+
url_callback="https://example.com/webhooks/crypto-chief",
|
|
139
|
+
))
|
|
140
|
+
final = await client.payouts.wait_for(payout.uuid, timeout=300)
|
|
141
|
+
print(final.status, final.txid)
|
|
142
|
+
except APIError as e:
|
|
143
|
+
if e.code == ErrorCode.INSUFFICIENT_FUNDS:
|
|
144
|
+
... # top up and retry
|
|
145
|
+
raise
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Amounts: always integers, never floats
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from cryptochief import human_to_base, base_to_human
|
|
152
|
+
|
|
153
|
+
human_to_base("1.5", 18) # 1500000000000000000
|
|
154
|
+
base_to_human(10_000, 8) # "0.0001"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`int` is arbitrary-precision in Python, so token values never overflow and
|
|
158
|
+
decimal strings round-trip exactly. Discover an asset's decimals with
|
|
159
|
+
`client.blockchain.contracts_available()`.
|
|
160
|
+
|
|
161
|
+
## Contract calls without hand-encoding
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from cryptochief import EvmCallRequest, Erc20TransferRequest, Chain, human_to_base
|
|
165
|
+
|
|
166
|
+
# Any EVM/TRON method by Solidity signature - args are ABI-encoded for you.
|
|
167
|
+
await client.transactions.sign_evm_call(EvmCallRequest(
|
|
168
|
+
network=Chain.ETH_MAINNET,
|
|
169
|
+
from_address="0xYourWallet...",
|
|
170
|
+
contract="0xA0b8...", # Uniswap router, etc.
|
|
171
|
+
method="swapExactTokensForTokens(uint256,uint256,address[],address,uint256)",
|
|
172
|
+
args=[10**6, 0, ["0xTokenIn...", "0xTokenOut..."], "0xYourWallet...", 1750000000],
|
|
173
|
+
))
|
|
174
|
+
|
|
175
|
+
# ERC-20 / TRC-20 transfer in one line (TRON base58 addresses accepted):
|
|
176
|
+
await client.transactions.erc20_transfer(Erc20TransferRequest(
|
|
177
|
+
network=Chain.TRON_MAINNET,
|
|
178
|
+
from_address="TYour...",
|
|
179
|
+
token_contract="TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", # USDT
|
|
180
|
+
recipient="TRecipient...",
|
|
181
|
+
amount=human_to_base("12.5", 6),
|
|
182
|
+
))
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
TON Jetton transfers resolve the sender's Jetton wallet automatically and pick a
|
|
186
|
+
sensible gas budget:
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from cryptochief import JettonTransferRequest, Chain, human_to_base
|
|
190
|
+
|
|
191
|
+
await client.transactions.jetton_transfer(JettonTransferRequest(
|
|
192
|
+
network=Chain.TON_MAINNET,
|
|
193
|
+
from_address="UQYour...",
|
|
194
|
+
jetton_master="EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs", # USDT
|
|
195
|
+
recipient="UQRecipient...",
|
|
196
|
+
amount=human_to_base("5", 6),
|
|
197
|
+
memo="Order #4242",
|
|
198
|
+
))
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Solana Anchor calls take explicitly-typed Borsh args:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from cryptochief import AnchorCallRequest, SolanaAccount, borsh_u64, borsh_string, Chain
|
|
205
|
+
|
|
206
|
+
await client.transactions.sign_anchor_call(AnchorCallRequest(
|
|
207
|
+
network=Chain.SOLANA_MAINNET,
|
|
208
|
+
from_address="YourPubkey...",
|
|
209
|
+
program="YourProgramId...",
|
|
210
|
+
method="initialize",
|
|
211
|
+
args=[borsh_u64(1_000), borsh_string("hello")],
|
|
212
|
+
accounts=[SolanaAccount(pubkey="...", is_signer=True, is_writable=True)],
|
|
213
|
+
))
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Webhooks
|
|
217
|
+
|
|
218
|
+
`verify_webhook_signature` and `parse_webhook_event` are framework-agnostic - feed
|
|
219
|
+
them the raw request bytes and the `Signature` header. With FastAPI:
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
from fastapi import FastAPI, Request, HTTPException
|
|
223
|
+
from cryptochief import (
|
|
224
|
+
parse_webhook_event,
|
|
225
|
+
WebhookSignatureError,
|
|
226
|
+
PayInWebhookEvent,
|
|
227
|
+
PayoutWebhookEvent,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
app = FastAPI()
|
|
231
|
+
API_KEY = "..."
|
|
232
|
+
|
|
233
|
+
@app.post("/webhooks/crypto-chief")
|
|
234
|
+
async def hook(request: Request):
|
|
235
|
+
raw = await request.body() # the EXACT bytes - do not re-encode
|
|
236
|
+
try:
|
|
237
|
+
event = parse_webhook_event(API_KEY, raw, request.headers.get("Signature"))
|
|
238
|
+
except WebhookSignatureError:
|
|
239
|
+
raise HTTPException(status_code=401, detail="bad signature")
|
|
240
|
+
|
|
241
|
+
if isinstance(event, PayInWebhookEvent):
|
|
242
|
+
if event.status == "paid":
|
|
243
|
+
... # invoice.paid -> fulfill the order for event.order_id
|
|
244
|
+
elif isinstance(event, PayoutWebhookEvent):
|
|
245
|
+
... # payout.paid / payout.system_fail -> reconcile your ledger
|
|
246
|
+
return {"ok": True}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`parse_webhook_event` returns a typed event (`PayoutWebhookEvent`,
|
|
250
|
+
`TransactionWebhookEvent`, `PayInWebhookEvent`, `StaticDepositWebhookEvent`) chosen
|
|
251
|
+
by the event-name prefix, or the raw dict for an unrecognized prefix. Whitelist
|
|
252
|
+
the sender IPs in `WEBHOOK_SENDER_IPS` at your edge for defense in depth.
|
|
253
|
+
|
|
254
|
+
## Errors
|
|
255
|
+
|
|
256
|
+
Everything the SDK raises derives from `CryptoChiefError`. API failures are
|
|
257
|
+
`APIError` with a stable `.code` (and `.http_status`); branch on `ErrorCode`
|
|
258
|
+
rather than parsing messages. 5xx and network errors are retried automatically;
|
|
259
|
+
4xx is raised immediately.
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
from cryptochief import APIError, ErrorCode
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
await client.payouts.execute(req)
|
|
266
|
+
except APIError as e:
|
|
267
|
+
if e.code == ErrorCode.DEBT_LIMIT_EXCEEDED:
|
|
268
|
+
...
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Wallet private-key decryption
|
|
272
|
+
|
|
273
|
+
Generated wallets return `private_key_encrypted` (RSA-OAEP / SHA-256, base64).
|
|
274
|
+
Configure your project's RSA private key to decrypt locally - it never touches
|
|
275
|
+
the network:
|
|
276
|
+
|
|
277
|
+
```python
|
|
278
|
+
client = CryptoChiefClient(
|
|
279
|
+
merchant_id="M", api_key="K",
|
|
280
|
+
rsa_private_key=open("project_private_key.pem").read(),
|
|
281
|
+
)
|
|
282
|
+
wallet = await client.wallets.generate(...)
|
|
283
|
+
priv = client.wallets.decrypt_private_key(wallet.private_key_encrypted)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## FAQ - common crypto-processing tasks in Python
|
|
287
|
+
|
|
288
|
+
- **How do I accept crypto payments in Python?** Create a pay-in with
|
|
289
|
+
`client.pay_ins.create(...)`, redirect the customer to `pay_in.payment_link`,
|
|
290
|
+
and confirm via webhook or `client.pay_ins.wait_for(uuid)`.
|
|
291
|
+
- **How do I send a USDT payout?** `client.payouts.execute(...)` with the
|
|
292
|
+
stablecoin's `coin` / `network`; poll `wait_for`.
|
|
293
|
+
- **How do I send many payouts at once?** `client.payouts.batch_execute(...)` -
|
|
294
|
+
up to 50 items, funds locked sequentially.
|
|
295
|
+
- **How do I do a crypto swap?** A swap is a payout with `auto_convert=True`.
|
|
296
|
+
- **How do I call a smart contract?** `client.transactions.sign_evm_call` /
|
|
297
|
+
`sign_anchor_call` / `jetton_transfer`, then `transactions.execute`.
|
|
298
|
+
|
|
299
|
+
## Documentation
|
|
300
|
+
|
|
301
|
+
- SDK guide: https://docs-sdk.crypto-chief.com/processing/python
|
|
302
|
+
- REST API reference: https://docs-processing.crypto-chief.com
|
|
303
|
+
- Product: https://crypto-chief.com/processing/
|
|
304
|
+
|
|
305
|
+
## License
|
|
306
|
+
|
|
307
|
+
MIT
|