cryptochief-crypto-processing-python 0.1.0__tar.gz → 0.4.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 → cryptochief_crypto_processing_python-0.4.0}/PKG-INFO +38 -4
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/README.md +35 -1
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/pyproject.toml +1 -1
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/__init__.py +23 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/_version.py +1 -1
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/client.py +2 -0
- cryptochief_crypto_processing_python-0.4.0/src/cryptochief/sentinels.py +38 -0
- cryptochief_crypto_processing_python-0.4.0/src/cryptochief/services/credits.py +70 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/payins.py +32 -0
- cryptochief_crypto_processing_python-0.4.0/src/cryptochief/services/sweeps.py +282 -0
- cryptochief_crypto_processing_python-0.1.0/src/cryptochief/services/sweeps.py +0 -85
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/.gitignore +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/LICENSE +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/_models.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/amount.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/assets.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/chains.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/contract/__init__.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/contract/base58.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/contract/borsh.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/contract/evm_abi.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/contract/keccak.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/contract/tron_address.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/errors.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/pagination.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/poll.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/rsa.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/__init__.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/base.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/blockchain.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/currencies.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/payouts.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/static_deposits.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/transactions.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/wallets.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/services/withdrawals.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/sign.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/ton/__init__.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/ton/address.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/ton/messages.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/ton/rpc.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/transport.py +0 -0
- {cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/src/cryptochief/webhook.py +0 -0
{cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: cryptochief-crypto-processing-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
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
5
|
Project-URL: Homepage, https://crypto-chief.com/processing/
|
|
6
6
|
Project-URL: Documentation, https://docs-sdk.crypto-chief.com/processing/python
|
|
@@ -34,7 +34,7 @@ Provides-Extra: dev
|
|
|
34
34
|
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
35
35
|
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
36
36
|
Requires-Dist: pytest>=8; extra == 'dev'
|
|
37
|
-
Requires-Dist: ruff
|
|
37
|
+
Requires-Dist: ruff<0.16,>=0.4; extra == 'dev'
|
|
38
38
|
Description-Content-Type: text/markdown
|
|
39
39
|
|
|
40
40
|
# Crypto Chief Python SDK - Crypto Processing API Client
|
|
@@ -121,11 +121,12 @@ Both credentials come from the Dashboard -> Project.
|
|
|
121
121
|
| TON contract calls (Jetton / NFT / text) | `client.transactions` | `jetton_transfer`, `nft_transfer`, `send_ton_comment`, `sign_ton_call` |
|
|
122
122
|
| Accept incoming payments | `client.pay_ins` | `create`, `select_asset`, `reset_asset`, `cancel`, `info`, `history`, `wait_for` |
|
|
123
123
|
| Wallet management + RSA decrypt | `client.wallets` | `generate`, `list`, `info`, `freeze`, `decrypt_private_key` |
|
|
124
|
-
| Treasury sweeps | `client.sweeps` | `force`, `history`, `wallet_history` |
|
|
124
|
+
| Treasury sweeps | `client.sweeps` | `force`, `history`, `wallet_history`, `settings`, `update_settings` |
|
|
125
125
|
| Withdrawals (read-only) | `client.withdrawals` | `info`, `history` |
|
|
126
126
|
| Static-deposit history | `client.static_deposits` | `info`, `history` |
|
|
127
127
|
| On-chain queries | `client.blockchain` | `contracts_available`, `wallet_balance`, `transaction_status` |
|
|
128
128
|
| Fiat <-> crypto rate quote | `client.currencies` | `fiat_to_crypto`, `crypto_to_fiat` |
|
|
129
|
+
| Credits (billing) balance check and top-up - free of charge | `client.credits` | `balance`, `topup` |
|
|
129
130
|
|
|
130
131
|
## Accept a crypto payment (pay-in)
|
|
131
132
|
|
|
@@ -334,6 +335,39 @@ priv = client.wallets.decrypt_private_key(wallet.private_key_encrypted)
|
|
|
334
335
|
- **How do I do a crypto swap?** A swap is a payout with `auto_convert=True`.
|
|
335
336
|
- **How do I call a smart contract?** `client.transactions.sign_evm_call` /
|
|
336
337
|
`sign_anchor_call` / `jetton_transfer`, then `transactions.execute`.
|
|
338
|
+
- **How do I control when a deposit wallet is swept?**
|
|
339
|
+
`client.sweeps.settings(...)` reads the policy in force for one wallet and
|
|
340
|
+
`client.sweeps.update_settings(...)` changes it - sweep on arrival
|
|
341
|
+
(`SweepPolicyMode.MOMENTUM`), sweep once the balance reaches an amount
|
|
342
|
+
(`SweepPolicyMode.THRESHOLD` plus `threshold_amount_usd`), or never on its own
|
|
343
|
+
(`SweepPolicyMode.OFF`, force still works). The read comes back in three
|
|
344
|
+
layers - what will happen, what this wallet overrides, and what it inherits
|
|
345
|
+
from the project - so a value of your own is distinguishable from an inherited
|
|
346
|
+
one:
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
s = await client.sweeps.update_settings(
|
|
350
|
+
deposit_address,
|
|
351
|
+
type_work=SweepPolicyMode.THRESHOLD,
|
|
352
|
+
threshold_amount_usd="250",
|
|
353
|
+
)
|
|
354
|
+
# s.effective is the resolved policy; s.effective.source names the layer it came from.
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Inheritance is per field: overriding the mode leaves the fee mode inherited.
|
|
358
|
+
To stop overriding a field, pass `CLEAR` - `None` already means "leave this
|
|
359
|
+
field alone", so it cannot also mean "reset it".
|
|
360
|
+
- **How do I know a sweep actually settled?** Check `status`.
|
|
361
|
+
`SweepStatus.BROADCASTED` means the transaction is out and not yet confirmed;
|
|
362
|
+
`SweepStatus.COMPLETED` means confirmed, with `sweep_confirmations` and
|
|
363
|
+
`completed_at` filled in. Earlier platform versions reported `completed` at
|
|
364
|
+
broadcast, so a sweep could read as settled while its transaction was still
|
|
365
|
+
unconfirmed.
|
|
366
|
+
- **How do I keep test payments off real chains?** Set `environment` on
|
|
367
|
+
`CreatePayInRequest` to `Environment.TESTNET` or `Environment.MAINNET`. It
|
|
368
|
+
constrains the asset the platform picks when you have not named a concrete
|
|
369
|
+
network - fiat mode and `ANY` - so an unconstrained pick cannot put a real
|
|
370
|
+
payment on a test chain. Omit it to use the project's default.
|
|
337
371
|
|
|
338
372
|
## Documentation
|
|
339
373
|
|
{cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/README.md
RENAMED
|
@@ -82,11 +82,12 @@ Both credentials come from the Dashboard -> Project.
|
|
|
82
82
|
| TON contract calls (Jetton / NFT / text) | `client.transactions` | `jetton_transfer`, `nft_transfer`, `send_ton_comment`, `sign_ton_call` |
|
|
83
83
|
| Accept incoming payments | `client.pay_ins` | `create`, `select_asset`, `reset_asset`, `cancel`, `info`, `history`, `wait_for` |
|
|
84
84
|
| Wallet management + RSA decrypt | `client.wallets` | `generate`, `list`, `info`, `freeze`, `decrypt_private_key` |
|
|
85
|
-
| Treasury sweeps | `client.sweeps` | `force`, `history`, `wallet_history` |
|
|
85
|
+
| Treasury sweeps | `client.sweeps` | `force`, `history`, `wallet_history`, `settings`, `update_settings` |
|
|
86
86
|
| Withdrawals (read-only) | `client.withdrawals` | `info`, `history` |
|
|
87
87
|
| Static-deposit history | `client.static_deposits` | `info`, `history` |
|
|
88
88
|
| On-chain queries | `client.blockchain` | `contracts_available`, `wallet_balance`, `transaction_status` |
|
|
89
89
|
| Fiat <-> crypto rate quote | `client.currencies` | `fiat_to_crypto`, `crypto_to_fiat` |
|
|
90
|
+
| Credits (billing) balance check and top-up - free of charge | `client.credits` | `balance`, `topup` |
|
|
90
91
|
|
|
91
92
|
## Accept a crypto payment (pay-in)
|
|
92
93
|
|
|
@@ -295,6 +296,39 @@ priv = client.wallets.decrypt_private_key(wallet.private_key_encrypted)
|
|
|
295
296
|
- **How do I do a crypto swap?** A swap is a payout with `auto_convert=True`.
|
|
296
297
|
- **How do I call a smart contract?** `client.transactions.sign_evm_call` /
|
|
297
298
|
`sign_anchor_call` / `jetton_transfer`, then `transactions.execute`.
|
|
299
|
+
- **How do I control when a deposit wallet is swept?**
|
|
300
|
+
`client.sweeps.settings(...)` reads the policy in force for one wallet and
|
|
301
|
+
`client.sweeps.update_settings(...)` changes it - sweep on arrival
|
|
302
|
+
(`SweepPolicyMode.MOMENTUM`), sweep once the balance reaches an amount
|
|
303
|
+
(`SweepPolicyMode.THRESHOLD` plus `threshold_amount_usd`), or never on its own
|
|
304
|
+
(`SweepPolicyMode.OFF`, force still works). The read comes back in three
|
|
305
|
+
layers - what will happen, what this wallet overrides, and what it inherits
|
|
306
|
+
from the project - so a value of your own is distinguishable from an inherited
|
|
307
|
+
one:
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
s = await client.sweeps.update_settings(
|
|
311
|
+
deposit_address,
|
|
312
|
+
type_work=SweepPolicyMode.THRESHOLD,
|
|
313
|
+
threshold_amount_usd="250",
|
|
314
|
+
)
|
|
315
|
+
# s.effective is the resolved policy; s.effective.source names the layer it came from.
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Inheritance is per field: overriding the mode leaves the fee mode inherited.
|
|
319
|
+
To stop overriding a field, pass `CLEAR` - `None` already means "leave this
|
|
320
|
+
field alone", so it cannot also mean "reset it".
|
|
321
|
+
- **How do I know a sweep actually settled?** Check `status`.
|
|
322
|
+
`SweepStatus.BROADCASTED` means the transaction is out and not yet confirmed;
|
|
323
|
+
`SweepStatus.COMPLETED` means confirmed, with `sweep_confirmations` and
|
|
324
|
+
`completed_at` filled in. Earlier platform versions reported `completed` at
|
|
325
|
+
broadcast, so a sweep could read as settled while its transaction was still
|
|
326
|
+
unconfirmed.
|
|
327
|
+
- **How do I keep test payments off real chains?** Set `environment` on
|
|
328
|
+
`CreatePayInRequest` to `Environment.TESTNET` or `Environment.MAINNET`. It
|
|
329
|
+
constrains the asset the platform picks when you have not named a concrete
|
|
330
|
+
network - fiat mode and `ANY` - so an unconstrained pick cannot put a real
|
|
331
|
+
payment on a test chain. Omit it to use the project's default.
|
|
298
332
|
|
|
299
333
|
## Documentation
|
|
300
334
|
|
|
@@ -75,10 +75,12 @@ from .services.blockchain import (
|
|
|
75
75
|
TxStatusRow,
|
|
76
76
|
WalletBalanceRow,
|
|
77
77
|
)
|
|
78
|
+
from .services.credits import CreditsBalance, CreditsService, CreditsTopup
|
|
78
79
|
from .services.currencies import ConvertRequest, ConvertResponse, CurrenciesService
|
|
79
80
|
from .services.payins import (
|
|
80
81
|
CoinOption,
|
|
81
82
|
CreatePayInRequest,
|
|
83
|
+
Environment,
|
|
82
84
|
PayIn,
|
|
83
85
|
PayInHistoryResponse,
|
|
84
86
|
PayInMode,
|
|
@@ -109,13 +111,20 @@ from .services.static_deposits import (
|
|
|
109
111
|
StaticDepositsService,
|
|
110
112
|
StaticDepositStatus,
|
|
111
113
|
)
|
|
114
|
+
from .sentinels import CLEAR, Clear
|
|
112
115
|
from .services.sweeps import (
|
|
113
116
|
ForceSweepResponse,
|
|
114
117
|
Sweep,
|
|
118
|
+
SweepFeeMode,
|
|
115
119
|
SweepHistoryQuery,
|
|
116
120
|
SweepHistoryResponse,
|
|
117
121
|
SweepMode,
|
|
122
|
+
SweepOverride,
|
|
123
|
+
SweepPolicy,
|
|
124
|
+
SweepPolicyMode,
|
|
125
|
+
SweepSettings,
|
|
118
126
|
SweepsService,
|
|
127
|
+
SweepStatus,
|
|
119
128
|
)
|
|
120
129
|
from .services.transactions import (
|
|
121
130
|
AnchorCallRequest,
|
|
@@ -170,6 +179,10 @@ from .webhook import (
|
|
|
170
179
|
|
|
171
180
|
__all__ = [
|
|
172
181
|
"__version__",
|
|
182
|
+
# Sentinels
|
|
183
|
+
"CLEAR",
|
|
184
|
+
"Clear",
|
|
185
|
+
"Environment",
|
|
173
186
|
# Client
|
|
174
187
|
"CryptoChiefClient",
|
|
175
188
|
"VERSION",
|
|
@@ -227,6 +240,7 @@ __all__ = [
|
|
|
227
240
|
"StaticDepositsService",
|
|
228
241
|
"BlockchainService",
|
|
229
242
|
"CurrenciesService",
|
|
243
|
+
"CreditsService",
|
|
230
244
|
# Payout types
|
|
231
245
|
"EstimatePayoutRequest",
|
|
232
246
|
"ExecutePayoutRequest",
|
|
@@ -276,10 +290,16 @@ __all__ = [
|
|
|
276
290
|
"WalletType",
|
|
277
291
|
# Sweep types
|
|
278
292
|
"Sweep",
|
|
293
|
+
"SweepFeeMode",
|
|
279
294
|
"SweepHistoryQuery",
|
|
280
295
|
"SweepHistoryResponse",
|
|
281
296
|
"ForceSweepResponse",
|
|
282
297
|
"SweepMode",
|
|
298
|
+
"SweepOverride",
|
|
299
|
+
"SweepPolicy",
|
|
300
|
+
"SweepPolicyMode",
|
|
301
|
+
"SweepSettings",
|
|
302
|
+
"SweepStatus",
|
|
283
303
|
# Withdrawal types
|
|
284
304
|
"Withdrawal",
|
|
285
305
|
"WithdrawalHistoryResponse",
|
|
@@ -296,6 +316,9 @@ __all__ = [
|
|
|
296
316
|
# Currency types
|
|
297
317
|
"ConvertRequest",
|
|
298
318
|
"ConvertResponse",
|
|
319
|
+
# Credits types
|
|
320
|
+
"CreditsBalance",
|
|
321
|
+
"CreditsTopup",
|
|
299
322
|
# Contract encoders
|
|
300
323
|
"encode_evm_call",
|
|
301
324
|
"encode_evm_call_hex",
|
|
@@ -12,6 +12,7 @@ from ._version import __version__
|
|
|
12
12
|
from .errors import CryptoChiefError, is_retryable
|
|
13
13
|
from .rsa import RsaKeyNotConfiguredError, decrypt_rsa_oaep, load_rsa_private_key_pem
|
|
14
14
|
from .services.blockchain import BlockchainService
|
|
15
|
+
from .services.credits import CreditsService
|
|
15
16
|
from .services.currencies import CurrenciesService
|
|
16
17
|
from .services.payins import PayInsService
|
|
17
18
|
from .services.payouts import PayoutsService
|
|
@@ -96,6 +97,7 @@ class CryptoChiefClient:
|
|
|
96
97
|
self.static_deposits = StaticDepositsService(self)
|
|
97
98
|
self.blockchain = BlockchainService(self)
|
|
98
99
|
self.currencies = CurrenciesService(self)
|
|
100
|
+
self.credits = CreditsService(self)
|
|
99
101
|
|
|
100
102
|
async def request(self, path: str, body: Any = None) -> Any:
|
|
101
103
|
"""Low-level signed POST against an API path (e.g. ``/v1/payout/estimate``).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Sentinels for values that ``None`` cannot express.
|
|
2
|
+
|
|
3
|
+
Python has one "absent" value and some APIs need two. Where an argument
|
|
4
|
+
distinguishes "not supplied" from "supplied as nothing", ``None`` takes the
|
|
5
|
+
first meaning and a sentinel from this module takes the second.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Clear:
|
|
12
|
+
"""Stop overriding a field and go back to inheriting it.
|
|
13
|
+
|
|
14
|
+
Used with :meth:`cryptochief.SweepsService.update_settings`, where the API
|
|
15
|
+
expresses "inherit this again" by naming a field and sending no value for
|
|
16
|
+
it. ``None`` already means "leave this field alone", so it cannot also mean
|
|
17
|
+
"reset it".
|
|
18
|
+
|
|
19
|
+
Use the :data:`CLEAR` singleton rather than constructing this.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
_instance: "Clear | None" = None
|
|
23
|
+
|
|
24
|
+
def __new__(cls) -> "Clear":
|
|
25
|
+
if cls._instance is None:
|
|
26
|
+
cls._instance = super().__new__(cls)
|
|
27
|
+
return cls._instance
|
|
28
|
+
|
|
29
|
+
def __repr__(self) -> str:
|
|
30
|
+
return "CLEAR"
|
|
31
|
+
|
|
32
|
+
def __bool__(self) -> bool:
|
|
33
|
+
# Truthy: `if value:` on a CLEAR must not read as "nothing was passed".
|
|
34
|
+
return True
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
#: The singleton :class:`Clear`.
|
|
38
|
+
CLEAR = Clear()
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Merchant credits (billing): balance check and top-up.
|
|
2
|
+
|
|
3
|
+
Both calls are billing-exempt (free of charge) - integrations can poll the
|
|
4
|
+
balance or open a top-up invoice without spending a paid call. Rate-limited to
|
|
5
|
+
60 req/min per project; the balance answers even at zero or negative balance.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
|
|
12
|
+
from .._models import from_dict
|
|
13
|
+
from .base import BaseService
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(kw_only=True)
|
|
17
|
+
class CreditsBalance:
|
|
18
|
+
#: Current balance in credits (10_000_000 credits = 1 USD).
|
|
19
|
+
credits_balance: int = 0
|
|
20
|
+
#: Pre-formatted USD with 2 decimals - can be negative, e.g. ``"-1.52"``.
|
|
21
|
+
usd_balance: str = ""
|
|
22
|
+
is_postpaid: bool = False
|
|
23
|
+
#: Effective debt limit in credits (postpaid only, 0 for prepaid).
|
|
24
|
+
debt_limit_credits: int = 0
|
|
25
|
+
#: Whether gas-paying ops (``/v1/transaction/execute`` etc.) would pass the gate.
|
|
26
|
+
can_execute_gas_operations: bool = False
|
|
27
|
+
#: Minimum credits required for gas-paying operations.
|
|
28
|
+
gas_ops_min_credits: int = 0
|
|
29
|
+
timestamp: str = "" # RFC3339
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(kw_only=True)
|
|
33
|
+
class CreditsTopup:
|
|
34
|
+
#: Billing invoice id.
|
|
35
|
+
invoice_id: int = 0
|
|
36
|
+
#: Hosted payment page (QR code, network selection, live status).
|
|
37
|
+
payment_link: str = ""
|
|
38
|
+
amount: str = ""
|
|
39
|
+
currency: str = ""
|
|
40
|
+
status: str = "" # "pending" on creation
|
|
41
|
+
order_uuid: str = ""
|
|
42
|
+
#: Unix seconds; 0 when the server does not set an expiry.
|
|
43
|
+
expired_at: int = 0
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CreditsService(BaseService):
|
|
47
|
+
async def balance(self) -> CreditsBalance:
|
|
48
|
+
"""Current credits balance - free of charge, safe to poll before paid calls."""
|
|
49
|
+
return from_dict(CreditsBalance, await self._post("/v1/credits/balance", {}))
|
|
50
|
+
|
|
51
|
+
async def topup(
|
|
52
|
+
self,
|
|
53
|
+
*,
|
|
54
|
+
amount: str,
|
|
55
|
+
currency: str,
|
|
56
|
+
url_success: str | None = None,
|
|
57
|
+
url_error: str | None = None,
|
|
58
|
+
) -> CreditsTopup:
|
|
59
|
+
"""Open a credits top-up invoice - free of charge.
|
|
60
|
+
|
|
61
|
+
``amount`` is a positive decimal up to 100000 (USD-pegged), ``currency``
|
|
62
|
+
is ``"USDT"`` or ``"USDC"``. Send the payer to ``payment_link``; the
|
|
63
|
+
optional urls are absolute http(s) redirects after payment.
|
|
64
|
+
"""
|
|
65
|
+
body: dict[str, str] = {"amount": amount, "currency": currency}
|
|
66
|
+
if url_success is not None:
|
|
67
|
+
body["url_success"] = url_success
|
|
68
|
+
if url_error is not None:
|
|
69
|
+
body["url_error"] = url_error
|
|
70
|
+
return from_dict(CreditsTopup, await self._post("/v1/credits/topup", body))
|
|
@@ -38,12 +38,40 @@ def is_payin_terminal(status: str) -> bool:
|
|
|
38
38
|
return status in _PAYIN_TERMINAL
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
class Environment(str, Enum):
|
|
42
|
+
"""The two environments an order can belong to.
|
|
43
|
+
|
|
44
|
+
A project may be allowed one or both; asking for testnet on a project that
|
|
45
|
+
does not permit it is refused with ``TESTNET_NOT_ALLOWED`` rather than
|
|
46
|
+
quietly served on mainnet, and a value that is neither is
|
|
47
|
+
``ENVIRONMENT_INVALID`` rather than a silent fallback.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
MAINNET = "mainnet"
|
|
51
|
+
TESTNET = "testnet"
|
|
52
|
+
|
|
53
|
+
|
|
41
54
|
@dataclass(kw_only=True)
|
|
42
55
|
class CreatePayInRequest:
|
|
43
56
|
order_id: str
|
|
44
57
|
user_id: str
|
|
45
58
|
mode: str
|
|
46
59
|
to_address: Optional[str] = None
|
|
60
|
+
#: Pin the transit deposit wallet of THIS order to the given master wallet of
|
|
61
|
+
#: the project - the address the funds are swept to. The order's
|
|
62
|
+
#: asset/network chain family must match the master wallet's; a foreign or
|
|
63
|
+
#: mismatched address is rejected with 400. Omit for the project-default
|
|
64
|
+
#: behaviour.
|
|
65
|
+
master_wallet_address: Optional[str] = None
|
|
66
|
+
#: Constrain the asset the platform PICKS for this order to the real chains
|
|
67
|
+
#: or the test ones - ``Environment.MAINNET`` or ``Environment.TESTNET``.
|
|
68
|
+
#: Omit to use the project's own default.
|
|
69
|
+
#:
|
|
70
|
+
#: It changes nothing when ``asset`` names a concrete network - that is the
|
|
71
|
+
#: caller's choice. It matters in fiat mode and when the network is ``ANY``,
|
|
72
|
+
#: where the platform selects the asset and an unconstrained pick could put
|
|
73
|
+
#: a real payment on a test network.
|
|
74
|
+
environment: Optional[str] = None
|
|
47
75
|
lifetime_sec: Optional[int] = None
|
|
48
76
|
url_callback: Optional[str] = None
|
|
49
77
|
url_success: Optional[str] = None
|
|
@@ -105,6 +133,10 @@ class SelectAssetRequest:
|
|
|
105
133
|
uuid: str
|
|
106
134
|
coin: str
|
|
107
135
|
network: str
|
|
136
|
+
#: Pin the order's transit deposit wallet to the given project master
|
|
137
|
+
#: wallet; see :class:`CreatePayInRequest`. A value here overrides one
|
|
138
|
+
#: supplied at order create.
|
|
139
|
+
master_wallet_address: Optional[str] = None
|
|
108
140
|
|
|
109
141
|
|
|
110
142
|
class PayInsService(BaseService):
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""Treasury sweeps (transit -> master)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any, List, Optional, Union
|
|
8
|
+
|
|
9
|
+
from .._models import from_dict
|
|
10
|
+
from ..sentinels import Clear
|
|
11
|
+
from ..pagination import HistoryMeta
|
|
12
|
+
from .base import BaseService
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SweepMode(str, Enum):
|
|
16
|
+
AUTO = "auto"
|
|
17
|
+
FORCE = "force"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(kw_only=True)
|
|
21
|
+
class SweepHistoryQuery:
|
|
22
|
+
mode: Optional[str] = None
|
|
23
|
+
page: Optional[int] = None
|
|
24
|
+
page_size: Optional[int] = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SweepStatus(str, Enum):
|
|
28
|
+
"""A sweep is broadcast first and confirmed after.
|
|
29
|
+
|
|
30
|
+
``BROADCASTED`` means the transaction is out and not yet confirmed;
|
|
31
|
+
``COMPLETED`` means the chain confirmed it. The platform used to report
|
|
32
|
+
``completed`` at broadcast, so a sweep could read as settled while its
|
|
33
|
+
transaction was still unconfirmed or had been dropped.
|
|
34
|
+
|
|
35
|
+
``SKIPPED`` is a sweep the platform decided against - almost always a
|
|
36
|
+
balance below the wallet's threshold. A normal outcome, not a failure.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
PENDING = "pending"
|
|
40
|
+
WAITING_GAS = "waiting_gas"
|
|
41
|
+
BROADCASTED = "broadcasted"
|
|
42
|
+
COMPLETED = "completed"
|
|
43
|
+
FAILED = "failed"
|
|
44
|
+
SKIPPED = "skipped"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class SweepPolicyMode(str, Enum):
|
|
48
|
+
"""Auto-sweep modes.
|
|
49
|
+
|
|
50
|
+
``OFF`` is never swept on its own (:meth:`SweepsService.force` still works),
|
|
51
|
+
``MOMENTUM`` sweeps as soon as funds arrive, and ``THRESHOLD`` sweeps once
|
|
52
|
+
the balance reaches ``threshold_amount_usd``. A held balance is re-checked
|
|
53
|
+
periodically, so a wallet that crosses the threshold through price movement
|
|
54
|
+
alone is still swept.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
OFF = "turned_off"
|
|
58
|
+
MOMENTUM = "momentum"
|
|
59
|
+
THRESHOLD = "threshold"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class SweepFeeMode(str, Enum):
|
|
63
|
+
"""Who pays the gas for a sweep.
|
|
64
|
+
|
|
65
|
+
``CLIENT`` takes it from the swept wallet, ``SERVICE`` from the platform's
|
|
66
|
+
service wallet, and ``MIX`` funds the gas from the service wallet and
|
|
67
|
+
reclaims the cost from the sweep.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
CLIENT = "client"
|
|
71
|
+
SERVICE = "service"
|
|
72
|
+
MIX = "mix"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass(kw_only=True)
|
|
76
|
+
class Sweep:
|
|
77
|
+
task_id: str = ""
|
|
78
|
+
status: str = ""
|
|
79
|
+
sweep_tx_hash: Optional[str] = None
|
|
80
|
+
gas_pump_tx_hash: Optional[str] = None
|
|
81
|
+
wallet_address: Optional[str] = None
|
|
82
|
+
chain: Optional[str] = None
|
|
83
|
+
chain_family: Optional[str] = None
|
|
84
|
+
asset_symbol: Optional[str] = None
|
|
85
|
+
asset_type: Optional[str] = None
|
|
86
|
+
amount_human: Optional[str] = None
|
|
87
|
+
#: What triggered this sweep: momentum, threshold or force.
|
|
88
|
+
type_work: Optional[str] = None
|
|
89
|
+
|
|
90
|
+
#: Confirmations seen on the sweep transaction, and when it reached the
|
|
91
|
+
#: network's confirmation target. Read them with ``status``:
|
|
92
|
+
#: ``completed_at`` is absent while the sweep is still in flight.
|
|
93
|
+
sweep_confirmations: Optional[int] = None
|
|
94
|
+
completed_at: Optional[str] = None
|
|
95
|
+
|
|
96
|
+
#: Fees. ``total_fee_usd`` is the whole cost of the sweep; the gas-pump half
|
|
97
|
+
#: is the funding transfer that pays for it on chains needing one. The
|
|
98
|
+
#: ``real_*`` figures are what the chain actually charged, filled in once the
|
|
99
|
+
#: transaction settles; the others are the estimate made up front.
|
|
100
|
+
total_fee_usd: Optional[str] = None
|
|
101
|
+
gas_pump_source: Optional[str] = None
|
|
102
|
+
gas_pump_fee_human: Optional[str] = None
|
|
103
|
+
gas_pump_fee_usd: Optional[str] = None
|
|
104
|
+
sweep_fee_human: Optional[str] = None
|
|
105
|
+
sweep_fee_usd: Optional[str] = None
|
|
106
|
+
real_gas_pump_fee_human: Optional[str] = None
|
|
107
|
+
real_gas_pump_fee_usd: Optional[str] = None
|
|
108
|
+
real_sweep_fee_human: Optional[str] = None
|
|
109
|
+
real_sweep_fee_usd: Optional[str] = None
|
|
110
|
+
|
|
111
|
+
created_at: Optional[str] = None
|
|
112
|
+
|
|
113
|
+
#: Deprecated: never populated. The API reports fees under the names above;
|
|
114
|
+
#: these were guesses at a shape it does not send.
|
|
115
|
+
gas_fee_human: Optional[str] = None
|
|
116
|
+
gas_fee_fiat: Optional[str] = None
|
|
117
|
+
service_fee_fiat: Optional[str] = None
|
|
118
|
+
#: Deprecated: never populated - sweeps carry ``created_at`` and
|
|
119
|
+
#: ``completed_at``.
|
|
120
|
+
updated_at: Optional[str] = None
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@dataclass(kw_only=True)
|
|
124
|
+
class SweepPolicy:
|
|
125
|
+
"""A resolved set of sweep rules."""
|
|
126
|
+
|
|
127
|
+
type_work: str = ""
|
|
128
|
+
#: Meaningful only when ``type_work`` is ``threshold``.
|
|
129
|
+
threshold_amount_usd: Optional[str] = None
|
|
130
|
+
fee_mode: str = ""
|
|
131
|
+
#: Which layer the mode came from: ``wallet_network``, ``wallet``,
|
|
132
|
+
#: ``project`` or ``default``. Present on the effective policy, where the
|
|
133
|
+
#: question arises.
|
|
134
|
+
source: Optional[str] = None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@dataclass(kw_only=True)
|
|
138
|
+
class SweepOverride:
|
|
139
|
+
"""What one wallet decides for itself.
|
|
140
|
+
|
|
141
|
+
A field of ``None`` is not overridden - it is inherited, which no ordinary
|
|
142
|
+
value can express.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
#: Empty covers the address on every network it exists on; set, it covers
|
|
146
|
+
#: that one network and takes precedence over the address-wide override.
|
|
147
|
+
network_code: Optional[str] = None
|
|
148
|
+
type_work: Optional[str] = None
|
|
149
|
+
threshold_amount_usd: Optional[str] = None
|
|
150
|
+
fee_mode: Optional[str] = None
|
|
151
|
+
#: Who wrote it: ``merchant`` or ``operator``.
|
|
152
|
+
source: Optional[str] = None
|
|
153
|
+
#: An operator pinned this policy. While it is set, a merchant write answers
|
|
154
|
+
#: ``SWEEP_SETTINGS_LOCKED`` and changes nothing.
|
|
155
|
+
locked: bool = False
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass(kw_only=True)
|
|
159
|
+
class SweepSettings:
|
|
160
|
+
"""Three layers, on purpose.
|
|
161
|
+
|
|
162
|
+
``effective`` is what will actually happen, ``override`` is what this wallet
|
|
163
|
+
decides for itself (``None`` if it decides nothing), and ``project_default``
|
|
164
|
+
is what it falls back to. Only the three together answer "is this value mine
|
|
165
|
+
or inherited" - the difference between changing it here and changing it on
|
|
166
|
+
the project. Inheritance is per field: a wallet can override the mode and
|
|
167
|
+
keep inheriting the fee mode.
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
wallet_address: Optional[str] = None
|
|
171
|
+
network_code: Optional[str] = None
|
|
172
|
+
effective: Optional[SweepPolicy] = None
|
|
173
|
+
override: Optional[SweepOverride] = None
|
|
174
|
+
project_default: Optional[SweepPolicy] = None
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@dataclass(kw_only=True)
|
|
178
|
+
class SweepHistoryResponse:
|
|
179
|
+
items: Optional[List[Sweep]] = None
|
|
180
|
+
meta: Optional[HistoryMeta] = None
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@dataclass(kw_only=True)
|
|
184
|
+
class ForceSweepResponse:
|
|
185
|
+
status: str = ""
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class SweepsService(BaseService):
|
|
189
|
+
async def force(self, address: str, network: str) -> ForceSweepResponse:
|
|
190
|
+
"""Trigger an immediate transit->master sweep for one address.
|
|
191
|
+
|
|
192
|
+
The status acknowledges acceptance; the resulting :class:`Sweep` record
|
|
193
|
+
appears via :meth:`wallet_history` once the on-chain tx is built.
|
|
194
|
+
"""
|
|
195
|
+
return from_dict(
|
|
196
|
+
ForceSweepResponse,
|
|
197
|
+
await self._post("/v1/sweeps/force", {"address": address, "network_code": network}),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
async def history(self, query: Optional[SweepHistoryQuery] = None) -> SweepHistoryResponse:
|
|
201
|
+
"""Recent sweeps across the whole project."""
|
|
202
|
+
return from_dict(
|
|
203
|
+
SweepHistoryResponse, await self._post("/v1/sweeps/history", query or SweepHistoryQuery())
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
async def wallet_history(
|
|
207
|
+
self, address: str, query: Optional[SweepHistoryQuery] = None
|
|
208
|
+
) -> SweepHistoryResponse:
|
|
209
|
+
"""Recent sweeps scoped to one wallet."""
|
|
210
|
+
body: dict[str, Any] = {"address": address}
|
|
211
|
+
if query is not None:
|
|
212
|
+
if query.mode is not None:
|
|
213
|
+
body["mode"] = query.mode
|
|
214
|
+
if query.page is not None:
|
|
215
|
+
body["page"] = query.page
|
|
216
|
+
if query.page_size is not None:
|
|
217
|
+
body["page_size"] = query.page_size
|
|
218
|
+
return from_dict(SweepHistoryResponse, await self._post("/v1/sweeps/wallet/history", body))
|
|
219
|
+
|
|
220
|
+
async def settings(
|
|
221
|
+
self, address: Optional[str] = None, network_code: Optional[str] = None
|
|
222
|
+
) -> SweepSettings:
|
|
223
|
+
"""The auto-sweep policy in force for one wallet.
|
|
224
|
+
|
|
225
|
+
Returns what will happen, what the wallet overrides, and what it
|
|
226
|
+
inherits. Omitting ``address`` asks for the project's own default rather
|
|
227
|
+
than any wallet's policy.
|
|
228
|
+
|
|
229
|
+
Scoped to the caller's own wallets: an address that is not the project's
|
|
230
|
+
answers ``WALLET_NOT_FOUND``.
|
|
231
|
+
"""
|
|
232
|
+
body: dict[str, Any] = {}
|
|
233
|
+
if address:
|
|
234
|
+
body["address"] = address
|
|
235
|
+
if network_code:
|
|
236
|
+
body["network_code"] = network_code
|
|
237
|
+
return from_dict(SweepSettings, await self._post("/v1/sweeps/settings", body))
|
|
238
|
+
|
|
239
|
+
async def update_settings(
|
|
240
|
+
self,
|
|
241
|
+
address: str,
|
|
242
|
+
*,
|
|
243
|
+
network_code: Optional[str] = None,
|
|
244
|
+
type_work: Union[str, Clear, None] = None,
|
|
245
|
+
threshold_amount_usd: Union[str, Clear, None] = None,
|
|
246
|
+
fee_mode: Union[str, Clear, None] = None,
|
|
247
|
+
) -> SweepSettings:
|
|
248
|
+
"""Write a wallet's auto-sweep policy.
|
|
249
|
+
|
|
250
|
+
Returns the settings as they stand afterwards, so the caller sees what
|
|
251
|
+
the write resolved to without asking again.
|
|
252
|
+
|
|
253
|
+
``None`` leaves a field alone. :data:`~cryptochief.CLEAR` stops
|
|
254
|
+
overriding it and goes back to inheriting - the only way to drop one
|
|
255
|
+
field while keeping the others. The API expresses that by naming the
|
|
256
|
+
field with no value, which ``None`` cannot say in Python because it
|
|
257
|
+
already means "not supplied".
|
|
258
|
+
|
|
259
|
+
Refusals are named: ``TYPE_WORK_INVALID``, ``FEE_MODE_INVALID``,
|
|
260
|
+
``THRESHOLD_INVALID``, ``THRESHOLD_MUST_BE_POSITIVE``,
|
|
261
|
+
``THRESHOLD_REQUIRED_FOR_THRESHOLD_MODE``, and
|
|
262
|
+
``SWEEP_SETTINGS_LOCKED`` when an operator has pinned the policy.
|
|
263
|
+
"""
|
|
264
|
+
body: dict[str, Any] = {"address": address}
|
|
265
|
+
if network_code:
|
|
266
|
+
body["network_code"] = network_code
|
|
267
|
+
|
|
268
|
+
fields: List[str] = []
|
|
269
|
+
for name, value in (
|
|
270
|
+
("type_work", type_work),
|
|
271
|
+
("threshold_amount_usd", threshold_amount_usd),
|
|
272
|
+
("fee_mode", fee_mode),
|
|
273
|
+
):
|
|
274
|
+
if value is None:
|
|
275
|
+
continue
|
|
276
|
+
fields.append(name)
|
|
277
|
+
if not isinstance(value, Clear):
|
|
278
|
+
body[name] = value.value if isinstance(value, Enum) else value
|
|
279
|
+
if fields:
|
|
280
|
+
body["fields"] = fields
|
|
281
|
+
|
|
282
|
+
return from_dict(SweepSettings, await self._post("/v1/sweeps/settings/update", body))
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"""Treasury sweeps (transit -> master)."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from dataclasses import dataclass
|
|
6
|
-
from enum import Enum
|
|
7
|
-
from typing import Any, List, Optional
|
|
8
|
-
|
|
9
|
-
from .._models import from_dict
|
|
10
|
-
from ..pagination import HistoryMeta
|
|
11
|
-
from .base import BaseService
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class SweepMode(str, Enum):
|
|
15
|
-
AUTO = "auto"
|
|
16
|
-
FORCE = "force"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclass(kw_only=True)
|
|
20
|
-
class SweepHistoryQuery:
|
|
21
|
-
mode: Optional[str] = None
|
|
22
|
-
page: Optional[int] = None
|
|
23
|
-
page_size: Optional[int] = None
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@dataclass(kw_only=True)
|
|
27
|
-
class Sweep:
|
|
28
|
-
task_id: str = ""
|
|
29
|
-
status: str = ""
|
|
30
|
-
sweep_tx_hash: Optional[str] = None
|
|
31
|
-
wallet_address: Optional[str] = None
|
|
32
|
-
chain: Optional[str] = None
|
|
33
|
-
chain_family: Optional[str] = None
|
|
34
|
-
asset_symbol: Optional[str] = None
|
|
35
|
-
asset_type: Optional[str] = None
|
|
36
|
-
amount_human: Optional[str] = None
|
|
37
|
-
gas_fee_human: Optional[str] = None
|
|
38
|
-
gas_fee_fiat: Optional[str] = None
|
|
39
|
-
service_fee_fiat: Optional[str] = None
|
|
40
|
-
created_at: Optional[str] = None
|
|
41
|
-
updated_at: Optional[str] = None
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@dataclass(kw_only=True)
|
|
45
|
-
class SweepHistoryResponse:
|
|
46
|
-
items: Optional[List[Sweep]] = None
|
|
47
|
-
meta: Optional[HistoryMeta] = None
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@dataclass(kw_only=True)
|
|
51
|
-
class ForceSweepResponse:
|
|
52
|
-
status: str = ""
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class SweepsService(BaseService):
|
|
56
|
-
async def force(self, address: str, network: str) -> ForceSweepResponse:
|
|
57
|
-
"""Trigger an immediate transit->master sweep for one address.
|
|
58
|
-
|
|
59
|
-
The status acknowledges acceptance; the resulting :class:`Sweep` record
|
|
60
|
-
appears via :meth:`wallet_history` once the on-chain tx is built.
|
|
61
|
-
"""
|
|
62
|
-
return from_dict(
|
|
63
|
-
ForceSweepResponse,
|
|
64
|
-
await self._post("/v1/sweeps/force", {"address": address, "network_code": network}),
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
async def history(self, query: Optional[SweepHistoryQuery] = None) -> SweepHistoryResponse:
|
|
68
|
-
"""Recent sweeps across the whole project."""
|
|
69
|
-
return from_dict(
|
|
70
|
-
SweepHistoryResponse, await self._post("/v1/sweeps/history", query or SweepHistoryQuery())
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
async def wallet_history(
|
|
74
|
-
self, address: str, query: Optional[SweepHistoryQuery] = None
|
|
75
|
-
) -> SweepHistoryResponse:
|
|
76
|
-
"""Recent sweeps scoped to one wallet."""
|
|
77
|
-
body: dict[str, Any] = {"address": address}
|
|
78
|
-
if query is not None:
|
|
79
|
-
if query.mode is not None:
|
|
80
|
-
body["mode"] = query.mode
|
|
81
|
-
if query.page is not None:
|
|
82
|
-
body["page"] = query.page
|
|
83
|
-
if query.page_size is not None:
|
|
84
|
-
body["page_size"] = query.page_size
|
|
85
|
-
return from_dict(SweepHistoryResponse, await self._post("/v1/sweeps/wallet/history", body))
|
{cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/.gitignore
RENAMED
|
File without changes
|
{cryptochief_crypto_processing_python-0.1.0 → cryptochief_crypto_processing_python-0.4.0}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|