- EIP-712 signed by the user against the vault’s
WithdrawERC20typed-data struct. - Compliance-screened (banned list, account restrictions, AML
screening of your wallet and the destination, amount). A banned or
AML-blocked destination, or a restriction that blocks withdrawals, is
refused on the spot: the response carries
status: "rejected"with acode(wallet_banned,aml_blocked,restriction_active) and no withdrawal is created. Other flags, and amounts above the auto-approve threshold, put the withdrawal inMLRO_REVIEWfor human compliance review. See what sends a withdrawal to review. - Backend co-signed with a second EIP-712 signature. Dual signatures are both required on-chain; neither party can move funds alone.
- Submitted on-chain by PredictStreet’s backend submitter (PredictStreet pays gas).
- Confirmed when the on-chain tx receipt is observed.
State machine
Withdrawal security
Two opt-in, per-wallet controls gate a withdrawal request before it enters the flow above (enforced when the platform enables withdrawal-security; SSO partners are exempt):- Address whitelist — once a
wallet has any whitelisted address, withdrawals are allowed only to listed
destinations (
403 withdrawal_address_not_whitelistedotherwise). No entries = unrestricted. - 2FA (TOTP) — once active, every
withdrawal must carry a
totpCode(403 totp_required/totp_invalidotherwise). Manage both under/api/me/withdrawal-security/*.
Typical timeline
- Happy path (no flag): under 10s from request to
CONFIRMEDon testnet; target < 60s on mainnet. - MLRO review path: a compliance decision, typically within 1
business day. If your signed deadline passes before the withdrawal
executes, it ends
EXPIREDand the amount is refunded.
User-visible balance effects
Partner & MM notes
Market makers running high withdrawal cadence should:- Withdrawals are not restricted to addresses that deposited before (see Deposit sources). To lock withdrawals to known destinations, use the address whitelist.
- Poll
GET /api/me/withdrawals/{id}for state transitions, or subscribe touser_activityon/ws/user(portfolio:read, noids), which pushes awithdrawal_<state>frame (for examplewithdrawal_requested,withdrawal_approved,withdrawal_flagged_for_review,withdrawal_submitted,withdrawal_rejected,withdrawal_cancelled) as the request moves through review and submission. The on-chain success is not auser_activityframe: it arrives aswithdrawal_confirmedonvault_activity(ids: [<your vault address>]).
Next
Dual-sig flow
Why two signatures, how the co-sign works.
EIP-712 struct
WithdrawERC20 struct + signing.
State machine
All states + transitions.
Deposit sources
Read-only list of the addresses that funded your vault.
Withdrawal 2FA
TOTP second factor on withdrawals.
Address whitelist
Restrict withdrawals to approved destinations.