Two account kinds
Every Polymarket user controls exactly one of two on-chain account types, depending on when their Polymarket account was created.A deployed DepositWallet always takes priority. Only fall back to the Safe proxy if no DepositWallet is deployed for the EOA.
Resolving the wallet
Resolution is deterministic from the EOA — both addresses are derivable off-chain, then you confirm which is actually deployed on-chain.1
Derive and check the DepositWallet
Derive the EOA’s DepositWallet address through the Polymarket relay client (
deriveDepositWalletAddress), then ask the relay client whether it is deployed (getDeployed(address, "WALLET")). Both calls are read-only and prompt no signature.2
Fall back to the Safe proxy
If no DepositWallet is deployed, compute the Safe proxy address from Polymarket’s Safe proxy factory (
computeProxyAddress(eoa)) and check that the address has bytecode on-chain (getCode returns more than 0x).3
Handle the unresolved case
If neither is deployed, the EOA has no Polymarket account yet. The user must transact on Polymarket once to deploy their wallet.
Transaction transport per kind
The resolved kind also decides how you submit deposits and withdrawals. Both kinds support deposit and withdraw, only the transport and the available deposit flow differ.
Both transports accept the same shape of batched call (
{ to, value, data }), so you can build the call list once and dispatch it through whichever transport the resolved kind requires.
Robin does not sponsor gas
Reference implementation
The runnableresolveWallet() and executeViaWallet() helpers live in src/wallet.ts of the robin-markets-integration example repo. They cover both kinds end to end — DepositWallet derivation, the deployment checks, the Safe protocol-kit path, and the relayer batch.
Next steps
Deposits
Build pull and push deposits for the wallet kind you resolved.
Withdrawals
Burn shares and reclaim outcome tokens plus organic yield.