Feature Request: Add Proxy Wallet Support (signature_type and funder) to py-builder-relayer-client
Summary
The Python py-builder-relayer-client does not support proxy wallet functionality (signature_type=2) that allows builders to execute transactions on behalf of users without requiring the user's private key. This feature exists in both the TypeScript builder-relayer-client and the Python py-clob-client, but is missing from the Python relayer client.
Current Behavior
The RelayClient.__init__() only accepts:
relayer_url
chain_id
private_key
builder_config
Current Python implementation:
# py_builder_relayer_client/client.py
class RelayClient:
def __init__(
self,
relayer_url,
chain_id: int,
private_key: str = None,
builder_config: BuilderConfig = None,
):
# ...
self.signer = Signer(private_key, chain_id) if private_key else None
This means:
- The Safe wallet address is always auto-derived from the
private_key using CREATE2
- There's no way to specify a custom Safe address or use a funder/proxy pattern
- Users MUST share their private key with the builder to trade
Expected Behavior
The Python relayer client should support the same proxy wallet pattern as:
- TypeScript builder-relayer-client (as shown in the docs)
- Python py-clob-client (already implemented)
TypeScript Implementation (Reference)
From the Builder Signing Server docs:
import { RelayClient } from "@polymarket/builder-relayer-client";
import { BuilderConfig } from "@polymarket/builder-signing-sdk";
const builderConfig = new BuilderConfig({
remoteBuilderConfig: {url: "http://localhost:3000/sign"}
});
const relayClient = new RelayClient(
relayerUrl,
chainId,
wallet, // Builder's wallet (proxy signer)
builderConfig
);
Python py-clob-client Implementation (Already Works)
# py-clob-client/py_clob_client/client.py (lines 108-138)
class ClobClient:
def __init__(
self,
host,
chain_id: int = None,
key: str = None,
creds: ApiCreds = None,
signature_type: int = None, # ✅ SUPPORTED
funder: str = None, # ✅ SUPPORTED
builder_config: BuilderConfig = None,
):
# ...
if self.signer:
self.builder = OrderBuilder(
self.signer, sig_type=signature_type, funder=funder
)
Proposed Solution
Add signature_type and funder parameters to RelayClient:
# Proposed change to py_builder_relayer_client/client.py
class RelayClient:
def __init__(
self,
relayer_url,
chain_id: int,
private_key: str = None,
builder_config: BuilderConfig = None,
signature_type: int = 0, # NEW: 0=EOA, 1=Email/Magic, 2=Proxy
funder: str = None, # NEW: Client's EOA for proxy wallets
):
self.relayer_url = (
relayer_url[0:-1] if relayer_url.endswith("/") else relayer_url
)
self.chain_id = chain_id
self.contract_config = get_contract_config(chain_id)
self.signature_type = signature_type
self.funder = funder
self.signer = None
if private_key is not None:
self.signer = Signer(private_key, chain_id)
self.builder_config = None
if builder_config is not None:
self.builder_config = builder_config
self.logger = logging.getLogger(self.__class__.__name__)
Additionally, the derive() function and execute() method would need to be updated to use the funder address instead of the signer's address when signature_type=2.
Use Case
Scenario: A builder (trading service) wants to execute trades for their users without collecting private keys.
With current implementation: ❌ Impossible - must use auto-derived Safe
With proxy wallet support: ✅
# Builder's private key (not the user's!)
service_pk = os.getenv("SERVICE_PK")
# User's EOA address (owns their Safe wallet)
user_eoa = "0x8E9c68Ae342CF4cC5a888BC99686590014DA3719"
# User's existing Safe wallet
user_safe = "0xdF15830e070437f4593e1F7d5Fe32F2ec388319C"
builder_config = BuilderConfig(
local_builder_creds=BuilderApiKeyCreds(
key=os.getenv("BUILDER_API_KEY"),
secret=os.getenv("BUILDER_SECRET"),
passphrase=os.getenv("BUILDER_PASS_PHRASE"),
)
)
client = RelayClient(
relayer_url="https://relayer-v2.polymarket.com/",
chain_id=137,
private_key=service_pk, # Builder's PK
builder_config=builder_config,
signature_type=2, # Proxy wallet
funder=user_eoa, # User's EOA (doesn't share PK)
)
# Execute trade on user's Safe with Builder attribution
resp = client.execute([approve_txn, split_txn], "10 USDC BTC Trade")
Additional Context
- This feature is critical for builders who want to provide custodial trading services
- The py-clob-client already implements this correctly for orderbook trading
- The TypeScript relayer client supports this pattern
- Without this, builders must either:
- Collect user private keys (security risk)
- Have users transfer funds to builder-controlled Safes (poor UX)
- Only use orderbook trading via CLOB client (limited functionality)
Files to Modify
py_builder_relayer_client/client.py - Add parameters to __init__ and execute()
py_builder_relayer_client/builder/safe.py - Update to use funder for Safe derivation
py_builder_relayer_client/signer.py - May need updates for proxy signature handling
References
Feature Request: Add Proxy Wallet Support (signature_type and funder) to py-builder-relayer-client
Summary
The Python
py-builder-relayer-clientdoes not support proxy wallet functionality (signature_type=2) that allows builders to execute transactions on behalf of users without requiring the user's private key. This feature exists in both the TypeScriptbuilder-relayer-clientand the Pythonpy-clob-client, but is missing from the Python relayer client.Current Behavior
The
RelayClient.__init__()only accepts:relayer_urlchain_idprivate_keybuilder_configCurrent Python implementation:
This means:
private_keyusing CREATE2Expected Behavior
The Python relayer client should support the same proxy wallet pattern as:
TypeScript Implementation (Reference)
From the Builder Signing Server docs:
Python py-clob-client Implementation (Already Works)
Proposed Solution
Add
signature_typeandfunderparameters toRelayClient:Additionally, the
derive()function andexecute()method would need to be updated to use thefunderaddress instead of the signer's address whensignature_type=2.Use Case
Scenario: A builder (trading service) wants to execute trades for their users without collecting private keys.
With current implementation: ❌ Impossible - must use auto-derived Safe
With proxy wallet support: ✅
Additional Context
Files to Modify
py_builder_relayer_client/client.py- Add parameters to__init__andexecute()py_builder_relayer_client/builder/safe.py- Update to use funder for Safe derivationpy_builder_relayer_client/signer.py- May need updates for proxy signature handlingReferences