polynode 0.7.0__py3-none-any.whl → 0.7.2__py3-none-any.whl
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/_version.py +1 -1
- polynode/trading/__init__.py +1 -0
- polynode/trading/constants.py +3 -0
- polynode/trading/escrow.py +166 -0
- polynode/trading/onboarding.py +17 -0
- polynode/trading/sqlite_backend.py +32 -5
- polynode/trading/trader.py +44 -1
- polynode/trading/types.py +15 -0
- {polynode-0.7.0.dist-info → polynode-0.7.2.dist-info}/METADATA +1 -1
- {polynode-0.7.0.dist-info → polynode-0.7.2.dist-info}/RECORD +11 -10
- {polynode-0.7.0.dist-info → polynode-0.7.2.dist-info}/WHEEL +0 -0
polynode/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.7.2"
|
polynode/trading/__init__.py
CHANGED
polynode/trading/constants.py
CHANGED
|
@@ -39,5 +39,8 @@ POLY_USD = "0xc011a7e12a19f7b1f670d46f03b03f3342e82dfb"
|
|
|
39
39
|
COLLATERAL_ONRAMP = "0x93070a847efef7f70739046a929d47a521f5b8ee"
|
|
40
40
|
COLLATERAL_OFFRAMP = "0x2957922eb93258b93368531d39facca3b4dc5854"
|
|
41
41
|
|
|
42
|
+
# Fee Escrow
|
|
43
|
+
FEE_ESCROW_ADDRESS = "0xa11D28433B79D0A88F3119b16A090075752258EA"
|
|
44
|
+
|
|
42
45
|
# Metadata cache TTL (5 minutes)
|
|
43
46
|
META_TTL_SECONDS = 300
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""Fee Escrow — EIP-712 signing, fee calculation, and nonce fetching
|
|
2
|
+
for the on-chain FeeEscrow contract.
|
|
3
|
+
|
|
4
|
+
The escrow is completely optional. When fee_bps=0, none of this code runs.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import math
|
|
10
|
+
import os
|
|
11
|
+
import secrets
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
import httpx
|
|
16
|
+
|
|
17
|
+
from .constants import CHAIN_ID, FEE_ESCROW_ADDRESS
|
|
18
|
+
from .types import Eip712Payload
|
|
19
|
+
|
|
20
|
+
# ── EIP-712 Types ──
|
|
21
|
+
|
|
22
|
+
FEE_AUTH_DOMAIN = {
|
|
23
|
+
"name": "PolyNodeFeeEscrow",
|
|
24
|
+
"version": "1",
|
|
25
|
+
"chainId": CHAIN_ID,
|
|
26
|
+
"verifyingContract": FEE_ESCROW_ADDRESS,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
FEE_AUTH_TYPES = {
|
|
30
|
+
"FeeAuth": [
|
|
31
|
+
{"name": "orderId", "type": "bytes32"},
|
|
32
|
+
{"name": "payer", "type": "address"},
|
|
33
|
+
{"name": "signer", "type": "address"},
|
|
34
|
+
{"name": "feeAmount", "type": "uint256"},
|
|
35
|
+
{"name": "deadline", "type": "uint256"},
|
|
36
|
+
{"name": "nonce", "type": "uint256"},
|
|
37
|
+
],
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ── Fee Calculation ──
|
|
44
|
+
|
|
45
|
+
def calculate_fee(price: float, size: float, fee_bps: int) -> int:
|
|
46
|
+
"""Calculate fee amount in raw USDC (6 decimals).
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
price: Order price (e.g. 0.55)
|
|
50
|
+
size: Order size in tokens (e.g. 100)
|
|
51
|
+
fee_bps: Fee in basis points (e.g. 50 = 0.5%)
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Fee amount as int in raw USDC units
|
|
55
|
+
"""
|
|
56
|
+
notional_raw = math.floor(price * size * 1e6)
|
|
57
|
+
fee = math.floor(notional_raw * fee_bps / 10000)
|
|
58
|
+
return max(fee, 0)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# ── Order ID Generation ──
|
|
62
|
+
|
|
63
|
+
def generate_escrow_order_id() -> str:
|
|
64
|
+
"""Generate a random bytes32 escrow order ID (0x-prefixed hex)."""
|
|
65
|
+
return "0x" + secrets.token_hex(32)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# ── Nonce Fetching ──
|
|
69
|
+
|
|
70
|
+
async def fetch_escrow_nonce(rpc_url: str, signer_address: str) -> int:
|
|
71
|
+
"""Fetch the current nonce for a signer from the FeeEscrow contract via eth_call."""
|
|
72
|
+
# getNonce(address) selector = 0x2d0335ab
|
|
73
|
+
addr = signer_address.lower().replace("0x", "").zfill(64)
|
|
74
|
+
data = "0x2d0335ab" + addr
|
|
75
|
+
|
|
76
|
+
async with httpx.AsyncClient() as client:
|
|
77
|
+
resp = await client.post(
|
|
78
|
+
rpc_url,
|
|
79
|
+
json={
|
|
80
|
+
"jsonrpc": "2.0",
|
|
81
|
+
"id": 1,
|
|
82
|
+
"method": "eth_call",
|
|
83
|
+
"params": [{"to": FEE_ESCROW_ADDRESS, "data": data}, "latest"],
|
|
84
|
+
},
|
|
85
|
+
)
|
|
86
|
+
result = resp.json()
|
|
87
|
+
|
|
88
|
+
if "error" in result:
|
|
89
|
+
raise RuntimeError(f"Failed to fetch escrow nonce: {result['error']}")
|
|
90
|
+
return int(result.get("result", "0x0"), 16)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ── EIP-712 Signing ──
|
|
94
|
+
|
|
95
|
+
@dataclass
|
|
96
|
+
class FeeAuthRequest:
|
|
97
|
+
escrow_order_id: str
|
|
98
|
+
payer: str
|
|
99
|
+
signer: str
|
|
100
|
+
fee_amount: str
|
|
101
|
+
deadline: int
|
|
102
|
+
nonce: int
|
|
103
|
+
signature: str
|
|
104
|
+
affiliate: str
|
|
105
|
+
affiliate_share_bps: int
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
async def sign_fee_auth(
|
|
109
|
+
sign_typed_data: Any,
|
|
110
|
+
*,
|
|
111
|
+
escrow_order_id: str,
|
|
112
|
+
payer: str,
|
|
113
|
+
signer_address: str,
|
|
114
|
+
fee_amount: int,
|
|
115
|
+
deadline: int,
|
|
116
|
+
nonce: int,
|
|
117
|
+
affiliate: str | None = None,
|
|
118
|
+
affiliate_share_bps: int | None = None,
|
|
119
|
+
) -> FeeAuthRequest:
|
|
120
|
+
"""Sign a FeeAuth EIP-712 message.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
sign_typed_data: Callable that signs an Eip712Payload and returns a hex signature.
|
|
124
|
+
escrow_order_id: Random bytes32 hex string.
|
|
125
|
+
payer: Safe wallet address (where USDC is pulled from).
|
|
126
|
+
signer_address: EOA address (signs the message).
|
|
127
|
+
fee_amount: Fee in raw USDC (6 decimals).
|
|
128
|
+
deadline: Unix timestamp — authorization expires after this.
|
|
129
|
+
nonce: Signer's current nonce from the escrow contract.
|
|
130
|
+
affiliate: Partner wallet address.
|
|
131
|
+
affiliate_share_bps: Partner's share of fee in bps.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
FeeAuthRequest ready for the cosigner.
|
|
135
|
+
"""
|
|
136
|
+
message = {
|
|
137
|
+
"orderId": escrow_order_id,
|
|
138
|
+
"payer": payer,
|
|
139
|
+
"signer": signer_address,
|
|
140
|
+
"feeAmount": str(fee_amount),
|
|
141
|
+
"deadline": str(deadline),
|
|
142
|
+
"nonce": str(nonce),
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
payload = Eip712Payload(
|
|
146
|
+
domain=FEE_AUTH_DOMAIN,
|
|
147
|
+
types=FEE_AUTH_TYPES,
|
|
148
|
+
primary_type="FeeAuth",
|
|
149
|
+
message=message,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
signature = await sign_typed_data(payload)
|
|
153
|
+
if not signature.startswith("0x"):
|
|
154
|
+
signature = f"0x{signature}"
|
|
155
|
+
|
|
156
|
+
return FeeAuthRequest(
|
|
157
|
+
escrow_order_id=escrow_order_id,
|
|
158
|
+
payer=payer,
|
|
159
|
+
signer=signer_address,
|
|
160
|
+
fee_amount=str(fee_amount),
|
|
161
|
+
deadline=deadline,
|
|
162
|
+
nonce=nonce,
|
|
163
|
+
signature=signature,
|
|
164
|
+
affiliate=affiliate or ZERO_ADDRESS,
|
|
165
|
+
affiliate_share_bps=affiliate_share_bps or 0,
|
|
166
|
+
)
|
polynode/trading/onboarding.py
CHANGED
|
@@ -28,6 +28,7 @@ from .constants import (
|
|
|
28
28
|
SPENDERS,
|
|
29
29
|
USDC,
|
|
30
30
|
V2_SPENDERS,
|
|
31
|
+
FEE_ESCROW_ADDRESS,
|
|
31
32
|
)
|
|
32
33
|
from .types import ApprovalStatus, BalanceInfo, ExchangeVersion, SignatureType
|
|
33
34
|
|
|
@@ -185,6 +186,11 @@ async def check_approvals(
|
|
|
185
186
|
approved = ctf_contract.functions.isApprovedForAll(funder, spender_addr).call()
|
|
186
187
|
ctf_status[name] = approved
|
|
187
188
|
|
|
189
|
+
# Fee Escrow USDC approval (always USDC.e regardless of exchange version)
|
|
190
|
+
usdc_contract = w3.eth.contract(address=Web3.to_checksum_address(USDC), abi=erc20_abi)
|
|
191
|
+
escrow_allowance = usdc_contract.functions.allowance(funder, Web3.to_checksum_address(FEE_ESCROW_ADDRESS)).call()
|
|
192
|
+
usdc_status["fee_escrow"] = escrow_allowance >= threshold
|
|
193
|
+
|
|
188
194
|
all_approved = all(usdc_status.values()) and all(ctf_status.values())
|
|
189
195
|
|
|
190
196
|
return ApprovalStatus(
|
|
@@ -264,6 +270,17 @@ async def set_approvals(
|
|
|
264
270
|
tx_hashes.append(tx_hash.hex())
|
|
265
271
|
nonce += 1
|
|
266
272
|
|
|
273
|
+
# Fee Escrow USDC approval (always USDC.e regardless of exchange version)
|
|
274
|
+
escrow_contract = w3.eth.contract(address=Web3.to_checksum_address(USDC), abi=erc20_abi)
|
|
275
|
+
tx = escrow_contract.functions.approve(Web3.to_checksum_address(FEE_ESCROW_ADDRESS), max_uint).build_transaction({
|
|
276
|
+
"from": account.address,
|
|
277
|
+
"nonce": nonce,
|
|
278
|
+
"chainId": CHAIN_ID,
|
|
279
|
+
})
|
|
280
|
+
signed = account.sign_transaction(tx)
|
|
281
|
+
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
|
|
282
|
+
tx_hashes.append(tx_hash.hex())
|
|
283
|
+
|
|
267
284
|
return tx_hashes
|
|
268
285
|
|
|
269
286
|
|
|
@@ -13,11 +13,14 @@ from .types import HistoryParams, MarketMeta, OrderHistoryRow, SignatureType, St
|
|
|
13
13
|
class TradingSqliteBackend:
|
|
14
14
|
"""Local SQLite storage for trading module."""
|
|
15
15
|
|
|
16
|
+
SCHEMA_VERSION = 2
|
|
17
|
+
|
|
16
18
|
def __init__(self, db_path: str) -> None:
|
|
17
19
|
self._db = sqlite3.connect(db_path)
|
|
18
20
|
self._db.execute("PRAGMA journal_mode=WAL")
|
|
19
21
|
self._db.execute("PRAGMA synchronous=NORMAL")
|
|
20
22
|
self._init_schema()
|
|
23
|
+
self._migrate()
|
|
21
24
|
|
|
22
25
|
def _init_schema(self) -> None:
|
|
23
26
|
self._db.executescript("""
|
|
@@ -54,13 +57,27 @@ class TradingSqliteBackend:
|
|
|
54
57
|
status TEXT NOT NULL DEFAULT 'submitting',
|
|
55
58
|
error_msg TEXT,
|
|
56
59
|
response_json TEXT,
|
|
57
|
-
created_at REAL NOT NULL
|
|
60
|
+
created_at REAL NOT NULL,
|
|
61
|
+
fee_amount_raw TEXT,
|
|
62
|
+
escrow_order_id TEXT,
|
|
63
|
+
fee_escrow_tx_hash TEXT
|
|
58
64
|
);
|
|
59
65
|
|
|
60
66
|
CREATE INDEX IF NOT EXISTS idx_order_history_wallet ON order_history(wallet_address);
|
|
61
67
|
CREATE INDEX IF NOT EXISTS idx_order_history_token ON order_history(token_id);
|
|
62
68
|
""")
|
|
63
69
|
|
|
70
|
+
def _migrate(self) -> None:
|
|
71
|
+
"""Run schema migrations for existing databases."""
|
|
72
|
+
# Check if fee escrow columns exist (v2 migration)
|
|
73
|
+
cols = {row[1] for row in self._db.execute("PRAGMA table_info(order_history)").fetchall()}
|
|
74
|
+
if "fee_amount_raw" not in cols:
|
|
75
|
+
self._db.executescript("""
|
|
76
|
+
ALTER TABLE order_history ADD COLUMN fee_amount_raw TEXT;
|
|
77
|
+
ALTER TABLE order_history ADD COLUMN escrow_order_id TEXT;
|
|
78
|
+
ALTER TABLE order_history ADD COLUMN fee_escrow_tx_hash TEXT;
|
|
79
|
+
""")
|
|
80
|
+
|
|
64
81
|
def get_credentials(self, wallet_address: str) -> StoredCredentials | None:
|
|
65
82
|
row = self._db.execute(
|
|
66
83
|
"SELECT * FROM clob_credentials WHERE wallet_address = ? COLLATE NOCASE",
|
|
@@ -148,13 +165,16 @@ class TradingSqliteBackend:
|
|
|
148
165
|
cur = self._db.execute(
|
|
149
166
|
"""INSERT INTO order_history
|
|
150
167
|
(wallet_address, order_id, token_id, side, price, size, order_type,
|
|
151
|
-
status, error_msg, response_json, created_at
|
|
152
|
-
|
|
168
|
+
status, error_msg, response_json, created_at,
|
|
169
|
+
fee_amount_raw, escrow_order_id, fee_escrow_tx_hash)
|
|
170
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
|
153
171
|
(
|
|
154
172
|
order["wallet_address"], order.get("order_id"), order["token_id"],
|
|
155
173
|
order["side"], order["price"], order["size"], order.get("order_type", "GTC"),
|
|
156
174
|
order.get("status", "submitting"), order.get("error_msg"),
|
|
157
175
|
order.get("response_json"), order.get("created_at", time.time()),
|
|
176
|
+
order.get("fee_amount_raw"), order.get("escrow_order_id"),
|
|
177
|
+
order.get("fee_escrow_tx_hash"),
|
|
158
178
|
),
|
|
159
179
|
)
|
|
160
180
|
self._db.commit()
|
|
@@ -163,13 +183,17 @@ class TradingSqliteBackend:
|
|
|
163
183
|
def update_order_status(
|
|
164
184
|
self, row_id: int, status: str, order_id: str | None = None,
|
|
165
185
|
error_msg: str | None = None, response_json: str | None = None,
|
|
186
|
+
fee_amount_raw: str | None = None, escrow_order_id: str | None = None,
|
|
187
|
+
fee_escrow_tx_hash: str | None = None,
|
|
166
188
|
) -> None:
|
|
167
189
|
self._db.execute(
|
|
168
190
|
"""UPDATE order_history
|
|
169
191
|
SET status = ?, order_id = COALESCE(?, order_id),
|
|
170
|
-
error_msg = COALESCE(?, error_msg), response_json = COALESCE(?, response_json)
|
|
192
|
+
error_msg = COALESCE(?, error_msg), response_json = COALESCE(?, response_json),
|
|
193
|
+
fee_amount_raw = COALESCE(?, fee_amount_raw), escrow_order_id = COALESCE(?, escrow_order_id),
|
|
194
|
+
fee_escrow_tx_hash = COALESCE(?, fee_escrow_tx_hash)
|
|
171
195
|
WHERE id = ?""",
|
|
172
|
-
(status, order_id, error_msg, response_json, row_id),
|
|
196
|
+
(status, order_id, error_msg, response_json, fee_amount_raw, escrow_order_id, fee_escrow_tx_hash, row_id),
|
|
173
197
|
)
|
|
174
198
|
self._db.commit()
|
|
175
199
|
|
|
@@ -200,6 +224,9 @@ class TradingSqliteBackend:
|
|
|
200
224
|
id=r[0], wallet_address=r[1], order_id=r[2], token_id=r[3],
|
|
201
225
|
side=r[4], price=r[5], size=r[6], order_type=r[7],
|
|
202
226
|
status=r[8], error_msg=r[9], response_json=r[10], created_at=r[11],
|
|
227
|
+
fee_amount_raw=r[12] if len(r) > 12 else None,
|
|
228
|
+
escrow_order_id=r[13] if len(r) > 13 else None,
|
|
229
|
+
fee_escrow_tx_hash=r[14] if len(r) > 14 else None,
|
|
203
230
|
)
|
|
204
231
|
for r in rows
|
|
205
232
|
]
|
polynode/trading/trader.py
CHANGED
|
@@ -24,6 +24,7 @@ from .constants import (
|
|
|
24
24
|
)
|
|
25
25
|
from .cosigner import build_l2_headers, send_via_cosigner
|
|
26
26
|
from .eip712 import create_signed_order, create_signed_order_v2
|
|
27
|
+
from .escrow import calculate_fee, generate_escrow_order_id, fetch_escrow_nonce, sign_fee_auth
|
|
27
28
|
from .onboarding import (
|
|
28
29
|
check_approvals as check_approvals_onchain,
|
|
29
30
|
check_balance as check_balance_onchain,
|
|
@@ -55,6 +56,7 @@ from .types import (
|
|
|
55
56
|
TraderConfig,
|
|
56
57
|
WalletExport,
|
|
57
58
|
WalletInfo,
|
|
59
|
+
FeeConfig,
|
|
58
60
|
)
|
|
59
61
|
|
|
60
62
|
|
|
@@ -71,6 +73,7 @@ class PolyNodeTrader:
|
|
|
71
73
|
self._rpc_url = c.rpc_url
|
|
72
74
|
self._builder_credentials = c.builder_credentials
|
|
73
75
|
self._exchange_version = c.exchange_version
|
|
76
|
+
self._fee_config = c.fee_config
|
|
74
77
|
|
|
75
78
|
self._db: TradingSqliteBackend | None = None
|
|
76
79
|
self._active_signer: NormalizedSigner | None = None
|
|
@@ -579,9 +582,47 @@ class PolyNodeTrader:
|
|
|
579
582
|
"status": "submitting",
|
|
580
583
|
})
|
|
581
584
|
|
|
585
|
+
# Build fee auth if escrow is enabled
|
|
586
|
+
fee_config = params.fee_config or self._fee_config
|
|
587
|
+
fee_auth_dict = None
|
|
588
|
+
fee_amount_raw = 0
|
|
589
|
+
if fee_config and fee_config.fee_bps > 0:
|
|
590
|
+
fee_amount_raw = calculate_fee(params.price, params.size, fee_config.fee_bps)
|
|
591
|
+
if fee_amount_raw > 0:
|
|
592
|
+
funder = creds.funder_address or creds.wallet_address
|
|
593
|
+
nonce = await fetch_escrow_nonce(self._rpc_url, signer.address)
|
|
594
|
+
deadline = int(time.time()) + 300
|
|
595
|
+
escrow_oid = generate_escrow_order_id()
|
|
596
|
+
fee_auth = await sign_fee_auth(
|
|
597
|
+
signer.sign_typed_data,
|
|
598
|
+
escrow_order_id=escrow_oid,
|
|
599
|
+
payer=funder,
|
|
600
|
+
signer_address=signer.address,
|
|
601
|
+
fee_amount=fee_amount_raw,
|
|
602
|
+
deadline=deadline,
|
|
603
|
+
nonce=nonce,
|
|
604
|
+
affiliate=fee_config.affiliate,
|
|
605
|
+
affiliate_share_bps=fee_config.affiliate_share_bps,
|
|
606
|
+
)
|
|
607
|
+
fee_auth_dict = {
|
|
608
|
+
"escrow_order_id": fee_auth.escrow_order_id,
|
|
609
|
+
"payer": fee_auth.payer,
|
|
610
|
+
"signer": fee_auth.signer,
|
|
611
|
+
"fee_amount": fee_auth.fee_amount,
|
|
612
|
+
"deadline": fee_auth.deadline,
|
|
613
|
+
"nonce": fee_auth.nonce,
|
|
614
|
+
"signature": fee_auth.signature,
|
|
615
|
+
"affiliate": fee_auth.affiliate,
|
|
616
|
+
"affiliate_share_bps": fee_auth.affiliate_share_bps,
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
request_data: dict[str, Any] = {"method": "POST", "path": "/order", "body": body_str, "headers": headers}
|
|
620
|
+
if fee_auth_dict:
|
|
621
|
+
request_data["fee_auth"] = fee_auth_dict
|
|
622
|
+
|
|
582
623
|
result = await send_via_cosigner(
|
|
583
624
|
self._cosigner_url, self._polynode_key, self._fallback_direct,
|
|
584
|
-
|
|
625
|
+
request_data,
|
|
585
626
|
builder_credentials=self._builder_credentials,
|
|
586
627
|
clob_host=clob_host,
|
|
587
628
|
)
|
|
@@ -603,6 +644,8 @@ class PolyNodeTrader:
|
|
|
603
644
|
error=error,
|
|
604
645
|
making_amount=result.get("makingAmount"),
|
|
605
646
|
taking_amount=result.get("takingAmount"),
|
|
647
|
+
fee_escrow_tx_hash=result.get("feeEscrowTxHash"),
|
|
648
|
+
fee_amount=str(fee_amount_raw / 1e6) if fee_amount_raw > 0 else None,
|
|
606
649
|
)
|
|
607
650
|
|
|
608
651
|
async def cancel_order(self, order_id: str) -> CancelResult:
|
polynode/trading/types.py
CHANGED
|
@@ -38,6 +38,14 @@ class GeneratedWallet:
|
|
|
38
38
|
address: str
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
@dataclass
|
|
42
|
+
class FeeConfig:
|
|
43
|
+
"""Optional fee configuration for per-order fee collection via on-chain escrow."""
|
|
44
|
+
fee_bps: int # fee in basis points (e.g. 50 = 0.5%)
|
|
45
|
+
affiliate: str | None = None # partner wallet address
|
|
46
|
+
affiliate_share_bps: int | None = None # partner's share of fee in bps
|
|
47
|
+
|
|
48
|
+
|
|
41
49
|
@dataclass
|
|
42
50
|
class BuilderCredentials:
|
|
43
51
|
"""Polymarket builder credentials for order attribution."""
|
|
@@ -56,6 +64,7 @@ class TraderConfig:
|
|
|
56
64
|
rpc_url: str = "https://polygon-bor-rpc.publicnode.com"
|
|
57
65
|
builder_credentials: BuilderCredentials | None = None
|
|
58
66
|
exchange_version: ExchangeVersion = ExchangeVersion.V1
|
|
67
|
+
fee_config: FeeConfig | None = None
|
|
59
68
|
|
|
60
69
|
|
|
61
70
|
@dataclass
|
|
@@ -127,6 +136,7 @@ class OrderParams:
|
|
|
127
136
|
type: OrderType = "GTC"
|
|
128
137
|
expiration: int | None = None
|
|
129
138
|
post_only: bool = False
|
|
139
|
+
fee_config: FeeConfig | None = None
|
|
130
140
|
|
|
131
141
|
|
|
132
142
|
@dataclass
|
|
@@ -137,6 +147,8 @@ class OrderResult:
|
|
|
137
147
|
error: str | None = None
|
|
138
148
|
making_amount: str | None = None
|
|
139
149
|
taking_amount: str | None = None
|
|
150
|
+
fee_escrow_tx_hash: str | None = None
|
|
151
|
+
fee_amount: str | None = None
|
|
140
152
|
|
|
141
153
|
|
|
142
154
|
@dataclass
|
|
@@ -224,6 +236,9 @@ class OrderHistoryRow:
|
|
|
224
236
|
error_msg: str | None
|
|
225
237
|
response_json: str | None
|
|
226
238
|
created_at: float
|
|
239
|
+
fee_amount_raw: str | None = None
|
|
240
|
+
escrow_order_id: str | None = None
|
|
241
|
+
fee_escrow_tx_hash: str | None = None
|
|
227
242
|
|
|
228
243
|
|
|
229
244
|
@dataclass
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
polynode/__init__.py,sha256=ucqXzFPMdEcfGEAdbgOeJczREEiSCNBX1G3Il7y8-UI,1127
|
|
2
|
-
polynode/_version.py,sha256=
|
|
2
|
+
polynode/_version.py,sha256=lcrcqfPdVkkAQSUY7-6U3m2gooWLXX_neDSS8dIuHdc,22
|
|
3
3
|
polynode/client.py,sha256=eSCKpuZFg2ssQC5tmsfRYF3cTqCk1Gdw4KPjbd5MFHQ,21831
|
|
4
4
|
polynode/engine.py,sha256=DSXBmx3DXPh-PN0ihkXn7LSiyxeOoo0iY3z4YinQ3XI,6488
|
|
5
5
|
polynode/errors.py,sha256=5qUCI7K76VKbF5R5G5UYhPzcnOPlGLCA8-sJnKbrK-4,925
|
|
@@ -11,18 +11,19 @@ polynode/subscription.py,sha256=O2yKfdllI0px-1qrVK-0Qq9S4KUmIiXjjYCNC7QW0jM,4121
|
|
|
11
11
|
polynode/testing.py,sha256=bSSgV18ZSaRoLZPlNRCCLmRNwNIQDS35qi7NhuTg8Bg,2802
|
|
12
12
|
polynode/ws.py,sha256=VZdn2dkUJH2-CYBu_L45YnvCU0kQejxHcy2Ji2pRu60,9653
|
|
13
13
|
polynode/cache/__init__.py,sha256=A9lXcIE3ISKKo1r0o3o-CkmQpBhLdKwdQfCR0eW5i9o,519
|
|
14
|
-
polynode/trading/__init__.py,sha256=
|
|
14
|
+
polynode/trading/__init__.py,sha256=sPv30j9eyvqjnUBxGAYaKpAPQZ2jTw3UwA4DZXYZ21s,923
|
|
15
15
|
polynode/trading/clob_api.py,sha256=ygaOoMIg4PGtMzNBT70wk4XrSbVX0EyCCU6PmXK3xrs,5308
|
|
16
|
-
polynode/trading/constants.py,sha256=
|
|
16
|
+
polynode/trading/constants.py,sha256=_DDwutJkOfeyPkClrTcyJCOYMoqDymZzDpjYWeHbfG0,1862
|
|
17
17
|
polynode/trading/cosigner.py,sha256=Fww9OgaKdHQAHd8Kom1AJBtmMGC8FbNZxdFaFALNBY8,3058
|
|
18
18
|
polynode/trading/eip712.py,sha256=pZf0Pf4DDIPpK4qbz4DWfcdOeU8PlCQhJPpKSQ97pC4,9553
|
|
19
|
-
polynode/trading/
|
|
19
|
+
polynode/trading/escrow.py,sha256=mDNAUQUzFOvzo6HpmqJTzjMEx7o3ySQHoVbvNiqIwmA,4549
|
|
20
|
+
polynode/trading/onboarding.py,sha256=-Ub5tsJA4vqPJmkNLx2OE_szUY08UmXYi_9ATThajkA,14670
|
|
20
21
|
polynode/trading/position_management.py,sha256=z2pYls4ErhyRE6thQdOs45BF4llKvKNNruQgcMEFT_U,3827
|
|
21
22
|
polynode/trading/privy.py,sha256=iiUQZsBqjj29C7oUiFFktoT2muZY06bcMzABKstFKqE,4523
|
|
22
23
|
polynode/trading/signer.py,sha256=piifRquwnwFwrKLL24jsRQYMh_cdkz8wNz99Vx8_KTY,3413
|
|
23
|
-
polynode/trading/sqlite_backend.py,sha256=
|
|
24
|
-
polynode/trading/trader.py,sha256=
|
|
25
|
-
polynode/trading/types.py,sha256=
|
|
24
|
+
polynode/trading/sqlite_backend.py,sha256=zfo4WevuunWV-7i6Z3gQi_e7Tonw-7m1TsEd88O5I4w,9486
|
|
25
|
+
polynode/trading/trader.py,sha256=U2dghRO5Ra1-2UqCBzOkI3GYvGPvAHKJAc2lFF-UJXQ,31541
|
|
26
|
+
polynode/trading/types.py,sha256=JxhjsRRhh8WA127VNNPLf7QJKn5e_PZucaG7WAfdOsM,5528
|
|
26
27
|
polynode/types/__init__.py,sha256=0v_CByqG-zT1xucbT2So_77YDmsPj9u956at94nyrLM,280
|
|
27
28
|
polynode/types/enums.py,sha256=2cx9l10A-LUeDNBJZn7l0XBTka2YfxRQcXW0s7s3_4k,1082
|
|
28
29
|
polynode/types/events.py,sha256=MJGZqxBFKfT1y44dZ96bHbwvoPpGvtutBwYE6OTT6nU,6880
|
|
@@ -30,6 +31,6 @@ polynode/types/orderbook.py,sha256=MwD6P3poo3F70bONUZ5i3ajk1sgw39hHTOw6D0fP5_8,1
|
|
|
30
31
|
polynode/types/rest.py,sha256=ftJKQZH0wBrR_l199rDMqnVS8cyt8YnCvo9cKIsTcCw,7012
|
|
31
32
|
polynode/types/short_form.py,sha256=xfGklDi587u6K2aXaRWiwbxqkipW8BiEPeNIDT45v2Y,799
|
|
32
33
|
polynode/types/ws.py,sha256=EzE9Vzrb6cILemfssmnqM8fbHt4USn3latpUHKatwk4,994
|
|
33
|
-
polynode-0.7.
|
|
34
|
-
polynode-0.7.
|
|
35
|
-
polynode-0.7.
|
|
34
|
+
polynode-0.7.2.dist-info/METADATA,sha256=AMgCidJ2QSucrPTg9fjGTMFTUevK02Std5zw-KSMWuo,3302
|
|
35
|
+
polynode-0.7.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
36
|
+
polynode-0.7.2.dist-info/RECORD,,
|
|
File without changes
|