cryptochief-crypto-processing-python 0.2.0__tar.gz → 0.5.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.2.0 → cryptochief_crypto_processing_python-0.5.0}/PKG-INFO +43 -2
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/README.md +42 -1
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/pyproject.toml +1 -1
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/__init__.py +22 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/_version.py +1 -1
- cryptochief_crypto_processing_python-0.5.0/src/cryptochief/py.typed +0 -0
- cryptochief_crypto_processing_python-0.5.0/src/cryptochief/sentinels.py +38 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/payins.py +32 -0
- cryptochief_crypto_processing_python-0.5.0/src/cryptochief/services/sweeps.py +282 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/webhook.py +65 -0
- cryptochief_crypto_processing_python-0.2.0/src/cryptochief/services/sweeps.py +0 -85
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/.gitignore +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/LICENSE +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/_models.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/amount.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/assets.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/chains.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/client.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/contract/__init__.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/contract/base58.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/contract/borsh.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/contract/evm_abi.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/contract/keccak.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/contract/tron_address.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/errors.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/pagination.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/poll.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/rsa.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/__init__.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/base.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/blockchain.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/credits.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/currencies.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/payouts.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/static_deposits.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/transactions.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/wallets.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/services/withdrawals.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/sign.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/ton/__init__.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/ton/address.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/ton/messages.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/ton/rpc.py +0 -0
- {cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/src/cryptochief/transport.py +0 -0
{cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cryptochief-crypto-processing-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.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
|
|
@@ -121,7 +121,7 @@ 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` |
|
|
@@ -200,6 +200,14 @@ decimal strings round-trip exactly. Discover an asset's decimals with
|
|
|
200
200
|
|
|
201
201
|
## Contract calls without hand-encoding
|
|
202
202
|
|
|
203
|
+
> **This snippet shows the encoder, not a complete swap.** Uniswap's router
|
|
204
|
+
> moves your input token with `transferFrom`, so it needs an ERC-20
|
|
205
|
+
> `approve(address,uint256)` on that token first, confirmed before the swap is
|
|
206
|
+
> signed — without it the swap reverts and burns the gas. And an `amountOutMin`
|
|
207
|
+
> of `0` accepts whatever the pool returns, which on a public mempool hands the
|
|
208
|
+
> trade to the first sandwich bot that sees it. The runnable version, with both,
|
|
209
|
+
> is in `examples/`.
|
|
210
|
+
|
|
203
211
|
```python
|
|
204
212
|
from cryptochief import EvmCallRequest, Erc20TransferRequest, Chain, human_to_base
|
|
205
213
|
|
|
@@ -335,6 +343,39 @@ priv = client.wallets.decrypt_private_key(wallet.private_key_encrypted)
|
|
|
335
343
|
- **How do I do a crypto swap?** A swap is a payout with `auto_convert=True`.
|
|
336
344
|
- **How do I call a smart contract?** `client.transactions.sign_evm_call` /
|
|
337
345
|
`sign_anchor_call` / `jetton_transfer`, then `transactions.execute`.
|
|
346
|
+
- **How do I control when a deposit wallet is swept?**
|
|
347
|
+
`client.sweeps.settings(...)` reads the policy in force for one wallet and
|
|
348
|
+
`client.sweeps.update_settings(...)` changes it - sweep on arrival
|
|
349
|
+
(`SweepPolicyMode.MOMENTUM`), sweep once the balance reaches an amount
|
|
350
|
+
(`SweepPolicyMode.THRESHOLD` plus `threshold_amount_usd`), or never on its own
|
|
351
|
+
(`SweepPolicyMode.OFF`, force still works). The read comes back in three
|
|
352
|
+
layers - what will happen, what this wallet overrides, and what it inherits
|
|
353
|
+
from the project - so a value of your own is distinguishable from an inherited
|
|
354
|
+
one:
|
|
355
|
+
|
|
356
|
+
```python
|
|
357
|
+
s = await client.sweeps.update_settings(
|
|
358
|
+
deposit_address,
|
|
359
|
+
type_work=SweepPolicyMode.THRESHOLD,
|
|
360
|
+
threshold_amount_usd="250",
|
|
361
|
+
)
|
|
362
|
+
# s.effective is the resolved policy; s.effective.source names the layer it came from.
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Inheritance is per field: overriding the mode leaves the fee mode inherited.
|
|
366
|
+
To stop overriding a field, pass `CLEAR` - `None` already means "leave this
|
|
367
|
+
field alone", so it cannot also mean "reset it".
|
|
368
|
+
- **How do I know a sweep actually settled?** Check `status`.
|
|
369
|
+
`SweepStatus.BROADCASTED` means the transaction is out and not yet confirmed;
|
|
370
|
+
`SweepStatus.COMPLETED` means confirmed, with `sweep_confirmations` and
|
|
371
|
+
`completed_at` filled in. Earlier platform versions reported `completed` at
|
|
372
|
+
broadcast, so a sweep could read as settled while its transaction was still
|
|
373
|
+
unconfirmed.
|
|
374
|
+
- **How do I keep test payments off real chains?** Set `environment` on
|
|
375
|
+
`CreatePayInRequest` to `Environment.TESTNET` or `Environment.MAINNET`. It
|
|
376
|
+
constrains the asset the platform picks when you have not named a concrete
|
|
377
|
+
network - fiat mode and `ANY` - so an unconstrained pick cannot put a real
|
|
378
|
+
payment on a test chain. Omit it to use the project's default.
|
|
338
379
|
|
|
339
380
|
## Documentation
|
|
340
381
|
|
{cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.0}/README.md
RENAMED
|
@@ -82,7 +82,7 @@ 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` |
|
|
@@ -161,6 +161,14 @@ decimal strings round-trip exactly. Discover an asset's decimals with
|
|
|
161
161
|
|
|
162
162
|
## Contract calls without hand-encoding
|
|
163
163
|
|
|
164
|
+
> **This snippet shows the encoder, not a complete swap.** Uniswap's router
|
|
165
|
+
> moves your input token with `transferFrom`, so it needs an ERC-20
|
|
166
|
+
> `approve(address,uint256)` on that token first, confirmed before the swap is
|
|
167
|
+
> signed — without it the swap reverts and burns the gas. And an `amountOutMin`
|
|
168
|
+
> of `0` accepts whatever the pool returns, which on a public mempool hands the
|
|
169
|
+
> trade to the first sandwich bot that sees it. The runnable version, with both,
|
|
170
|
+
> is in `examples/`.
|
|
171
|
+
|
|
164
172
|
```python
|
|
165
173
|
from cryptochief import EvmCallRequest, Erc20TransferRequest, Chain, human_to_base
|
|
166
174
|
|
|
@@ -296,6 +304,39 @@ priv = client.wallets.decrypt_private_key(wallet.private_key_encrypted)
|
|
|
296
304
|
- **How do I do a crypto swap?** A swap is a payout with `auto_convert=True`.
|
|
297
305
|
- **How do I call a smart contract?** `client.transactions.sign_evm_call` /
|
|
298
306
|
`sign_anchor_call` / `jetton_transfer`, then `transactions.execute`.
|
|
307
|
+
- **How do I control when a deposit wallet is swept?**
|
|
308
|
+
`client.sweeps.settings(...)` reads the policy in force for one wallet and
|
|
309
|
+
`client.sweeps.update_settings(...)` changes it - sweep on arrival
|
|
310
|
+
(`SweepPolicyMode.MOMENTUM`), sweep once the balance reaches an amount
|
|
311
|
+
(`SweepPolicyMode.THRESHOLD` plus `threshold_amount_usd`), or never on its own
|
|
312
|
+
(`SweepPolicyMode.OFF`, force still works). The read comes back in three
|
|
313
|
+
layers - what will happen, what this wallet overrides, and what it inherits
|
|
314
|
+
from the project - so a value of your own is distinguishable from an inherited
|
|
315
|
+
one:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
s = await client.sweeps.update_settings(
|
|
319
|
+
deposit_address,
|
|
320
|
+
type_work=SweepPolicyMode.THRESHOLD,
|
|
321
|
+
threshold_amount_usd="250",
|
|
322
|
+
)
|
|
323
|
+
# s.effective is the resolved policy; s.effective.source names the layer it came from.
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Inheritance is per field: overriding the mode leaves the fee mode inherited.
|
|
327
|
+
To stop overriding a field, pass `CLEAR` - `None` already means "leave this
|
|
328
|
+
field alone", so it cannot also mean "reset it".
|
|
329
|
+
- **How do I know a sweep actually settled?** Check `status`.
|
|
330
|
+
`SweepStatus.BROADCASTED` means the transaction is out and not yet confirmed;
|
|
331
|
+
`SweepStatus.COMPLETED` means confirmed, with `sweep_confirmations` and
|
|
332
|
+
`completed_at` filled in. Earlier platform versions reported `completed` at
|
|
333
|
+
broadcast, so a sweep could read as settled while its transaction was still
|
|
334
|
+
unconfirmed.
|
|
335
|
+
- **How do I keep test payments off real chains?** Set `environment` on
|
|
336
|
+
`CreatePayInRequest` to `Environment.TESTNET` or `Environment.MAINNET`. It
|
|
337
|
+
constrains the asset the platform picks when you have not named a concrete
|
|
338
|
+
network - fiat mode and `ANY` - so an unconstrained pick cannot put a real
|
|
339
|
+
payment on a test chain. Omit it to use the project's default.
|
|
299
340
|
|
|
300
341
|
## Documentation
|
|
301
342
|
|
|
@@ -80,6 +80,7 @@ from .services.currencies import ConvertRequest, ConvertResponse, CurrenciesServ
|
|
|
80
80
|
from .services.payins import (
|
|
81
81
|
CoinOption,
|
|
82
82
|
CreatePayInRequest,
|
|
83
|
+
Environment,
|
|
83
84
|
PayIn,
|
|
84
85
|
PayInHistoryResponse,
|
|
85
86
|
PayInMode,
|
|
@@ -110,13 +111,20 @@ from .services.static_deposits import (
|
|
|
110
111
|
StaticDepositsService,
|
|
111
112
|
StaticDepositStatus,
|
|
112
113
|
)
|
|
114
|
+
from .sentinels import CLEAR, Clear
|
|
113
115
|
from .services.sweeps import (
|
|
114
116
|
ForceSweepResponse,
|
|
115
117
|
Sweep,
|
|
118
|
+
SweepFeeMode,
|
|
116
119
|
SweepHistoryQuery,
|
|
117
120
|
SweepHistoryResponse,
|
|
118
121
|
SweepMode,
|
|
122
|
+
SweepOverride,
|
|
123
|
+
SweepPolicy,
|
|
124
|
+
SweepPolicyMode,
|
|
125
|
+
SweepSettings,
|
|
119
126
|
SweepsService,
|
|
127
|
+
SweepStatus,
|
|
120
128
|
)
|
|
121
129
|
from .services.transactions import (
|
|
122
130
|
AnchorCallRequest,
|
|
@@ -162,6 +170,8 @@ from .webhook import (
|
|
|
162
170
|
PayInWebhookEvent,
|
|
163
171
|
PayoutWebhookEvent,
|
|
164
172
|
StaticDepositWebhookEvent,
|
|
173
|
+
SweepWebhookEvent,
|
|
174
|
+
SWEEP_EVENT_CONFIRMED,
|
|
165
175
|
TransactionWebhookEvent,
|
|
166
176
|
WebhookSignatureError,
|
|
167
177
|
coerce_webhook_event,
|
|
@@ -171,6 +181,10 @@ from .webhook import (
|
|
|
171
181
|
|
|
172
182
|
__all__ = [
|
|
173
183
|
"__version__",
|
|
184
|
+
# Sentinels
|
|
185
|
+
"CLEAR",
|
|
186
|
+
"Clear",
|
|
187
|
+
"Environment",
|
|
174
188
|
# Client
|
|
175
189
|
"CryptoChiefClient",
|
|
176
190
|
"VERSION",
|
|
@@ -218,6 +232,8 @@ __all__ = [
|
|
|
218
232
|
"TransactionWebhookEvent",
|
|
219
233
|
"PayInWebhookEvent",
|
|
220
234
|
"StaticDepositWebhookEvent",
|
|
235
|
+
"SweepWebhookEvent",
|
|
236
|
+
"SWEEP_EVENT_CONFIRMED",
|
|
221
237
|
# Services
|
|
222
238
|
"PayoutsService",
|
|
223
239
|
"TransactionsService",
|
|
@@ -278,10 +294,16 @@ __all__ = [
|
|
|
278
294
|
"WalletType",
|
|
279
295
|
# Sweep types
|
|
280
296
|
"Sweep",
|
|
297
|
+
"SweepFeeMode",
|
|
281
298
|
"SweepHistoryQuery",
|
|
282
299
|
"SweepHistoryResponse",
|
|
283
300
|
"ForceSweepResponse",
|
|
284
301
|
"SweepMode",
|
|
302
|
+
"SweepOverride",
|
|
303
|
+
"SweepPolicy",
|
|
304
|
+
"SweepPolicyMode",
|
|
305
|
+
"SweepSettings",
|
|
306
|
+
"SweepStatus",
|
|
285
307
|
# Withdrawal types
|
|
286
308
|
"Withdrawal",
|
|
287
309
|
"WithdrawalHistoryResponse",
|
|
File without changes
|
|
@@ -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()
|
|
@@ -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))
|
|
@@ -175,11 +175,75 @@ class StaticDepositWebhookEvent:
|
|
|
175
175
|
paid_at: Optional[str] = None
|
|
176
176
|
|
|
177
177
|
|
|
178
|
+
#: The only sweep event the platform emits. There is deliberately no
|
|
179
|
+
#: ``sweep.broadcasted``: "we sent it" is not something you can act on, and an
|
|
180
|
+
#: event that means "maybe" is one more thing to reconcile.
|
|
181
|
+
SWEEP_EVENT_CONFIRMED = "sweep.confirmed"
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@dataclass(kw_only=True)
|
|
185
|
+
class SweepWebhookEvent:
|
|
186
|
+
"""Funds swept off a deposit wallet, confirmed on chain.
|
|
187
|
+
|
|
188
|
+
A ``static_deposit.paid`` tells you a customer paid you. This tells you the
|
|
189
|
+
money has finished moving into your own custody - until it fires, the
|
|
190
|
+
balance still sits on the deposit address. Reconciliation, treasury
|
|
191
|
+
reporting and "funds available to pay out" all key off this event, not off
|
|
192
|
+
the deposit.
|
|
193
|
+
|
|
194
|
+
Sweeps run on static deposit wallets *and* on the transit wallets issued per
|
|
195
|
+
pay-in order; both deliver here, to the callback URL configured for the
|
|
196
|
+
wallet the funds left.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
event: str = ""
|
|
200
|
+
#: The sweeper task. One sweep settles once - use it as your idempotency key.
|
|
201
|
+
task_id: str = ""
|
|
202
|
+
#: Always ``"completed"``. A sweep reaches you in no other state.
|
|
203
|
+
status: str = ""
|
|
204
|
+
|
|
205
|
+
#: The wallet the funds left - the address your customer paid into.
|
|
206
|
+
wallet_address: str = ""
|
|
207
|
+
#: The master wallet they landed on.
|
|
208
|
+
to_address: Optional[str] = None
|
|
209
|
+
|
|
210
|
+
network: str = ""
|
|
211
|
+
chain_family: Optional[str] = None
|
|
212
|
+
asset_symbol: str = ""
|
|
213
|
+
asset_contract: Optional[str] = None
|
|
214
|
+
#: ``"native"`` or ``"token"``.
|
|
215
|
+
asset_type: Optional[str] = None
|
|
216
|
+
amount_raw: Optional[str] = None
|
|
217
|
+
amount_human: Optional[str] = None
|
|
218
|
+
|
|
219
|
+
sweep_tx_hash: str = ""
|
|
220
|
+
#: Set when the platform had to fund gas on the wallet before it could sweep.
|
|
221
|
+
gas_pump_tx_hash: Optional[str] = None
|
|
222
|
+
|
|
223
|
+
#: What makes this event true rather than hopeful, and never zero. It
|
|
224
|
+
#: travels with the event rather than being implied by it: "confirmed" is
|
|
225
|
+
#: not the same number on every chain, so if you run your own finality
|
|
226
|
+
#: policy you need the count to apply it.
|
|
227
|
+
sweep_confirmations: int = 0
|
|
228
|
+
|
|
229
|
+
#: When the chain was observed to hold the sweep. NOT the task's completion
|
|
230
|
+
#: timestamp, which is stamped on every terminal outcome - failures
|
|
231
|
+
#: included - and so says nothing about settlement.
|
|
232
|
+
confirmed_at: Optional[str] = None
|
|
233
|
+
|
|
234
|
+
#: What triggered it: ``"momentum"``, ``"threshold"`` or ``"force"``.
|
|
235
|
+
type_work: Optional[str] = None
|
|
236
|
+
#: What the sweep cost: network fee plus any gas or energy the platform
|
|
237
|
+
#: fronted to make it possible.
|
|
238
|
+
total_fee_usd: Optional[str] = None
|
|
239
|
+
|
|
240
|
+
|
|
178
241
|
WebhookEvent = Union[
|
|
179
242
|
PayoutWebhookEvent,
|
|
180
243
|
TransactionWebhookEvent,
|
|
181
244
|
PayInWebhookEvent,
|
|
182
245
|
StaticDepositWebhookEvent,
|
|
246
|
+
SweepWebhookEvent,
|
|
183
247
|
Dict[str, Any],
|
|
184
248
|
]
|
|
185
249
|
|
|
@@ -188,4 +252,5 @@ _EVENT_BY_PREFIX = {
|
|
|
188
252
|
"transaction": TransactionWebhookEvent,
|
|
189
253
|
"invoice": PayInWebhookEvent,
|
|
190
254
|
"static_deposit": StaticDepositWebhookEvent,
|
|
255
|
+
"sweep": SweepWebhookEvent,
|
|
191
256
|
}
|
|
@@ -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.2.0 → cryptochief_crypto_processing_python-0.5.0}/.gitignore
RENAMED
|
File without changes
|
{cryptochief_crypto_processing_python-0.2.0 → cryptochief_crypto_processing_python-0.5.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
|