polynode 0.6.0__tar.gz → 0.6.2__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.
- {polynode-0.6.0 → polynode-0.6.2}/PKG-INFO +1 -1
- {polynode-0.6.0 → polynode-0.6.2}/polynode/short_form.py +1 -1
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/__init__.py +5 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/clob_api.py +8 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/cosigner.py +7 -0
- polynode-0.6.2/polynode/trading/position_management.py +104 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/trader.py +29 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/types.py +51 -0
- {polynode-0.6.0 → polynode-0.6.2}/pyproject.toml +1 -1
- {polynode-0.6.0 → polynode-0.6.2}/.gitignore +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/README.md +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/__init__.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/_version.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/cache/__init__.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/client.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/engine.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/errors.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/orderbook.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/orderbook_state.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/redemption_watcher.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/subscription.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/testing.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/constants.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/eip712.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/onboarding.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/privy.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/signer.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/trading/sqlite_backend.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/__init__.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/enums.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/events.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/orderbook.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/rest.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/short_form.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/types/ws.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/polynode/ws.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/tests/__init__.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/tests/conftest.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/tests/test_client.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/tests/test_orderbook.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/tests/test_trading.py +0 -0
- {polynode-0.6.0 → polynode-0.6.2}/tests/test_types.py +0 -0
|
@@ -37,7 +37,7 @@ COIN_SYMBOLS: dict[ShortFormCoin, str] = {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
INTERVAL_VARIANT: dict[ShortFormInterval, str] = {
|
|
40
|
-
"5m": "
|
|
40
|
+
"5m": "fiveminute", "15m": "fifteen", "1h": "hourly",
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
WINDOW_SECONDS: dict[ShortFormInterval, int] = {
|
|
@@ -5,11 +5,13 @@ from .constants import * # noqa: F401, F403
|
|
|
5
5
|
from .signer import NormalizedSigner, normalize_signer
|
|
6
6
|
from .cosigner import build_l2_headers, send_via_cosigner
|
|
7
7
|
from .onboarding import derive_safe_address, derive_proxy_address, detect_wallet_type
|
|
8
|
+
from .position_management import build_split_txn, build_merge_txn, build_convert_txn
|
|
8
9
|
from .trader import PolyNodeTrader
|
|
9
10
|
from .privy import PrivySigner, PrivyConfig
|
|
10
11
|
|
|
11
12
|
__all__ = [
|
|
12
13
|
"PolyNodeTrader",
|
|
14
|
+
"BuilderCredentials",
|
|
13
15
|
"PrivySigner",
|
|
14
16
|
"PrivyConfig",
|
|
15
17
|
"NormalizedSigner",
|
|
@@ -19,4 +21,7 @@ __all__ = [
|
|
|
19
21
|
"derive_safe_address",
|
|
20
22
|
"derive_proxy_address",
|
|
21
23
|
"detect_wallet_type",
|
|
24
|
+
"build_split_txn",
|
|
25
|
+
"build_merge_txn",
|
|
26
|
+
"build_convert_txn",
|
|
22
27
|
]
|
|
@@ -17,6 +17,7 @@ async def post_order(
|
|
|
17
17
|
credentials: dict[str, str],
|
|
18
18
|
wallet_address: str,
|
|
19
19
|
order_body: str,
|
|
20
|
+
builder_credentials: Any | None = None,
|
|
20
21
|
) -> dict[str, Any]:
|
|
21
22
|
"""Submit a signed order to the CLOB."""
|
|
22
23
|
from .cosigner import send_via_cosigner
|
|
@@ -36,6 +37,7 @@ async def post_order(
|
|
|
36
37
|
polynode_key,
|
|
37
38
|
fallback_direct,
|
|
38
39
|
{"method": "POST", "path": "/order", "body": order_body, "headers": headers},
|
|
40
|
+
builder_credentials=builder_credentials,
|
|
39
41
|
)
|
|
40
42
|
|
|
41
43
|
|
|
@@ -46,6 +48,7 @@ async def cancel_order(
|
|
|
46
48
|
credentials: dict[str, str],
|
|
47
49
|
wallet_address: str,
|
|
48
50
|
order_id: str,
|
|
51
|
+
builder_credentials: Any | None = None,
|
|
49
52
|
) -> dict[str, Any]:
|
|
50
53
|
"""Cancel a specific order."""
|
|
51
54
|
from .cosigner import send_via_cosigner
|
|
@@ -67,6 +70,7 @@ async def cancel_order(
|
|
|
67
70
|
polynode_key,
|
|
68
71
|
fallback_direct,
|
|
69
72
|
{"method": "DELETE", "path": "/order", "body": body, "headers": headers},
|
|
73
|
+
builder_credentials=builder_credentials,
|
|
70
74
|
)
|
|
71
75
|
|
|
72
76
|
|
|
@@ -77,6 +81,7 @@ async def cancel_all_orders(
|
|
|
77
81
|
credentials: dict[str, str],
|
|
78
82
|
wallet_address: str,
|
|
79
83
|
market: str | None = None,
|
|
84
|
+
builder_credentials: Any | None = None,
|
|
80
85
|
) -> dict[str, Any]:
|
|
81
86
|
"""Cancel all orders, optionally for a specific market."""
|
|
82
87
|
from .cosigner import send_via_cosigner
|
|
@@ -99,6 +104,7 @@ async def cancel_all_orders(
|
|
|
99
104
|
polynode_key,
|
|
100
105
|
fallback_direct,
|
|
101
106
|
{"method": "DELETE", "path": path, "body": body, "headers": headers},
|
|
107
|
+
builder_credentials=builder_credentials,
|
|
102
108
|
)
|
|
103
109
|
|
|
104
110
|
|
|
@@ -110,6 +116,7 @@ async def get_open_orders(
|
|
|
110
116
|
wallet_address: str,
|
|
111
117
|
market: str | None = None,
|
|
112
118
|
asset_id: str | None = None,
|
|
119
|
+
builder_credentials: Any | None = None,
|
|
113
120
|
) -> list[dict[str, Any]]:
|
|
114
121
|
"""Get open orders from the CLOB."""
|
|
115
122
|
from .cosigner import send_via_cosigner
|
|
@@ -137,6 +144,7 @@ async def get_open_orders(
|
|
|
137
144
|
polynode_key,
|
|
138
145
|
fallback_direct,
|
|
139
146
|
{"method": "GET", "path": path, "headers": headers},
|
|
147
|
+
builder_credentials=builder_credentials,
|
|
140
148
|
)
|
|
141
149
|
|
|
142
150
|
if isinstance(result, list):
|
|
@@ -48,10 +48,17 @@ async def send_via_cosigner(
|
|
|
48
48
|
polynode_key: str,
|
|
49
49
|
fallback_direct: bool,
|
|
50
50
|
request: dict[str, Any],
|
|
51
|
+
builder_credentials: Any | None = None,
|
|
51
52
|
) -> Any:
|
|
52
53
|
"""Send a request through the co-signer with optional fallback to direct CLOB."""
|
|
53
54
|
if cosigner_url:
|
|
54
55
|
try:
|
|
56
|
+
if builder_credentials is not None:
|
|
57
|
+
request["builder_credentials"] = {
|
|
58
|
+
"key": builder_credentials.key,
|
|
59
|
+
"secret": builder_credentials.secret,
|
|
60
|
+
"passphrase": builder_credentials.passphrase,
|
|
61
|
+
}
|
|
55
62
|
async with httpx.AsyncClient(timeout=10.0) as http:
|
|
56
63
|
resp = await http.post(
|
|
57
64
|
f"{cosigner_url}/submit",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Position management — build transactions for split, merge, and convert on Polymarket.
|
|
3
|
+
|
|
4
|
+
These functions return TransactionRequest objects containing the contract address
|
|
5
|
+
and ABI-encoded calldata. Submit them via the Polymarket relayer (gasless for
|
|
6
|
+
Safe wallets) or directly on-chain.
|
|
7
|
+
|
|
8
|
+
from polynode.trading.position_management import build_split_txn, build_convert_txn
|
|
9
|
+
|
|
10
|
+
# Split $100 into YES + NO tokens
|
|
11
|
+
tx = build_split_txn("0xabc...conditionId", 100.0, neg_risk=True)
|
|
12
|
+
|
|
13
|
+
# Convert NO positions on outcomes 0 and 1
|
|
14
|
+
tx = build_convert_txn("0xdef...marketId", [0, 1], 50.0)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .constants import CTF, NEG_RISK_ADAPTER, USDC
|
|
18
|
+
from .types import TransactionRequest
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def build_split_txn(condition_id: str, amount: float, neg_risk: bool = True) -> TransactionRequest:
|
|
22
|
+
"""Build a split transaction: USDC -> YES + NO outcome tokens.
|
|
23
|
+
|
|
24
|
+
Routes to NegRiskAdapter for neg-risk markets, CTF for standard markets.
|
|
25
|
+
Amount is in USDC (e.g. 100.0 = $100).
|
|
26
|
+
"""
|
|
27
|
+
amount_raw = int(amount * 1_000_000)
|
|
28
|
+
|
|
29
|
+
if neg_risk:
|
|
30
|
+
# NegRiskAdapter.splitPosition(bytes32 conditionId, uint256 amount)
|
|
31
|
+
data = "0xa3d7da1d" + _encode_bytes32(condition_id) + _encode_uint256(amount_raw)
|
|
32
|
+
return TransactionRequest(to=NEG_RISK_ADAPTER, data=data)
|
|
33
|
+
else:
|
|
34
|
+
# CTF.splitPosition(address, bytes32, bytes32, uint256[], uint256)
|
|
35
|
+
data = (
|
|
36
|
+
"0x72108503"
|
|
37
|
+
+ _encode_address(USDC)
|
|
38
|
+
+ "00" * 32 # parentCollectionId = bytes32(0)
|
|
39
|
+
+ _encode_bytes32(condition_id)
|
|
40
|
+
+ _encode_uint256(160) # offset to partition array
|
|
41
|
+
+ _encode_uint256(amount_raw)
|
|
42
|
+
+ _encode_uint256(2) # partition length
|
|
43
|
+
+ _encode_uint256(1)
|
|
44
|
+
+ _encode_uint256(2)
|
|
45
|
+
)
|
|
46
|
+
return TransactionRequest(to=CTF, data=data)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def build_merge_txn(condition_id: str, amount: float, neg_risk: bool = True) -> TransactionRequest:
|
|
50
|
+
"""Build a merge transaction: YES + NO outcome tokens -> USDC."""
|
|
51
|
+
amount_raw = int(amount * 1_000_000)
|
|
52
|
+
|
|
53
|
+
if neg_risk:
|
|
54
|
+
# NegRiskAdapter.mergePositions(bytes32 conditionId, uint256 amount)
|
|
55
|
+
data = "0x5d03f453" + _encode_bytes32(condition_id) + _encode_uint256(amount_raw)
|
|
56
|
+
return TransactionRequest(to=NEG_RISK_ADAPTER, data=data)
|
|
57
|
+
else:
|
|
58
|
+
# CTF.mergePositions(address, bytes32, bytes32, uint256[], uint256)
|
|
59
|
+
data = (
|
|
60
|
+
"0xcad9440e"
|
|
61
|
+
+ _encode_address(USDC)
|
|
62
|
+
+ "00" * 32
|
|
63
|
+
+ _encode_bytes32(condition_id)
|
|
64
|
+
+ _encode_uint256(160)
|
|
65
|
+
+ _encode_uint256(amount_raw)
|
|
66
|
+
+ _encode_uint256(2)
|
|
67
|
+
+ _encode_uint256(1)
|
|
68
|
+
+ _encode_uint256(2)
|
|
69
|
+
)
|
|
70
|
+
return TransactionRequest(to=CTF, data=data)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def build_convert_txn(market_id: str, outcome_indices: list[int], amount: float) -> TransactionRequest:
|
|
74
|
+
"""Build a convert transaction: NO positions -> USDC + YES on complementary outcomes.
|
|
75
|
+
|
|
76
|
+
Only works on neg-risk multi-outcome markets.
|
|
77
|
+
outcome_indices: which outcomes' NOs to convert (e.g. [0, 1]).
|
|
78
|
+
"""
|
|
79
|
+
amount_raw = int(amount * 1_000_000)
|
|
80
|
+
|
|
81
|
+
# Compute indexSet bitmask
|
|
82
|
+
index_set = 0
|
|
83
|
+
for idx in outcome_indices:
|
|
84
|
+
index_set |= 1 << idx
|
|
85
|
+
|
|
86
|
+
# NegRiskAdapter.convertPositions(bytes32 marketId, uint256 indexSet, uint256 amount)
|
|
87
|
+
data = "0xc64748c4" + _encode_bytes32(market_id) + _encode_uint256(index_set) + _encode_uint256(amount_raw)
|
|
88
|
+
return TransactionRequest(to=NEG_RISK_ADAPTER, data=data)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# ── Encoding helpers ──
|
|
92
|
+
|
|
93
|
+
def _encode_bytes32(hex_str: str) -> str:
|
|
94
|
+
s = hex_str.removeprefix("0x")
|
|
95
|
+
return s.zfill(64)[:64]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _encode_address(addr: str) -> str:
|
|
99
|
+
s = addr.removeprefix("0x")
|
|
100
|
+
return s.lower().zfill(64)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _encode_uint256(val: int) -> str:
|
|
104
|
+
return hex(val)[2:].zfill(64)
|
|
@@ -60,6 +60,7 @@ class PolyNodeTrader:
|
|
|
60
60
|
self._fallback_direct = c.fallback_direct
|
|
61
61
|
self._default_sig_type = c.default_signature_type
|
|
62
62
|
self._rpc_url = c.rpc_url
|
|
63
|
+
self._builder_credentials = c.builder_credentials
|
|
63
64
|
|
|
64
65
|
self._db: TradingSqliteBackend | None = None
|
|
65
66
|
self._active_signer: NormalizedSigner | None = None
|
|
@@ -382,6 +383,7 @@ class PolyNodeTrader:
|
|
|
382
383
|
result = await send_via_cosigner(
|
|
383
384
|
self._cosigner_url, self._polynode_key, self._fallback_direct,
|
|
384
385
|
{"method": "POST", "path": "/order", "body": body_str, "headers": headers},
|
|
386
|
+
builder_credentials=self._builder_credentials,
|
|
385
387
|
)
|
|
386
388
|
|
|
387
389
|
order_id = result.get("orderID") or result.get("orderId")
|
|
@@ -409,6 +411,7 @@ class PolyNodeTrader:
|
|
|
409
411
|
self._cosigner_url, self._polynode_key, self._fallback_direct,
|
|
410
412
|
{"apiKey": creds.api_key, "apiSecret": creds.api_secret, "apiPassphrase": creds.api_passphrase},
|
|
411
413
|
creds.wallet_address, order_id,
|
|
414
|
+
builder_credentials=self._builder_credentials,
|
|
412
415
|
)
|
|
413
416
|
return CancelResult(
|
|
414
417
|
canceled=result.get("canceled", []),
|
|
@@ -421,6 +424,7 @@ class PolyNodeTrader:
|
|
|
421
424
|
self._cosigner_url, self._polynode_key, self._fallback_direct,
|
|
422
425
|
{"apiKey": creds.api_key, "apiSecret": creds.api_secret, "apiPassphrase": creds.api_passphrase},
|
|
423
426
|
creds.wallet_address, market,
|
|
427
|
+
builder_credentials=self._builder_credentials,
|
|
424
428
|
)
|
|
425
429
|
return CancelResult(
|
|
426
430
|
canceled=result.get("canceled", []),
|
|
@@ -435,6 +439,7 @@ class PolyNodeTrader:
|
|
|
435
439
|
self._cosigner_url, self._polynode_key, self._fallback_direct,
|
|
436
440
|
{"apiKey": creds.api_key, "apiSecret": creds.api_secret, "apiPassphrase": creds.api_passphrase},
|
|
437
441
|
creds.wallet_address, market, asset_id,
|
|
442
|
+
builder_credentials=self._builder_credentials,
|
|
438
443
|
)
|
|
439
444
|
return [
|
|
440
445
|
OpenOrder(
|
|
@@ -473,6 +478,30 @@ class PolyNodeTrader:
|
|
|
473
478
|
db.upsert_market_meta(meta)
|
|
474
479
|
return meta
|
|
475
480
|
|
|
481
|
+
# ── Position Management (split/merge/convert) ──
|
|
482
|
+
|
|
483
|
+
def split(self, params: "SplitParams") -> "TransactionRequest":
|
|
484
|
+
"""Build a split transaction: USDC -> YES + NO outcome tokens.
|
|
485
|
+
|
|
486
|
+
Returns a TransactionRequest to submit via the Polymarket relayer or on-chain.
|
|
487
|
+
For gasless execution, use the TypeScript SDK's trader.split().
|
|
488
|
+
"""
|
|
489
|
+
from .position_management import build_split_txn
|
|
490
|
+
return build_split_txn(params.condition_id, params.amount, neg_risk=True)
|
|
491
|
+
|
|
492
|
+
def merge(self, params: "MergeParams") -> "TransactionRequest":
|
|
493
|
+
"""Build a merge transaction: YES + NO outcome tokens -> USDC."""
|
|
494
|
+
from .position_management import build_merge_txn
|
|
495
|
+
return build_merge_txn(params.condition_id, params.amount, neg_risk=True)
|
|
496
|
+
|
|
497
|
+
def convert(self, params: "ConvertParams") -> "TransactionRequest":
|
|
498
|
+
"""Build a convert transaction: NO positions -> USDC + YES on complementary outcomes.
|
|
499
|
+
|
|
500
|
+
Only works on neg-risk multi-outcome markets.
|
|
501
|
+
"""
|
|
502
|
+
from .position_management import build_convert_txn
|
|
503
|
+
return build_convert_txn(params.market_id, params.outcome_indices, params.amount)
|
|
504
|
+
|
|
476
505
|
# ── History ──
|
|
477
506
|
|
|
478
507
|
def get_order_history(self, params: HistoryParams | None = None) -> list[OrderHistoryRow]:
|
|
@@ -33,6 +33,14 @@ class GeneratedWallet:
|
|
|
33
33
|
address: str
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
@dataclass
|
|
37
|
+
class BuilderCredentials:
|
|
38
|
+
"""Polymarket builder credentials for order attribution."""
|
|
39
|
+
key: str
|
|
40
|
+
secret: str
|
|
41
|
+
passphrase: str
|
|
42
|
+
|
|
43
|
+
|
|
36
44
|
@dataclass
|
|
37
45
|
class TraderConfig:
|
|
38
46
|
polynode_key: str = ""
|
|
@@ -41,6 +49,7 @@ class TraderConfig:
|
|
|
41
49
|
fallback_direct: bool = True
|
|
42
50
|
default_signature_type: SignatureType = SignatureType.POLY_GNOSIS_SAFE
|
|
43
51
|
rpc_url: str = "https://polygon-bor-rpc.publicnode.com"
|
|
52
|
+
builder_credentials: BuilderCredentials | None = None
|
|
44
53
|
|
|
45
54
|
|
|
46
55
|
@dataclass
|
|
@@ -144,6 +153,48 @@ class OpenOrder:
|
|
|
144
153
|
order_type: str
|
|
145
154
|
|
|
146
155
|
|
|
156
|
+
# ── Position Management (split/merge/convert) ──
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass
|
|
160
|
+
class SplitParams:
|
|
161
|
+
"""Parameters for splitting USDC into YES + NO outcome tokens."""
|
|
162
|
+
condition_id: str
|
|
163
|
+
amount: float # USDC amount (e.g. 100.0 = $100)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@dataclass
|
|
167
|
+
class MergeParams:
|
|
168
|
+
"""Parameters for merging YES + NO outcome tokens back into USDC."""
|
|
169
|
+
condition_id: str
|
|
170
|
+
amount: float
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@dataclass
|
|
174
|
+
class ConvertParams:
|
|
175
|
+
"""Parameters for converting NO positions on selected outcomes.
|
|
176
|
+
Only works on neg-risk multi-outcome markets."""
|
|
177
|
+
market_id: str
|
|
178
|
+
outcome_indices: list[int] # e.g. [0, 1]
|
|
179
|
+
amount: float
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@dataclass
|
|
183
|
+
class TransactionRequest:
|
|
184
|
+
"""A pre-built transaction ready for submission."""
|
|
185
|
+
to: str
|
|
186
|
+
data: str # hex-encoded calldata
|
|
187
|
+
value: str = "0"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@dataclass
|
|
191
|
+
class PositionResult:
|
|
192
|
+
"""Result of a position management operation."""
|
|
193
|
+
success: bool
|
|
194
|
+
tx_hash: str | None = None
|
|
195
|
+
error: str | None = None
|
|
196
|
+
|
|
197
|
+
|
|
147
198
|
@dataclass
|
|
148
199
|
class MarketMeta:
|
|
149
200
|
token_id: str
|
|
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
|
|
File without changes
|
|
File without changes
|