Skip to content

Design: Flutter Polymarket Deposit Wallet

Status: Designed; plan written; paused on Flutter WIP. Source: docs/superpowers/specs/2026-05-07-flutter-polymarket-deposit-wallet-design.md. User-facing reference: Polymarket Deposit Wallet.

Polymarket announced (May 2026) that new API users must trade through a relayer-deployed deposit wallet (CREATE2 contract) instead of a raw EOA. Existing Magic / proxy / Safe users are unaffected. The Polymarket flow has six steps; this slice covers the first four — derive address, deploy via WALLET-CREATE, hand off pUSD funding to the user, and submit the standard six-call approval batch via WALLET. Trading itself (CLOB orders with signature_type=3 / POLY_1271 / ERC-7739) is the next slice.

The Flutter app implements the flow standalone: no server-arenaton involvement, direct calls to relayer-v2.polymarket.com. polygolem serves as the canonical Go reference; the Dart code mirrors its internal/wallet/derive.go and internal/relayer/{client.go,signing.go,approvals.go} shapes file-for-file. Cross-language correctness is verified by golden tests against polygolem’s known-good outputs.

The Dart code is organized to mirror polygolem layer-for-layer so cross-language parity is auditable.

arenaton-flutter/lib/
├── config/
│ └── polymarket_environment.dart # relayer URL, factory, addresses, chainId
├── models/polymarket/
│ ├── deposit_wallet_state.dart # state enum + persistence record
│ └── relayer_transaction.dart # mirror of polygolem/internal/relayer/types.go
├── services/polymarket/
│ ├── polymarket_wallet_derivation.dart # mirror of internal/wallet/derive.go + auth/signer.go
│ ├── polymarket_calldata.dart # mirror of internal/relayer/approvals.go
│ ├── polymarket_typed_data.dart # mirror of internal/relayer/signing.go
│ └── polymarket_relayer_service.dart # mirror of internal/relayer/client.go
├── controllers/
│ └── polymarket_setup_controller.dart # state machine, Reown bridge, persistence
└── widgets/settings/
└── polymarket_setup_card.dart # the only UI surface
notStarted → addressReady → deploying → deployed → approving → ready
error ← any failure (retryable | not)

Each per-EOA record is persisted in flutter_secure_storage at key arenaton.polymarket.setup.<eoaLowercase>. Switching the active EOA in the wallet UI rehydrates the new EOA’s record without mutating the previous one.

Three golden tests lock the Dart implementation byte-for-byte to polygolem:

TestAsserts
polymarket_wallet_derivation_testEOA 0x2c75…65c23 derives to 0xfd5041…fa3cf9c (matches polygolem auth_test.go:113).
polymarket_calldata_testThe 6-call approval batch has the exact ordering and bytes polygolem’s BuildApprovalCalls() produces.
polymarket_typed_data_testThe EIP-712 envelope (domain, types, primaryType) matches polygolem’s depositBatchTypes() and depositBatchDomain().

If polygolem ever changes its derivation or typed-data builder, the Dart goldens will break — that’s the intended failure mode.

Mirrors polygolem internal/auth/signer.go and internal/relayer/approvals.go:

factory = 0x00000000000Fb5C9ADea0298D729A0CB3823Cc07
impl = 0x58CA52ebe0DadfdF531Cde7062e76746de4Db1eB
depositCloneC2 = 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076
depositCloneC1 = 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3
prefix = 0x61 0x00 (0x3d + len(args)) 0x3d 0x81 0x60 0x23 0x3d 0x39 0x73
pUSD = 0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB
CTF = 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045
ctfExchangeV2 = 0xE111180000d2663C0091e4f400237545B87B996B
negRiskV2 = 0xe2222d279d744050d28e00520010520000310F59
negRiskAdptV2 = 0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296
relayerProd = https://relayer-v2.polymarket.com
relayerPreprod = https://relayer-v2-preprod-int.polymarket.com
  • No CLOB order placement (signature_type=3 / POLY_1271 / ERC-7739) — separate slice.
  • No server-arenaton changes — Flutter standalone.
  • No polygolem changes — read-only reference.
  • No in-app pUSD funding — funding is fully external.
  • No multi-chain — Polygon mainnet only.
  • No support for Magic / browser / Safe accounts — existing users unaffected.
  • Cross-language drift. Mitigated by golden tests on the Dart side; polygolem has its own Go tests.
  • Polymarket API change. Addresses live in a single config file; no mid-flow auto-failover.
  • Reown popup latency. Relayer rejects expired deadlines; user retries with a fresh nonce.
  • User funds the wrong address. Funding panel emphasizes the deposit-wallet hex and labels it as different from the owner EOA.