flexvaults 0.1.5__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.
Files changed (31) hide show
  1. flexvaults-0.1.5/.gitignore +34 -0
  2. flexvaults-0.1.5/PKG-INFO +140 -0
  3. flexvaults-0.1.5/README.md +107 -0
  4. flexvaults-0.1.5/pyproject.toml +67 -0
  5. flexvaults-0.1.5/src/flexvaults/__init__.py +168 -0
  6. flexvaults-0.1.5/src/flexvaults/client/__init__.py +11 -0
  7. flexvaults-0.1.5/src/flexvaults/client/errors.py +33 -0
  8. flexvaults-0.1.5/src/flexvaults/client/flexvaults_client.py +358 -0
  9. flexvaults-0.1.5/src/flexvaults/client/http_client.py +86 -0
  10. flexvaults-0.1.5/src/flexvaults/py.typed +0 -0
  11. flexvaults-0.1.5/src/flexvaults/signatures/__init__.py +38 -0
  12. flexvaults-0.1.5/src/flexvaults/signatures/_signer.py +49 -0
  13. flexvaults-0.1.5/src/flexvaults/signatures/eip712_types.py +93 -0
  14. flexvaults-0.1.5/src/flexvaults/signatures/sign_lock.py +43 -0
  15. flexvaults-0.1.5/src/flexvaults/signatures/sign_transfer.py +36 -0
  16. flexvaults-0.1.5/src/flexvaults/signatures/sign_transfer_locked.py +36 -0
  17. flexvaults-0.1.5/src/flexvaults/signatures/sign_withdraw.py +36 -0
  18. flexvaults-0.1.5/src/flexvaults/types/__init__.py +105 -0
  19. flexvaults-0.1.5/src/flexvaults/types/chains.py +52 -0
  20. flexvaults-0.1.5/src/flexvaults/types/common.py +57 -0
  21. flexvaults-0.1.5/src/flexvaults/types/requests.py +76 -0
  22. flexvaults-0.1.5/src/flexvaults/types/responses.py +128 -0
  23. flexvaults-0.1.5/src/flexvaults/types/tokens.py +43 -0
  24. flexvaults-0.1.5/src/flexvaults/utils.py +79 -0
  25. flexvaults-0.1.5/tests/__init__.py +0 -0
  26. flexvaults-0.1.5/tests/test_client.py +464 -0
  27. flexvaults-0.1.5/tests/test_errors.py +41 -0
  28. flexvaults-0.1.5/tests/test_package.py +58 -0
  29. flexvaults-0.1.5/tests/test_signatures.py +198 -0
  30. flexvaults-0.1.5/tests/test_types.py +125 -0
  31. flexvaults-0.1.5/tests/test_utils.py +131 -0
@@ -0,0 +1,34 @@
1
+ # dependencies
2
+ node_modules/
3
+
4
+ # build outputs
5
+ dist/
6
+ .next/
7
+ out/
8
+ build/
9
+ *.compiled.css
10
+ packages/sdk/src/compiled.css
11
+
12
+ # turbo
13
+ .turbo/
14
+
15
+ # testing
16
+ coverage/
17
+
18
+ # env
19
+ .env*
20
+
21
+ # misc
22
+ .DS_Store
23
+ *.pem
24
+ *.log
25
+
26
+ # typescript
27
+ *.tsbuildinfo
28
+
29
+ # IDE
30
+ .idea/
31
+ .vscode/
32
+
33
+ # vercel
34
+ .vercel
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.4
2
+ Name: flexvaults
3
+ Version: 0.1.5
4
+ Summary: Python SDK for Flexvaults - manage deposits, withdrawals, locks, and transfers
5
+ Project-URL: Homepage, https://github.com/oasisprotocol/flexvaults-sdk
6
+ Project-URL: Repository, https://github.com/oasisprotocol/flexvaults-sdk
7
+ Project-URL: Issues, https://github.com/oasisprotocol/flexvaults-sdk/issues
8
+ Author-email: Oasis Protocol Foundation <security@oasisprotocol.org>
9
+ License-Expression: Apache-2.0
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: eth-account>=0.13.0
22
+ Requires-Dist: eth-typing>=5.0.0
23
+ Requires-Dist: httpx>=0.27.0
24
+ Requires-Dist: pydantic>=2.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: mypy>=1.11.0; extra == 'dev'
27
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
28
+ Requires-Dist: pytest-httpx>=0.34.0; extra == 'dev'
29
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
30
+ Requires-Dist: respx>=0.22.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.7.0; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # flexvaults
35
+
36
+ Python SDK for Flexvaults - manage deposits, withdrawals, locks, and transfers on the Oasis Sapphire network.
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install flexvaults
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ ```python
47
+ import asyncio
48
+ from flexvaults import FlexvaultsClient, DepositQuoteRequest
49
+
50
+ async def main():
51
+ async with FlexvaultsClient(base_url="https://api.example.com") as client:
52
+ # Get a deposit quote
53
+ quote = await client.get_deposit_quote(
54
+ DepositQuoteRequest(
55
+ user_address="0xYourAddress",
56
+ token_id="0xTokenId",
57
+ amount=1000000,
58
+ )
59
+ )
60
+ print(f"Deposit to: {quote.deposit_address}")
61
+
62
+ # Check balance
63
+ balance = await client.get_balance("0xYourAddress", "0xTokenId")
64
+ print(f"Balance: {balance.balance}")
65
+
66
+ asyncio.run(main())
67
+ ```
68
+
69
+ ## EIP-712 Signing
70
+
71
+ ```python
72
+ from eth_account import Account
73
+ from flexvaults import (
74
+ sign_lock_message,
75
+ SignLockParams,
76
+ LockMessage,
77
+ get_accounting_contract,
78
+ create_lock_expiry,
79
+ )
80
+
81
+ account = Account.from_key("0xYourPrivateKey")
82
+
83
+ signature = sign_lock_message(
84
+ SignLockParams(
85
+ account=account,
86
+ network="testnet",
87
+ verifying_contract=get_accounting_contract("testnet"),
88
+ message=LockMessage(
89
+ user_address=account.address,
90
+ service_address="0xServiceAddress",
91
+ token_id="0xTokenId",
92
+ amount=1000000,
93
+ expiry=create_lock_expiry(60),
94
+ ),
95
+ )
96
+ )
97
+ ```
98
+
99
+ ## API Reference
100
+
101
+ ### Client
102
+
103
+ - `FlexvaultsClient(base_url, timeout=30.0, headers=None)` - Main API client
104
+ - `get_deposit_quote(request)` - Get deposit quote
105
+ - `include_deposit(request)` - Include deposit proof
106
+ - `get_balance(user_address, token_id)` - Get token balance
107
+ - `get_batch_balances(request)` - Get multiple token balances
108
+ - `get_token_info(token_id)` - Get token information
109
+ - `lock_funds(request)` - Lock funds for a service
110
+ - `unlock_funds(request)` - Unlock specific lock
111
+ - `unlock_all_expired(request)` - Unlock all expired locks
112
+ - `get_locked_funds(user_address, service_address=None)` - Get locked funds
113
+ - `get_total_locked_balance(user_address, token_id)` - Get total locked balance
114
+ - `get_expired_locks(user_address)` - Get expired locks
115
+ - `transfer_funds(request)` - Transfer tokens
116
+ - `transfer_locked_funds(request)` - Transfer locked tokens
117
+ - `request_withdrawal(request)` - Request withdrawal
118
+ - `get_pending_withdrawals(user_address)` - Get pending withdrawals
119
+ - `get_withdrawal_info(index)` - Get withdrawal info
120
+
121
+ ### Signing
122
+
123
+ - `sign_lock_message(params)` - Sign lock message
124
+ - `sign_transfer_message(params)` - Sign transfer message
125
+ - `sign_transfer_locked_message(params)` - Sign transfer locked message
126
+ - `sign_withdraw_message(params)` - Sign withdrawal message
127
+ - `create_lock_expiry(minutes_from_now=60)` - Create expiry timestamp
128
+
129
+ ### Utilities
130
+
131
+ - `format_token_amount(amount, decimals=18)` - Format wei to human-readable
132
+ - `parse_token_amount(amount, decimals=18)` - Parse human-readable to wei
133
+ - `shorten_address(address, chars=4)` - Shorten Ethereum address
134
+ - `is_expired(expiry)` - Check if timestamp is expired
135
+ - `format_time_remaining(expiry_timestamp)` - Format time remaining
136
+ - `format_relative_time(timestamp)` - Format relative time (e.g., "5m ago")
137
+
138
+ ## License
139
+
140
+ Apache-2.0
@@ -0,0 +1,107 @@
1
+ # flexvaults
2
+
3
+ Python SDK for Flexvaults - manage deposits, withdrawals, locks, and transfers on the Oasis Sapphire network.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install flexvaults
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ import asyncio
15
+ from flexvaults import FlexvaultsClient, DepositQuoteRequest
16
+
17
+ async def main():
18
+ async with FlexvaultsClient(base_url="https://api.example.com") as client:
19
+ # Get a deposit quote
20
+ quote = await client.get_deposit_quote(
21
+ DepositQuoteRequest(
22
+ user_address="0xYourAddress",
23
+ token_id="0xTokenId",
24
+ amount=1000000,
25
+ )
26
+ )
27
+ print(f"Deposit to: {quote.deposit_address}")
28
+
29
+ # Check balance
30
+ balance = await client.get_balance("0xYourAddress", "0xTokenId")
31
+ print(f"Balance: {balance.balance}")
32
+
33
+ asyncio.run(main())
34
+ ```
35
+
36
+ ## EIP-712 Signing
37
+
38
+ ```python
39
+ from eth_account import Account
40
+ from flexvaults import (
41
+ sign_lock_message,
42
+ SignLockParams,
43
+ LockMessage,
44
+ get_accounting_contract,
45
+ create_lock_expiry,
46
+ )
47
+
48
+ account = Account.from_key("0xYourPrivateKey")
49
+
50
+ signature = sign_lock_message(
51
+ SignLockParams(
52
+ account=account,
53
+ network="testnet",
54
+ verifying_contract=get_accounting_contract("testnet"),
55
+ message=LockMessage(
56
+ user_address=account.address,
57
+ service_address="0xServiceAddress",
58
+ token_id="0xTokenId",
59
+ amount=1000000,
60
+ expiry=create_lock_expiry(60),
61
+ ),
62
+ )
63
+ )
64
+ ```
65
+
66
+ ## API Reference
67
+
68
+ ### Client
69
+
70
+ - `FlexvaultsClient(base_url, timeout=30.0, headers=None)` - Main API client
71
+ - `get_deposit_quote(request)` - Get deposit quote
72
+ - `include_deposit(request)` - Include deposit proof
73
+ - `get_balance(user_address, token_id)` - Get token balance
74
+ - `get_batch_balances(request)` - Get multiple token balances
75
+ - `get_token_info(token_id)` - Get token information
76
+ - `lock_funds(request)` - Lock funds for a service
77
+ - `unlock_funds(request)` - Unlock specific lock
78
+ - `unlock_all_expired(request)` - Unlock all expired locks
79
+ - `get_locked_funds(user_address, service_address=None)` - Get locked funds
80
+ - `get_total_locked_balance(user_address, token_id)` - Get total locked balance
81
+ - `get_expired_locks(user_address)` - Get expired locks
82
+ - `transfer_funds(request)` - Transfer tokens
83
+ - `transfer_locked_funds(request)` - Transfer locked tokens
84
+ - `request_withdrawal(request)` - Request withdrawal
85
+ - `get_pending_withdrawals(user_address)` - Get pending withdrawals
86
+ - `get_withdrawal_info(index)` - Get withdrawal info
87
+
88
+ ### Signing
89
+
90
+ - `sign_lock_message(params)` - Sign lock message
91
+ - `sign_transfer_message(params)` - Sign transfer message
92
+ - `sign_transfer_locked_message(params)` - Sign transfer locked message
93
+ - `sign_withdraw_message(params)` - Sign withdrawal message
94
+ - `create_lock_expiry(minutes_from_now=60)` - Create expiry timestamp
95
+
96
+ ### Utilities
97
+
98
+ - `format_token_amount(amount, decimals=18)` - Format wei to human-readable
99
+ - `parse_token_amount(amount, decimals=18)` - Parse human-readable to wei
100
+ - `shorten_address(address, chars=4)` - Shorten Ethereum address
101
+ - `is_expired(expiry)` - Check if timestamp is expired
102
+ - `format_time_remaining(expiry_timestamp)` - Format time remaining
103
+ - `format_relative_time(timestamp)` - Format relative time (e.g., "5m ago")
104
+
105
+ ## License
106
+
107
+ Apache-2.0
@@ -0,0 +1,67 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "flexvaults"
7
+ version = "0.1.5"
8
+ description = "Python SDK for Flexvaults - manage deposits, withdrawals, locks, and transfers"
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "Oasis Protocol Foundation", email = "security@oasisprotocol.org" },
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: Apache Software License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ "Typing :: Typed",
26
+ ]
27
+ dependencies = [
28
+ "httpx>=0.27.0",
29
+ "eth-account>=0.13.0",
30
+ "eth-typing>=5.0.0",
31
+ "pydantic>=2.0.0",
32
+ ]
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pytest>=8.0.0",
37
+ "pytest-asyncio>=0.24.0",
38
+ "pytest-httpx>=0.34.0",
39
+ "respx>=0.22.0",
40
+ "mypy>=1.11.0",
41
+ "ruff>=0.7.0",
42
+ ]
43
+
44
+ [project.urls]
45
+ Homepage = "https://github.com/oasisprotocol/flexvaults-sdk"
46
+ Repository = "https://github.com/oasisprotocol/flexvaults-sdk"
47
+ Issues = "https://github.com/oasisprotocol/flexvaults-sdk/issues"
48
+
49
+ [tool.hatch.build.targets.wheel]
50
+ packages = ["src/flexvaults"]
51
+
52
+ [tool.pytest.ini_options]
53
+ asyncio_mode = "auto"
54
+ testpaths = ["tests"]
55
+
56
+ [tool.mypy]
57
+ python_version = "3.10"
58
+ strict = true
59
+ warn_return_any = true
60
+ warn_unused_configs = true
61
+
62
+ [tool.ruff]
63
+ target-version = "py310"
64
+ line-length = 100
65
+
66
+ [tool.ruff.lint]
67
+ select = ["E", "F", "I", "N", "W", "UP"]
@@ -0,0 +1,168 @@
1
+ from .client import (
2
+ AccountingApiError,
3
+ FlexvaultsClient,
4
+ HttpClient,
5
+ NetworkError,
6
+ ValidationError,
7
+ )
8
+ from .signatures import (
9
+ LOCK_TYPES,
10
+ TRANSFER_LOCKED_TYPES,
11
+ TRANSFER_TYPES,
12
+ WITHDRAW_TYPES,
13
+ EIP712Domain,
14
+ LockMessage,
15
+ SignLockParams,
16
+ SignTransferLockedParams,
17
+ SignTransferParams,
18
+ SignWithdrawParams,
19
+ TransferLockedMessage,
20
+ TransferMessage,
21
+ WithdrawMessage,
22
+ create_domain,
23
+ create_lock_expiry,
24
+ sign_lock_message,
25
+ sign_transfer_locked_message,
26
+ sign_transfer_message,
27
+ sign_withdraw_message,
28
+ )
29
+ from .types import (
30
+ NETWORK_CONFIG,
31
+ SUPPORTED_CHAINS,
32
+ SUPPORTED_TOKENS,
33
+ Address,
34
+ BalanceResponse,
35
+ BatchBalancesRequest,
36
+ BatchBalancesResponse,
37
+ Bytes32,
38
+ ChainConfig,
39
+ DepositQuoteRequest,
40
+ DepositQuoteResponse,
41
+ ExpiredLocksResponse,
42
+ HexString,
43
+ IncludeDepositRequest,
44
+ IncludeDepositResponse,
45
+ LockedFundsResponse,
46
+ LockFundsRequest,
47
+ LockInfo,
48
+ Network,
49
+ NetworkConfig,
50
+ PendingWithdrawal,
51
+ PendingWithdrawalsResponse,
52
+ SupportedToken,
53
+ TokenBalance,
54
+ TokenConfig,
55
+ TokenInfoResponse,
56
+ TotalLockedBalanceResponse,
57
+ TransactionData,
58
+ TransactionSubmissionResponse,
59
+ TransferFundsRequest,
60
+ TransferLockedFundsRequest,
61
+ UnlockAllExpiredRequest,
62
+ UnlockFundsRequest,
63
+ WithdrawalInfoResponse,
64
+ WithdrawalRequest,
65
+ get_accounting_contract,
66
+ get_all_tokens,
67
+ get_api_url,
68
+ get_chain_by_id,
69
+ get_chain_id,
70
+ get_explorer_address_url,
71
+ get_token_by_id,
72
+ get_token_config,
73
+ is_valid_token,
74
+ normalize_address,
75
+ normalize_hex,
76
+ )
77
+ from .utils import (
78
+ format_relative_time,
79
+ format_time_remaining,
80
+ format_timestamp,
81
+ format_token_amount,
82
+ is_expired,
83
+ parse_token_amount,
84
+ shorten_address,
85
+ )
86
+
87
+ __version__ = "0.1.5"
88
+
89
+ __all__ = [
90
+ "__version__",
91
+ "Address",
92
+ "Bytes32",
93
+ "HexString",
94
+ "Network",
95
+ "NetworkConfig",
96
+ "NETWORK_CONFIG",
97
+ "get_chain_id",
98
+ "get_accounting_contract",
99
+ "get_api_url",
100
+ "normalize_hex",
101
+ "normalize_address",
102
+ "TokenConfig",
103
+ "SupportedToken",
104
+ "SUPPORTED_TOKENS",
105
+ "get_token_config",
106
+ "get_token_by_id",
107
+ "is_valid_token",
108
+ "ChainConfig",
109
+ "SUPPORTED_CHAINS",
110
+ "get_chain_by_id",
111
+ "get_explorer_address_url",
112
+ "get_all_tokens",
113
+ "DepositQuoteRequest",
114
+ "IncludeDepositRequest",
115
+ "LockFundsRequest",
116
+ "UnlockFundsRequest",
117
+ "UnlockAllExpiredRequest",
118
+ "TransferFundsRequest",
119
+ "TransferLockedFundsRequest",
120
+ "WithdrawalRequest",
121
+ "BatchBalancesRequest",
122
+ "TransactionData",
123
+ "DepositQuoteResponse",
124
+ "IncludeDepositResponse",
125
+ "TransactionSubmissionResponse",
126
+ "BalanceResponse",
127
+ "TokenBalance",
128
+ "BatchBalancesResponse",
129
+ "TokenInfoResponse",
130
+ "LockInfo",
131
+ "LockedFundsResponse",
132
+ "ExpiredLocksResponse",
133
+ "TotalLockedBalanceResponse",
134
+ "PendingWithdrawal",
135
+ "PendingWithdrawalsResponse",
136
+ "WithdrawalInfoResponse",
137
+ "FlexvaultsClient",
138
+ "HttpClient",
139
+ "AccountingApiError",
140
+ "NetworkError",
141
+ "ValidationError",
142
+ "EIP712Domain",
143
+ "create_domain",
144
+ "LOCK_TYPES",
145
+ "TRANSFER_TYPES",
146
+ "TRANSFER_LOCKED_TYPES",
147
+ "WITHDRAW_TYPES",
148
+ "LockMessage",
149
+ "TransferMessage",
150
+ "TransferLockedMessage",
151
+ "WithdrawMessage",
152
+ "SignLockParams",
153
+ "sign_lock_message",
154
+ "create_lock_expiry",
155
+ "SignTransferParams",
156
+ "sign_transfer_message",
157
+ "SignTransferLockedParams",
158
+ "sign_transfer_locked_message",
159
+ "SignWithdrawParams",
160
+ "sign_withdraw_message",
161
+ "format_token_amount",
162
+ "parse_token_amount",
163
+ "shorten_address",
164
+ "format_timestamp",
165
+ "is_expired",
166
+ "format_time_remaining",
167
+ "format_relative_time",
168
+ ]
@@ -0,0 +1,11 @@
1
+ from .errors import AccountingApiError, NetworkError, ValidationError
2
+ from .flexvaults_client import FlexvaultsClient
3
+ from .http_client import HttpClient
4
+
5
+ __all__ = [
6
+ "AccountingApiError",
7
+ "NetworkError",
8
+ "ValidationError",
9
+ "HttpClient",
10
+ "FlexvaultsClient",
11
+ ]
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ class AccountingApiError(Exception):
5
+ def __init__(
6
+ self,
7
+ message: str,
8
+ status_code: int,
9
+ detail: str | None = None,
10
+ ) -> None:
11
+ super().__init__(message)
12
+ self.status_code = status_code
13
+ self.detail = detail
14
+
15
+
16
+ class NetworkError(Exception):
17
+ def __init__(
18
+ self,
19
+ message: str,
20
+ cause: Exception | None = None,
21
+ ) -> None:
22
+ super().__init__(message)
23
+ self.__cause__ = cause
24
+
25
+
26
+ class ValidationError(Exception):
27
+ def __init__(
28
+ self,
29
+ message: str,
30
+ field: str | None = None,
31
+ ) -> None:
32
+ super().__init__(message)
33
+ self.field = field