Status: BLOCKED — every item below depends on deployed Base Sepolia addresses and/or a live gateway. Nothing here fakes success today; each entry is honest-gated. When the deployed addresses are pasted, this unit wires and proves them at the next slice boundary.
Items bundled: D2 (real swap execution) · D3 (real recovery tx) · M5 (governance vote submission — client call is pre-written and live-capable once the gateway is deployed) · M6 (batch EAS attestation writes) · M7 (dispute file/vote/claim) · D4 (EAS resolver/read verification).
| Piece | Where | State |
|---|---|---|
Swap route/execute request builders on the real gateway contract (token_in/token_out/amount, wallet/route_id) |
Services/SwapService.swift |
done, envelope-decoded; execute unreachable from UI until this unit fires |
Governance vote builder (proposal_id, voter, support) + server support→choice kwarg fix |
Services/GovernanceService.swift + DAOView.castVote; 0pnMatrx gateway/service_routes.py |
vote SUBMISSION correct; DAO proposals live-read BLOCKED on a shape-matching route (see below) |
Adversarial-verify remediation: paymaster ReentrancyGuard + NaN-stake guard + appeal-clears-claims + juror party-exclusion + 4 client fake-success theaters killed |
multiple | done, gated |
| Dispute file/vote/claim builders on the real contracts | Services/DisputeService.swift |
done, envelope-decoded |
Dispute server routes POST /api/v1/dispute/vote + /claim + service methods (juror-panel-enforced vote; idempotent post-resolution claim; platform holds no funds) |
0pnMatrx gateway/service_routes.py, runtime/.../dispute_resolution/service.py |
done, 8 tests green |
| Dispute file handler kwarg fix (was a guaranteed TypeError 500) | 0pnMatrx gateway/service_routes.py |
done |
| Client EAS schema-UID slot | Config/PendingCredentials.swift Attestation.schemaUID |
done (empty, fails closed) |
| Server EAS example fixed to the Base predeploy + chain-specific warning | 0pnMatrx openmatrix.config.json.example |
done |
- D2 — flip SwapView's Confirm from the honest notice to
SwapService.executeSwap(routeId:)using the server-issued route id; remove the hardcoded fee/route rows (SwapView.swift:567-569). NOTE: on-chain DEX execution viaComponents.dexstays legally blocked — the gateway path is the only sanctioned route. - D3 — replace
WalletCreation.setupRecovery's honest failure (WalletCreation.swift:707-717) with a real guardian-registration write viaWalletTransactionService.submitCall; the rotation path (performGuardianRecovery→rotateOwner(bytes)) is already real and gated onRecovery.socialRecoveryModuleAddress. The deployed module's ABI must exposerotateOwner(bytes). - M6 — implement
encodeMultiAttestRequestinEASManager(ABI:multiAttest((bytes32,(address,uint64,bool,bytes32,bytes,uint256)[])[]), selector0x44adc90e), mirroring the existing single-attestencodeAttestRequest+ ERC-4337 submit; schema fromPendingCredentials.Attestation.schemaUID(empty → honest failure stays). - D4 — implement
getAttestation(bytes32)/ SchemaRegistrygetSchema(bytes32)as read-onlyeth_calls via the existing BaseNetwork JSON-RPC layer (needs onlyNetwork.rpcURL); then the resolver branch ofverifyWithResolverresolves instead of honest-failing. EAS addresses are the Base predeploys already hardcoded (0x4200…0021/0x4200…0020). - M5/M7 UI — flip
GovernanceView.confirmVoteandDisputeViewsubmit/vote/claim from honest notices to the pre-written service calls (all gated onisBackendConfigured). - Runtime shape verification — the typed decodes (SwapQuote, feed, staking, portfolio) intentionally throw on mismatch; verify against the live gateway and adjust models. Until then mismatches remain honest demo-fallbacks.
MTRX Config/PendingCredentials.swift:
| Field | For | Format |
|---|---|---|
Network.rpcURL |
everything on-chain (D2-on-chain/D3/M6/D4) | https URL |
AccountAbstraction.bundlerURL |
4337 submits (D3, M6) | https URL |
AccountAbstraction.entryPointAddress |
4337 | 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 (v0.6 canonical) |
AccountAbstraction.accountFactoryAddress |
4337 | deployed OpenMatrixAccountFactory |
AccountAbstraction.paymasterAddress |
sponsored gas | deployed OpenMatrixVerifyingPaymaster |
AccountAbstraction.paymasterSignatureEndpoint |
sponsored gas | gateway /api/v1/paymaster/sign URL |
Recovery.socialRecoveryModuleAddress |
D3 | deployed recovery module (must expose rotateOwner(bytes)) |
Attestation.schemaUID |
M6/D4 | 0x + 64 hex, same as server schemas.primary |
Backend.gatewayURL |
D2-gateway, M5, M7, all remapped reads | deployed 0pnMatrx gateway URL |
Components.dex |
D2 on-chain (LEGALLY BLOCKED — leave empty for MVP) | — |
0pnMatrx openmatrix.config.json (server):
| Key | For |
|---|---|
blockchain.rpc_url, blockchain.chain_id (84532) |
chain reads/writes |
blockchain.eas_contract (Base predeploy 0x4200…0021) + blockchain.schemas.primary/identity/payments |
server EAS writes; must match the client schemaUID |
blockchain.paymaster.{address, signer_key, bundler_url, entry_point, account_factory, policy} |
/api/v1/paymaster/sign (503 until set) |
blockchain.price_feeds.eth_usd |
Chainlink-primary price route |
- DAO proposals live-read (M5 read side) — ✅ RESOLVED (2026-07-03). Added
GET /api/v1/governance/daos/{daoId}/proposals→_call→governance.list_proposals_detailed, which emits exactly the client'sProposalshape (proposal_id/title/description/status/votes_for/votes_against/ quorum/end_time, end_time ISO-8601). ClientGovernanceService.getProposalsnow uses that path viagetEnveloped. Tally + quorum are extracted server-side (voting-model knowledge stays on the server); unknown tallies are an honest 0.0. 2 gateway tests green. Independent of deploy — the DAO tab read side is unblocked now. sponsoredCallWithValue(contract) — ✅ RESOLVED (2026-07-03).OpenMatrixPaymasternow constrains non-owner AGENT value-calls with a per-agent daily cap (agentDailyCap, wei) AND an optional target allowlist (targetAllowlistEnabled+allowedTargets), mirroring the server paymasterpolicy.allowed_actions. Secure by default: the cap is 0, so a compromised/authorized agent key cannot move any value until the owner grants a daily allowance; the owner is unrestricted. 6 new forge tests (blocked-by-default / within-cap / cumulative-cap / daily-reset / allowlist / owner-unrestricted); full paymaster suite 21 green. Written + tested now; ships with the Part-3 deploy.
Byte-exact digest cross-test stays green; forge suites green; a testnet UserOp per flow (D2 gateway swap, D3 rotation, M6 batch attest) each verified by reading the resulting state/attestation back from chain — no submit-and-assume.
Legs wired to real paths during Phases 1–5 of the loop build-out. All are
honest-gated (isBackendConfigured / isGasSponsorshipConfigured / deployed
addresses) and stay dormant until the deploy-wall keys below are filled — so the
shipping app is unchanged.
| Leg | Where | Fires when |
|---|---|---|
P5-2 gas-sponsorship splice — requestPaymasterAndData → fold paymasterAndData into the op before signing |
Core/Blockchain/BlockchainBridge.swift sendTransaction; ERC4337Manager.withPaymasterAndData |
isGasSponsorshipConfigured (bundler + paymaster address + paymaster-sign endpoint) |
P3 NFT mint — real POST /api/v1/nft/mint, success gated on the server result |
UI/Views/NFT/MintNFTView.swift |
isBackendConfigured |
P3 IP register / issue-license — real POST /api/v1/licensing/ip · /licenses (paths corrected to /api/v1) |
UI/Views/Licensing/LicensingView.swift, Services/LicensingService.swift |
isBackendConfigured |
P1-2 Oracle/Compute/Portfolio client paths corrected to /api/v1 |
Services/{Oracle,Compute,Portfolio}Service.swift |
isBackendConfigured (some routes are P2 501s → demo fallback) |
Server-side legs that are live now (no deploy dependency): P1-1 gateway
routing fixes, P2 route completion (42 legs; 5 WIRE, 37 honest-501), P4 ripple
emission (feed.ripple on every executed non-privacy action), P5-1 governance
vote identity binding.
Paste these into Config/PendingCredentials.swift (and the gateway config)
after deploying to Base Sepolia. Until then every dependent leg fails honestly.
Chain / ERC-4337 (unblocks sends, sponsorship, recovery):
Network.rpcURL, Network.webSocketURL, Network.gatewayURL,
AccountAbstraction.bundlerURL, AccountAbstraction.entryPointAddress,
AccountAbstraction.accountFactoryAddress,
AccountAbstraction.paymasterAddress,
AccountAbstraction.paymasterSignatureEndpoint,
Recovery.socialRecoveryModuleAddress
Attestation / Oracle: Attestation.schemaUID, Oracle.ethUsdSource
30 component contract addresses (Contracts.*): contractConversion,
deFiLending, nft, rwa, identity, dao, stablecoin, attestation, agentIdentity,
agenticPayments, oracle, supplyChain, insurance, gaming, ip, staking, payments,
securities, governance, dashboard, dex, fundraising, loyalty, marketplace, …
Payments (optional, App Store): Payments.applePayMerchantID,
Payments.applePayProcessorChargeURL
STOP. No further chain-dependent wiring can be proven without these addresses. This is the sanctioned Phase-6 deploy wall.