Baseline: Ausgangszustand vor Modularisierung
Erster Commit des bestehenden monolithischen WinForms-Copytraders, inklusive der Alt-Backups (*.bak), damit diese dauerhaft in der Historie rekonstruierbar bleiben. Threema-Lib unter libs/ wurde vendored (nested .git entfernt). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
$PSWindow = (Get-Host).UI.RawUI
|
||||
$NewSize = New-Object System.Management.Automation.Host.Size(4000, 3000)
|
||||
$PSWindow.BufferSize = $NewSize
|
||||
$PSWindow.WindowSize = New-Object System.Management.Automation.Host.Size(120, 50)
|
||||
dotnet build -clp:ErrorsOnly
|
||||
@@ -0,0 +1,14 @@
|
||||
using LiteDB;
|
||||
using System.Linq;
|
||||
|
||||
using (var db = new LiteDatabase(@"j:\Softwareprojekte\PolytraderSharp\PolyTraderSharp\bin\Debug\net8.0-windows7.0\polytrader_data.db"))
|
||||
{
|
||||
var accounts = db.GetCollection("accounts").FindAll().ToList();
|
||||
foreach(var acc in accounts)
|
||||
{
|
||||
var id = acc["_id"].AsInt32;
|
||||
var name = acc["Name"].AsString;
|
||||
var active = acc["IsActive"].AsBoolean;
|
||||
Console.WriteLine($"ID: {id}, Name: {name}, Active: {active}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using LiteDB;
|
||||
using System.Linq;
|
||||
|
||||
using (var db = new LiteDatabase(@"j:\Softwareprojekte\PolytraderSharp\PolyTraderSharp\bin\Debug\net8.0-windows7.0\data.db"))
|
||||
{
|
||||
var accounts = db.GetCollection("accounts").FindAll().ToList();
|
||||
foreach(var acc in accounts)
|
||||
{
|
||||
var id = acc["_id"].AsInt32;
|
||||
var name = acc["Name"].AsString;
|
||||
var active = acc["IsActive"].AsBoolean;
|
||||
Console.WriteLine($"ID: {id}, Name: {name}, Active: {active}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import sys
|
||||
|
||||
def check_enc(fpath):
|
||||
with open(fpath, 'rb') as f:
|
||||
head = f.read(4)
|
||||
print("BOM bytes:", head.hex())
|
||||
|
||||
check_enc(sys.argv[1])
|
||||
@@ -0,0 +1,257 @@
|
||||
from typing import Any
|
||||
from dataclasses import dataclass, asdict
|
||||
from json import dumps
|
||||
from typing import Literal, Optional
|
||||
from py_order_utils.model import (
|
||||
SignedOrder,
|
||||
)
|
||||
|
||||
from .constants import ZERO_ADDRESS
|
||||
|
||||
|
||||
class OrderType(enumerate):
|
||||
GTC = "GTC"
|
||||
FOK = "FOK"
|
||||
GTD = "GTD"
|
||||
FAK = "FAK"
|
||||
|
||||
|
||||
@dataclass
|
||||
class ApiCreds:
|
||||
api_key: str
|
||||
api_secret: str
|
||||
api_passphrase: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReadonlyApiKeyResponse:
|
||||
api_key: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class RequestArgs:
|
||||
method: str
|
||||
request_path: str
|
||||
body: Any = None
|
||||
serialized_body: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class BookParams:
|
||||
token_id: str
|
||||
side: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrderArgs:
|
||||
token_id: str
|
||||
"""
|
||||
TokenID of the Conditional token asset being traded
|
||||
"""
|
||||
|
||||
price: float
|
||||
"""
|
||||
Price used to create the order
|
||||
"""
|
||||
|
||||
size: float
|
||||
"""
|
||||
Size in terms of the ConditionalToken
|
||||
"""
|
||||
|
||||
side: str
|
||||
"""
|
||||
Side of the order
|
||||
"""
|
||||
|
||||
fee_rate_bps: int = 0
|
||||
"""
|
||||
Fee rate, in basis points, charged to the order maker, charged on proceeds
|
||||
"""
|
||||
|
||||
nonce: int = 0
|
||||
"""
|
||||
Nonce used for onchain cancellations
|
||||
"""
|
||||
|
||||
expiration: int = 0
|
||||
"""
|
||||
Timestamp after which the order is expired.
|
||||
"""
|
||||
|
||||
taker: str = ZERO_ADDRESS
|
||||
"""
|
||||
Address of the order taker. The zero address is used to indicate a public order
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class MarketOrderArgs:
|
||||
token_id: str
|
||||
"""
|
||||
TokenID of the Conditional token asset being traded
|
||||
"""
|
||||
|
||||
amount: float
|
||||
"""
|
||||
BUY orders: $$$ Amount to buy
|
||||
SELL orders: Shares to sell
|
||||
"""
|
||||
|
||||
side: str
|
||||
"""
|
||||
Side of the order
|
||||
"""
|
||||
|
||||
price: float = 0
|
||||
"""
|
||||
Price used to create the order
|
||||
"""
|
||||
|
||||
fee_rate_bps: int = 0
|
||||
"""
|
||||
Fee rate, in basis points, charged to the order maker, charged on proceeds
|
||||
"""
|
||||
|
||||
nonce: int = 0
|
||||
"""
|
||||
Nonce used for onchain cancellations
|
||||
"""
|
||||
|
||||
taker: str = ZERO_ADDRESS
|
||||
"""
|
||||
Address of the order taker. The zero address is used to indicate a public order
|
||||
"""
|
||||
|
||||
order_type: OrderType = OrderType.FOK
|
||||
|
||||
|
||||
@dataclass
|
||||
class TradeParams:
|
||||
id: str = None
|
||||
maker_address: str = None
|
||||
market: str = None
|
||||
asset_id: str = None
|
||||
before: int = None
|
||||
after: int = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class OpenOrderParams:
|
||||
id: str = None
|
||||
market: str = None
|
||||
asset_id: str = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class DropNotificationParams:
|
||||
ids: list[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrderSummary:
|
||||
price: str = None
|
||||
size: str = None
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
return asdict(self)
|
||||
|
||||
@property
|
||||
def json(self):
|
||||
return dumps(self.__dict__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrderBookSummary:
|
||||
market: str = None
|
||||
asset_id: str = None
|
||||
timestamp: str = None
|
||||
bids: list[OrderSummary] = None
|
||||
asks: list[OrderSummary] = None
|
||||
min_order_size: str = None
|
||||
neg_risk: bool = None
|
||||
tick_size: str = None
|
||||
last_trade_price: str = None
|
||||
hash: str = None
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
return asdict(self)
|
||||
|
||||
@property
|
||||
def json(self):
|
||||
return dumps(self.__dict__, separators=(",", ":"))
|
||||
|
||||
|
||||
class AssetType(enumerate):
|
||||
COLLATERAL = "COLLATERAL"
|
||||
CONDITIONAL = "CONDITIONAL"
|
||||
|
||||
|
||||
@dataclass
|
||||
class BalanceAllowanceParams:
|
||||
asset_type: AssetType = None
|
||||
token_id: str = None
|
||||
signature_type: int = -1
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrderScoringParams:
|
||||
orderId: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class OrdersScoringParams:
|
||||
orderIds: list[str]
|
||||
|
||||
|
||||
TickSize = Literal["0.1", "0.01", "0.001", "0.0001"]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CreateOrderOptions:
|
||||
tick_size: TickSize
|
||||
neg_risk: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class PartialCreateOrderOptions:
|
||||
tick_size: Optional[TickSize] = None
|
||||
neg_risk: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoundConfig:
|
||||
price: float
|
||||
size: float
|
||||
amount: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class ContractConfig:
|
||||
"""
|
||||
Contract Configuration
|
||||
"""
|
||||
|
||||
exchange: str
|
||||
"""
|
||||
The exchange contract responsible for matching orders
|
||||
"""
|
||||
|
||||
collateral: str
|
||||
"""
|
||||
The ERC20 token used as collateral for the exchange's markets
|
||||
"""
|
||||
|
||||
conditional_tokens: str
|
||||
"""
|
||||
The ERC1155 conditional tokens contract
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class PostOrdersArgs:
|
||||
order: SignedOrder
|
||||
orderType: OrderType = OrderType.GTC
|
||||
postOnly: bool = False
|
||||
@@ -0,0 +1,11 @@
|
||||
import requests
|
||||
import json
|
||||
url = "https://polygon-rpc.com"
|
||||
payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "eth_getTransactionReceipt",
|
||||
"params": ["0x884bd63c71974579e525ad9af7a081ef7f81faeed980f7f46a7fbfd8ad7534eb"],
|
||||
"id": 1
|
||||
}
|
||||
resp = requests.post(url, json=payload).json()
|
||||
print(json.dumps(resp, indent=2))
|
||||
@@ -0,0 +1,8 @@
|
||||
import sys
|
||||
with open("j:/Softwareprojekte/PolytraderSharp/PolyTraderSharp/services/PolymarketApiService.cs", "r", encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
with open("j:/Softwareprojekte/PolytraderSharp/PolyTraderSharp/services/PolymarketApiService.cs", "w", encoding="utf-8") as f:
|
||||
for i, line in enumerate(lines):
|
||||
if 649 <= i <= 843:
|
||||
continue
|
||||
f.write(line)
|
||||
@@ -0,0 +1,14 @@
|
||||
from pymongo import MongoClient
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
client = MongoClient('mongodb://localhost:27017/')
|
||||
db = client['PolyTraderDB']
|
||||
col = db['closed_trades']
|
||||
|
||||
deleted = 0
|
||||
for doc in col.find({}):
|
||||
if isinstance(doc['_id'], ObjectId):
|
||||
col.delete_one({'_id': doc['_id']})
|
||||
deleted += 1
|
||||
|
||||
print(f"Deleted {deleted} invalid ObjectId records from closed_trades.")
|
||||
@@ -0,0 +1,2 @@
|
||||
$response = Invoke-RestMethod -Uri "https://data-api.polymarket.com/activity?user=0xC5d563A36AE78145C45a50134d48A1215220f80a"
|
||||
$response | ConvertTo-Json -Depth 10 > debug_activity.json
|
||||
@@ -0,0 +1,2 @@
|
||||
$response = Invoke-RestMethod -Uri "https://gamma-api.polymarket.com/events?slug=highest-temperature-in-seattle-on-march-4-2026-54-55f"
|
||||
$response | ConvertTo-Json -Depth 5 > debug_event.json
|
||||
@@ -0,0 +1,2 @@
|
||||
$response = Invoke-RestMethod -Uri "https://data-api.polymarket.com/markets?asset_id=16390480740794212860585822641698670781065007954223853906471315387406983668414"
|
||||
$response | ConvertTo-Json -Depth 5 > debug_market.json
|
||||
@@ -0,0 +1,2 @@
|
||||
$response = Invoke-RestMethod -Uri "https://data-api.polymarket.com/positions?user=0xC5d563A36AE78145C45a50134d48A1215220f80a"
|
||||
$response | ConvertTo-Json -Depth 10 > debug_positions.json
|
||||
@@ -0,0 +1,161 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
def patch_file(designer_file):
|
||||
with open(designer_file, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
grids = {
|
||||
"dgv_dashboard": [
|
||||
("AccountId", "Account ID", False, False),
|
||||
("IsDemo", "Is Demo", False, False),
|
||||
("IsActive", "Is Active", False, False),
|
||||
("AccountName", "Account", True, False),
|
||||
("TotalBalance", "Total USD", True, False),
|
||||
("AvailableBalance", "Available", True, False),
|
||||
("PositionBalance", "Positions", True, False),
|
||||
("OpenTradesCount", "Open", True, False),
|
||||
("ClosedTrades24h", "Closed 24h", True, False),
|
||||
("Pnl24h", "Pnl 24h", True, False),
|
||||
("Winrate24h", "Winrate 24h", True, False),
|
||||
("ClosedTrades7d", "Closed 7d", True, False),
|
||||
("Pnl7d", "Pnl 7d", True, False),
|
||||
("Winrate7d", "Winrate 7d", True, False)
|
||||
],
|
||||
"dgv_openTrades": [
|
||||
("AccountName", "Account", True, False),
|
||||
("SourceTraderName", "Copied From", True, True),
|
||||
("MarketQuestion", "Market", True, True),
|
||||
("MarketSlug", "Market Slug", False, False),
|
||||
("Outcome", "Outcome", True, False),
|
||||
("Side", "Side", True, False),
|
||||
("EntryPrice", "Entry Price", True, False),
|
||||
("Size", "Shares", True, False),
|
||||
("AmountUsd", "Amount USD", True, False)
|
||||
],
|
||||
"dgv_closedTrades": [
|
||||
("TradeId", "ID", False, False),
|
||||
("AccountId", "Account ID", False, False),
|
||||
("SourceTraderId", "SourceTraderId", False, False),
|
||||
("IsDemo", "Is Demo", False, False),
|
||||
("TokenId", "TokenId", False, False),
|
||||
("MarketSlug", "Market Slug", False, False),
|
||||
("MarketQuestion", "Market", True, True),
|
||||
("Outcome", "Outcome", True, False),
|
||||
("Side", "Side", True, False),
|
||||
("EntryPrice", "Entry Price", True, False),
|
||||
("ExitPrice", "Exit Price", True, False),
|
||||
("Size", "Shares", True, False),
|
||||
("RealizedPnl", "P&L", True, False),
|
||||
("PnlPercent", "P&L %", True, False),
|
||||
("TotalFees", "Fees", True, False),
|
||||
("OpenedAt", "Opened At", True, False),
|
||||
("ClosedAt", "Closed At", True, False),
|
||||
("ExitReason", "Reason", True, False)
|
||||
],
|
||||
"dgv_masterTraders": [
|
||||
("Id", "Id", False, False),
|
||||
("WalletAddress", "Wallet", True, False),
|
||||
("DisplayName", "Name", True, False),
|
||||
("Category", "Category", True, False),
|
||||
("Description", "Description", True, False),
|
||||
("Reasoning", "Reasoning", True, False),
|
||||
("IsActive", "Is Active", True, False),
|
||||
("IsHidden", "Is Hidden", True, False),
|
||||
("TotalTrades", "Trades", True, False),
|
||||
("WinningTrades", "Wins", True, False),
|
||||
("Winrate30t", "Winrate 30t", True, False),
|
||||
("TotalPnl", "Total P&L", True, False)
|
||||
],
|
||||
"dgv_SlaveTraders": [
|
||||
("AccountId", "ID", False, False),
|
||||
("Name", "Name", True, False),
|
||||
("WalletAddress", "Wallet", True, False),
|
||||
("IsDemo", "Is Demo", True, False),
|
||||
("IsActive", "Is Active", True, False),
|
||||
("CloseOnlyMode", "Close Only", True, False),
|
||||
("PayoutAddress", "Payout Address", True, False),
|
||||
("PayoutLimitUsd", "Payout Limit", True, False),
|
||||
("PerMarketLimit", "Max %", True, False),
|
||||
("MaxPriceDifference", "Max Price Diff", True, False),
|
||||
("MaxBuyPrice", "Max Buy Price", True, False),
|
||||
("ProfitTarget", "Profit Target", True, False),
|
||||
("LimitUnder6h", "< 6h", True, False),
|
||||
("LimitUnder24h", "< 24h", True, False),
|
||||
("LimitUnder72h", "< 72h", True, False),
|
||||
("LimitOver72h", "> 72h", True, False)
|
||||
]
|
||||
}
|
||||
|
||||
declarations = []
|
||||
instantiations = []
|
||||
setups = []
|
||||
|
||||
for dgv_name, cols in grids.items():
|
||||
if f"{dgv_name}.Columns.AddRange" in content:
|
||||
print(f"{dgv_name} already patched.")
|
||||
continue
|
||||
|
||||
col_refs = []
|
||||
for prop, header, visible, is_link in cols:
|
||||
col_type = "DataGridViewLinkColumn" if is_link else "DataGridViewTextBoxColumn"
|
||||
col_name = f"col_{dgv_name}_{prop}"
|
||||
col_refs.append(f"{col_name}")
|
||||
|
||||
declarations.append(f"private {col_type} {col_name};")
|
||||
instantiations.append(f"{col_name} = new {col_type}();")
|
||||
|
||||
setup = f"""//
|
||||
// {col_name}
|
||||
//
|
||||
{col_name}.DataPropertyName = "{prop}";
|
||||
{col_name}.HeaderText = "{header}";
|
||||
{col_name}.Name = "{col_name}";
|
||||
{col_name}.ReadOnly = true;
|
||||
"""
|
||||
if not visible:
|
||||
setup += f"{col_name}.Visible = false;\n"
|
||||
|
||||
if is_link:
|
||||
setup += f"{col_name}.ActiveLinkColor = Color.White;\n"
|
||||
setup += f"{col_name}.LinkBehavior = LinkBehavior.SystemDefault;\n"
|
||||
setup += f"{col_name}.LinkColor = Color.Blue;\n"
|
||||
setup += f"{col_name}.TrackVisitedState = true;\n"
|
||||
setup += f"{col_name}.VisitedLinkColor = Color.Purple;\n"
|
||||
|
||||
setups.append(setup)
|
||||
|
||||
add_range_code = f"{dgv_name}.Columns.AddRange(new DataGridViewColumn[] {{ " + ", ".join(col_refs) + " });\n"
|
||||
|
||||
# find `dgv_name.Name = "..."`
|
||||
pattern = f'({dgv_name}\\.Name = "{dgv_name}";)'
|
||||
content, n = re.subn(pattern, r'\1\n ' + add_range_code.replace('\n', '\n '), content)
|
||||
if n == 0:
|
||||
print(f"FAILED to find {pattern}")
|
||||
|
||||
if not declarations:
|
||||
print("No grids to patch or already patched.")
|
||||
return
|
||||
|
||||
# Declarations
|
||||
bottom_pattern = r'(private DataGridView dgv_dashboard;)'
|
||||
decl_str = "\n ".join(declarations) + "\n "
|
||||
content, n = re.subn(bottom_pattern, decl_str + r'\1', content)
|
||||
|
||||
# Instantiations
|
||||
top_pattern = r'(dgv_dashboard = new DataGridView\(\);)'
|
||||
inst_str = "\n ".join(instantiations) + "\n "
|
||||
content, n = re.subn(top_pattern, inst_str + r'\1', content)
|
||||
|
||||
# Setups
|
||||
resume_pattern = r'(\(\(System\.ComponentModel\.ISupportInitialize\)dgv_dashboard\)\.EndInit\(\);)'
|
||||
setup_str = "\n ".join("\n ".join(s.splitlines()) for s in setups) + "\n "
|
||||
content, n = re.subn(resume_pattern, setup_str + r'\1', content)
|
||||
|
||||
with open(designer_file, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print("Patched successfully.")
|
||||
|
||||
if __name__ == '__main__':
|
||||
patch_file(sys.argv[1])
|
||||
@@ -0,0 +1,6 @@
|
||||
$json = Get-Content "debug_event.json" -Raw
|
||||
$obj = ConvertFrom-Json $json
|
||||
Write-Output "Event Closed: $($obj[0].closed)"
|
||||
Write-Output "Event Active: $($obj[0].active)"
|
||||
Write-Output "First Market Resolved: $($obj[0].markets[0].closed)"
|
||||
Write-Output "First Market Winner: $($obj[0].markets[0].winner)"
|
||||
@@ -0,0 +1,39 @@
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
# PolyTraderSharp - Auto-Redeem Stub
|
||||
# Dieses Skript dient als Brücke zur Polymarket Relayer API, um gewonnene Tokens
|
||||
# automatisiert (gasless) via On-Chain Meta-Transaktion auszulösen.
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
def redeem_tokens(token_ids, api_key, private_key, api_passphrase):
|
||||
# WICHTIG: Die offizielle Automatisierung von "Redeems" ohne Gas-Gebühren
|
||||
# erfordert Polymarkets py-builder-relayer-client SDK oder Relayer JWT Keys.
|
||||
# Da das Gnosis Safe Proxy Wallet angesprochen werden muss, ist das klassische py_clob_client SDK dafür nicht ausgelegt.
|
||||
|
||||
# 1. Sammle Token IDs
|
||||
tokens = [t.strip() for t in token_ids.split(",") if t.strip()]
|
||||
|
||||
logging.info(f"Redeem-Anforderung für Token erkannt: {tokens}")
|
||||
logging.warning("HINWEIS: Ein vollautomatisierter On-Chain Redeem erfordert das 'builder-relayer-client-python' Package.")
|
||||
logging.warning("Installiere es (sofern Polymarket es publiziert hat) oder nutze die Relayer REST-API direkt mit L2 Signaturen.")
|
||||
logging.info("PolyTraderSharp hat die C#-seitige Accounting-Logik aktualisiert, sodass Gewinne/Verluste in deinem Interface nun sofort verbucht werden!")
|
||||
|
||||
# Placeholder für erfolgreiches Accounting
|
||||
print(json.dumps({"status": "accounting_only", "redeemed_tokens": tokens}))
|
||||
return
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 5:
|
||||
print("Usage: python redeem_markets.py <token_ids_comma_separated> <api_key> <private_key> <api_passphrase>")
|
||||
sys.exit(1)
|
||||
|
||||
token_ids = sys.argv[1]
|
||||
api_key = sys.argv[2]
|
||||
private_key = sys.argv[3]
|
||||
api_passphrase = sys.argv[4]
|
||||
|
||||
redeem_tokens(token_ids, api_key, private_key, api_passphrase)
|
||||
@@ -0,0 +1,38 @@
|
||||
import re
|
||||
import sys
|
||||
|
||||
def revert_file(filepath):
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 1. Remove AddRange statements for our columns
|
||||
# Example: dgv_dashboard.Columns.AddRange(new DataGridViewColumn[] { ... col_dgv_ ... });
|
||||
pattern1 = r'\s*dgv_\w+\.Columns\.AddRange\(new DataGridViewColumn\[\] \{[^}]*col_dgv_[^}]*\}\);'
|
||||
content = re.sub(pattern1, '', content, flags=re.MULTILINE)
|
||||
|
||||
# 2. Remove all lines referencing col_dgv_ (declarations, instantiations, property assignments)
|
||||
# Be careful not to remove lines that just accidentally match. We'll match lines that start with whitespace and have col_dgv_
|
||||
lines = content.splitlines()
|
||||
new_lines = []
|
||||
skip = False
|
||||
for line in lines:
|
||||
if "col_dgv_" in line:
|
||||
continue
|
||||
if line.strip() == "//" and new_lines and new_lines[-1].strip() == "//":
|
||||
# Might be part of our property comment block // \n // col_name \n //
|
||||
# Wait, easier to just strip empty trailing // later.
|
||||
pass
|
||||
new_lines.append(line)
|
||||
|
||||
content = "\n".join(new_lines)
|
||||
|
||||
# 3. Clean up empty comment blocks
|
||||
content = re.sub(r'\s*// \s*\n\s*// \s*\n\s*// \s*\n', '\n', content)
|
||||
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print("Reverted.")
|
||||
|
||||
if __name__ == '__main__':
|
||||
revert_file(sys.argv[1])
|
||||
@@ -0,0 +1,35 @@
|
||||
import sys
|
||||
import datetime
|
||||
sys.path.append('J:\\Softwareprojekte\\Polytrader\\venv\\Lib\\site-packages')
|
||||
from py_clob_client.signing.eip712 import get_clob_auth_domain, MSG_TO_SIGN
|
||||
from py_clob_client.signing.model import ClobAuth
|
||||
from eth_utils import keccak
|
||||
|
||||
domain = get_clob_auth_domain(137)
|
||||
target_msg_hash = bytes.fromhex("68eff3a266838ca5dd9049f4dba0b95170871d2a1a16478443df0515e5c3f606")
|
||||
|
||||
# The timestamp of the log was 16:06:52. Let's guess unix time for 2026-03-26.
|
||||
# Let's just brute force a wide range of timestamps.
|
||||
# 2026-03-26 15:00:00 UTC is ~1774537200
|
||||
base = 1774537200
|
||||
|
||||
found = False
|
||||
for t in range(base - 10000, base + 10000):
|
||||
clob_auth_msg = ClobAuth(
|
||||
address="0x628914CF1e96A9D1Ab8F0489A9f64be5633bac41",
|
||||
timestamp=str(t),
|
||||
nonce=0,
|
||||
message=MSG_TO_SIGN,
|
||||
)
|
||||
# The message hash is the keccak hash of the ABI encoded ClobAuth type struct.
|
||||
# signable_bytes returns 1901 + domainHash + messageHash
|
||||
signable = clob_auth_msg.signable_bytes(domain)
|
||||
# the last 32 bytes is the message Hash
|
||||
msg_hash = signable[34:]
|
||||
if msg_hash == target_msg_hash:
|
||||
print("MATCH FOUND FOR TIMESTAMP:", t)
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
print("NO MATCH FOUND.")
|
||||
@@ -0,0 +1,16 @@
|
||||
import sys
|
||||
import datetime
|
||||
sys.path.append('J:\\Softwareprojekte\\Polytrader\\venv\\Lib\\site-packages')
|
||||
from py_clob_client.signer import Signer
|
||||
from py_clob_client.signing.eip712 import sign_clob_auth_message
|
||||
|
||||
signer = Signer("425454f8eef01dc6d4effeec1a9587f5969b53c18c7c9e621da73b9e80effd60", 137)
|
||||
target_sig = "0x3c4f2c1cbede3e423c265a90cfc32e37c2336e95fc4aa92e82081c96bcf518295893c4e65f0c2ae6e414210815e37f40200a4b5cad0104c0f71de5551297fd5d1c"
|
||||
|
||||
sig = sign_clob_auth_message(signer, 1774537612, 0)
|
||||
print("PYTHON SIG: " + sig)
|
||||
print("CSHARP SIG: " + target_sig)
|
||||
if sig == target_sig:
|
||||
print("THEY ARE IDENTICAL!!")
|
||||
else:
|
||||
print("THE ECDSA OUTPUT DIFFERS!!")
|
||||
@@ -0,0 +1,105 @@
|
||||
// File: hash_test.csx
|
||||
#r "nuget: Nethereum.Signer, 4.22.0"
|
||||
#r "nuget: Nethereum.ABI, 4.22.0"
|
||||
#r "nuget: Nethereum.Hex, 4.22.0"
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Nethereum.Signer.EIP712;
|
||||
using Nethereum.Signer;
|
||||
using Nethereum.ABI.FunctionEncoding.Attributes;
|
||||
|
||||
[Struct("EIP712Domain")]
|
||||
public class CtfDomain
|
||||
{
|
||||
[Parameter("string", "name", 1)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Parameter("string", "version", 2)]
|
||||
public string Version { get; set; }
|
||||
|
||||
[Parameter("uint256", "chainId", 3)]
|
||||
public ulong ChainId { get; set; }
|
||||
|
||||
[Parameter("address", "verifyingContract", 4)]
|
||||
public string VerifyingContract { get; set; }
|
||||
}
|
||||
|
||||
[Struct("Order")]
|
||||
public class CtfOrder
|
||||
{
|
||||
[Parameter("uint256", "salt", 1)]
|
||||
public BigInteger Salt { get; set; }
|
||||
|
||||
[Parameter("address", "maker", 2)]
|
||||
public string Maker { get; set; }
|
||||
|
||||
[Parameter("address", "signer", 3)]
|
||||
public string Signer { get; set; }
|
||||
|
||||
[Parameter("address", "taker", 4)]
|
||||
public string Taker { get; set; }
|
||||
|
||||
[Parameter("uint256", "tokenId", 5)]
|
||||
public BigInteger TokenId { get; set; }
|
||||
|
||||
[Parameter("uint256", "makerAmount", 6)]
|
||||
public BigInteger MakerAmount { get; set; }
|
||||
|
||||
[Parameter("uint256", "takerAmount", 7)]
|
||||
public BigInteger TakerAmount { get; set; }
|
||||
|
||||
[Parameter("uint256", "expiration", 8)]
|
||||
public BigInteger Expiration { get; set; }
|
||||
|
||||
[Parameter("uint256", "nonce", 9)]
|
||||
public BigInteger Nonce { get; set; }
|
||||
|
||||
[Parameter("uint256", "feeRateBps", 10)]
|
||||
public BigInteger FeeRateBps { get; set; }
|
||||
|
||||
[Parameter("uint8", "side", 11)]
|
||||
public byte Side { get; set; }
|
||||
|
||||
[Parameter("uint8", "signatureType", 12)]
|
||||
public byte SignatureType { get; set; }
|
||||
}
|
||||
|
||||
var typedData = new TypedData<CtfDomain>
|
||||
{
|
||||
Domain = new CtfDomain
|
||||
{
|
||||
Name = "Polymarket CTF Exchange",
|
||||
Version = "1",
|
||||
ChainId = 137,
|
||||
VerifyingContract = "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E"
|
||||
},
|
||||
Types = Nethereum.ABI.EIP712.MemberDescriptionFactory.GetTypesMemberDescription(typeof(CtfDomain), typeof(CtfOrder)),
|
||||
PrimaryType = "Order"
|
||||
};
|
||||
|
||||
var ctfOrder = new CtfOrder
|
||||
{
|
||||
Salt = 17747015785747,
|
||||
Maker = "0x628914cf1e96a9d1ab8f0489a9f64be5633bac41",
|
||||
Signer = "0x883fe952a23bb68aab8832343d4bedde759b40ea",
|
||||
Taker = "0x0000000000000000000000000000000000000000",
|
||||
TokenId = BigInteger.Parse("54119275359569982132308633107899675342776540894581625713762792947175003762644"),
|
||||
MakerAmount = 999180,
|
||||
TakerAmount = 3660000,
|
||||
Expiration = 0,
|
||||
Nonce = 0,
|
||||
FeeRateBps = 0,
|
||||
Side = 0,
|
||||
SignatureType = 0
|
||||
};
|
||||
|
||||
string privKey = new string('1', 64);
|
||||
var eip712TypedDataSigner = new Eip712TypedDataSigner();
|
||||
var key = new EthECKey(privKey);
|
||||
|
||||
var hash = eip712TypedDataSigner.HashTypedDataV4(ctfOrder, typedData);
|
||||
var sig = eip712TypedDataSigner.SignTypedDataV4(ctfOrder, typedData, key);
|
||||
|
||||
Console.WriteLine("CS_STRUCT_HASH|" + Nethereum.Hex.HexConvertors.Extensions.HexByteConvertorExtensions.ToHex(hash, true));
|
||||
Console.WriteLine("CS_SIG|" + sig);
|
||||
@@ -0,0 +1,39 @@
|
||||
from eth_account import Account
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, "J:/Softwareprojekte/Polytrader/venv/Lib/site-packages")
|
||||
|
||||
from py_order_utils.builders.base_builder import BaseBuilder
|
||||
from py_order_utils.model.order import OrderData
|
||||
from py_order_utils.signer import Signer
|
||||
|
||||
order_json = '''{"salt":17747015785747,"maker":"0x628914cf1e96a9d1ab8f0489a9f64be5633bac41","signer":"0x883fe952a23bb68aab8832343d4bedde759b40ea","taker":"0x0000000000000000000000000000000000000000","tokenId":"54119275359569982132308633107899675342776540894581625713762792947175003762644","makerAmount":"999180","takerAmount":"3660000","expiration":"0","nonce":"0","feeRateBps":"0","side":"BUY","signatureType":0}'''
|
||||
|
||||
data = json.loads(order_json)
|
||||
data["side"] = 0 if data["side"] == "BUY" else 1
|
||||
|
||||
priv_key = "0x" + "1"*64
|
||||
signer = Signer(priv_key)
|
||||
|
||||
builder = BaseBuilder('0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E', 137, signer, lambda: 1)
|
||||
|
||||
from py_order_utils.model.order import Order
|
||||
order = Order(
|
||||
salt=int(data["salt"]),
|
||||
maker=data["maker"],
|
||||
signer=data["signer"],
|
||||
taker=data["taker"],
|
||||
tokenId=int(data["tokenId"]),
|
||||
makerAmount=int(data["makerAmount"]),
|
||||
takerAmount=int(data["takerAmount"]),
|
||||
expiration=int(data["expiration"]),
|
||||
nonce=int(data["nonce"]),
|
||||
feeRateBps=int(data["feeRateBps"]),
|
||||
side=int(data["side"]),
|
||||
signatureType=int(data["signatureType"])
|
||||
)
|
||||
|
||||
struct_hash = builder._create_struct_hash(order)
|
||||
print("PYTHON_STRUCT_HASH|" + struct_hash)
|
||||
print("PYTHON_SIG|" + signer.sign(struct_hash))
|
||||
Reference in New Issue
Block a user