feat(relayer): add relayer service for user vault execution
This commit is contained in:
@@ -47,7 +47,7 @@ class TradingService:
|
||||
order_id = str(uuid.uuid4())
|
||||
fee = amount * Decimal("0.006") # 0.6% protocol fee
|
||||
|
||||
# 1. 记账并扣款/冻结
|
||||
# 1. 记账并扣款/冻结 (若提供 vault_address 则关联金库)
|
||||
await self.ledger_service.record_trade(
|
||||
address=user_address,
|
||||
market_address=market_address,
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import logging
|
||||
from decimal import Decimal
|
||||
from typing import Optional, Dict, Any
|
||||
from web3 import AsyncWeb3, AsyncHTTPProvider
|
||||
from eth_account import Account
|
||||
from app.config import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class RelayerService:
|
||||
"""
|
||||
【WTFX Relayer 链上代付撮合服务】
|
||||
代表持有 Session Key 授权的用户,将其交易免 Gas 费提交至链上执行
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.w3 = AsyncWeb3(AsyncHTTPProvider(settings.ROBINHOOD_TESTNET_RPC))
|
||||
# 管理员/Relayer 私钥
|
||||
self.relayer_private_key = "0x02aef1247dbddab8e8d6b0962f086f47874626e94988541ca21c9c2ea2475e62"
|
||||
self.relayer_account = Account.from_key(self.relayer_private_key)
|
||||
|
||||
async def execute_vault_transaction(
|
||||
self,
|
||||
vault_address: str,
|
||||
target_market: str,
|
||||
call_data: str,
|
||||
value: int = 0
|
||||
) -> str:
|
||||
"""
|
||||
通过 Relayer 调用用户 Vault 的 execute() 函数
|
||||
"""
|
||||
try:
|
||||
vault_checksum = self.w3.to_checksum_address(vault_address)
|
||||
target_checksum = self.w3.to_checksum_address(target_market)
|
||||
|
||||
# 构建 execute(address target, uint256 value, bytes calldata data) ABI 调用
|
||||
execute_abi = [{
|
||||
"inputs": [
|
||||
{"name": "target", "type": "address"},
|
||||
{"name": "value", "type": "uint256"},
|
||||
{"name": "data", "type": "bytes"}
|
||||
],
|
||||
"name": "execute",
|
||||
"outputs": [{"name": "", "type": "bytes"}],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
}]
|
||||
|
||||
vault_contract = self.w3.eth.contract(address=vault_checksum, abi=execute_abi)
|
||||
nonce = await self.w3.eth.get_transaction_count(self.relayer_account.address)
|
||||
gas_price = await self.w3.eth.gas_price
|
||||
|
||||
data_bytes = bytes.fromhex(call_data[2:]) if call_data.startswith("0x") else bytes.fromhex(call_data)
|
||||
|
||||
tx = await vault_contract.functions.execute(
|
||||
target_checksum,
|
||||
value,
|
||||
data_bytes
|
||||
).build_transaction({
|
||||
"from": self.relayer_account.address,
|
||||
"nonce": nonce,
|
||||
"gasPrice": gas_price,
|
||||
"chainId": 46630
|
||||
})
|
||||
|
||||
signed_tx = self.relayer_account.sign_transaction(tx)
|
||||
tx_hash = await self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
|
||||
logger.info(f"Relayer tx submitted: {tx_hash.hex()} for Vault {vault_address}")
|
||||
return tx_hash.hex()
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to execute relayer tx: {e}")
|
||||
raise e
|
||||
|
||||
relayer_service = RelayerService()
|
||||
@@ -52,10 +52,12 @@ class MarketDTO(BaseModel):
|
||||
|
||||
class CreateOrderRequest(BaseModel):
|
||||
market_address: str
|
||||
vault_address: Optional[str] = None
|
||||
outcome_index: int = Field(..., ge=0, le=7)
|
||||
side: str = Field(..., pattern="^(BUY|SELL)$")
|
||||
amount: Decimal = Field(..., gt=0)
|
||||
price: Optional[Decimal] = None
|
||||
session_signature: Optional[str] = None
|
||||
|
||||
class OrderDTO(BaseModel):
|
||||
order_id: str
|
||||
|
||||
Reference in New Issue
Block a user