UmiaUmia Docs

Reclaim zkTLS Integration

End-to-end architecture, privacy model, sybil resistance, and CCA behavior for Umia's Reclaim integration

This page is the implementation-level companion to Umia zkTLS Extension. It explains how Umia integrates Reclaim proofs into Tailored Auctions, how the privacy model works in practice, how sybil resistance is enforced, and what this changes for the Continuous Clearing Auction (CCA).

Why We Use Reclaim

Tailored Auctions need a way to make statements like "this round is for GitHub contributors" or "this bucket is for a specific community" without turning the auction into a centralized KYC flow.

Reclaim gives Umia a way to:

  • gate early auction steps by offchain credentials;
  • bind a proof to the bidder's wallet so it cannot be replayed by someone else;
  • preserve public onchain execution of the auction itself;
  • add provider-scoped sybil resistance for gated rounds;
  • keep the CCA's price discovery and settlement logic unchanged.

What Umia Actually Integrates

At a high level, Umia combines five layers:

LayerRole
Reclaim provider + witnessesProduce and attest to a zkTLS proof about some offchain account or activity
Umia docs/hub frontendRequests proofs, stores them locally, and attaches them to bids as hookData
Umia APICreates proof-request configs, verifies proofs off-chain, stores proofs, computes identity hashes, and serves eligibility
UmiaValidationHookVerifies wallet binding, provider compatibility, monotonic eligibility, and on-chain identity ownership
CCA / Validation RouterCalls the hook on every bid; accepts or rejects the bid based on verification state

The important design choice is that Reclaim is the proof system, while Umia is the auction-specific policy layer. Reclaim proves something about offchain data. Umia decides which proofs are accepted for which auction step and how that affects bid eligibility.

Architecture Diagram

Architecture diagram for the Umia Reclaim zkTLS integration

Founder and CLI configure the validation hook and CCA. The Hub UI talks to the API and Reclaim extension. Bid submissions go through the CCA into the validation hook, which checks Reclaim proofs and identity ownership.

Umia Reclaim Integration Architecture

Reclaim produces the proof, Umia applies auction policy, and the validation hook enforces it at bid admission time.

Founder / Ops

Defines lock requirements, provider IDs, and provider hashes per step

Umia CLI / Deploy Flow

Deploys the hook, pairs it to the auction, and enables step-level providers

UmiaValidationHook

Wallet binding, provider checks,

monotonic registration, identity gate

ValidationRouter

Points the auction at the active hook

Continuous Clearing Auction

Normal CCA pricing, clearing, and settlement

with gated bid admission

Reclaim Verifier Contract

Checks witness signatures and proof validity

Umia Hub UI

Requests proof configs, stores proofs locally,

and submits bids with hookData

Umia API + DB

Eligibility, proof-request config, proof storage,

identityHash, permit wallets, hook metadata

Reclaim Browser Extension

Runs the provider verification flow in the user session

Offchain Provider

GitHub, token source, reputation system, etc.

configure auction policydeploy + enableStepBatchregister active hookpair to auctionhook selectedvalidate(hookData)verifyProof(...)eligibility + proof APIsproof request / proof resultprovider verification flowsubmitBid(..., hookData)optional pre-submit / backend policy checks

Sequence Diagram

Sequence diagram for the Umia Reclaim zkTLS verification flow

The user opens the Hub, the Hub fetches eligibility, requests a Reclaim proof config, receives a proof from the extension, stores it via the API, and later submits a bid whose hookData is validated by the CCA and validation hook.

Proof and Bid Admission Sequence

The off-chain proof flow reduces wasted transactions, but the final admit / reject decision still happens in the validation hook during the bid transaction.

Userwallet holderHub UIfrontendUmia APIeligibility + storageReclaim Extensionbrowser verifierProviderGitHub, token, etc.CCAsubmitBidValidation Hookpolicy enforcementReclaimverify1open gated auction2GET eligibility(auction, wallet)3requirements, current step, proof / permit state4click Verify5POST /proof-request6serialized config with wallet context7start verification in extension8provider proof flow9proof material10Reclaim proof11POST /verify with proofAPI checksproviderHashwallet contextidentityHash + storage12verifiedFromStep / conflict / error13place bid14submitBid(maxPrice, amount, owner, hookData)15validate(owner, hookData)verifyProof(...)Hook logicresolve current stepcheck provider setclaim identity slotstore verifiedFromStep

Current default Hub flow

Today, the main user flow is: verify off-chain, store the proof in the backend, then send that proof inline in hookData when the user bids. The contract also supports permissionless pre-submission via submitProof(), and the keeper has a route for it, but that is not the primary Hub path right now.

How We Integrate Reclaim Into an Auction

1. We deploy and pair the hook

Each gated auction gets a UmiaValidationHook. The hook is paired to a single CCA via setCCA(address).

That pairing matters because the hook caches the CCA's step ranges and resolves the current step from block number during validate().

2. We configure allowed Reclaim providers per step

Auction steps are configured with Reclaim providerHash values, plus human-readable providerId labels for UI/indexing.

In practice, the CLI computes or accepts provider hashes and then calls:

  • enableStepBatch(stepIndices, providerHashesPerStep, providerIdsPerStep) during deployment;
  • addStepProviders(...) or setStepProviders(...) for later updates.

This is how a founder says, for example, "step 0 accepts GitHub provider X" while later steps may accept a broader or different set.

3. We expose readable requirements to the Hub

The API/indexer layer stores a human-readable description per provider and per step. That is what powers the lock-requirements UI in the Hub.

4. We mint proof requests server-side

The Hub never gets the Reclaim app secret directly.

Instead, the API creates the proof request using Reclaim credentials and returns a serialized config to the frontend. During that step, Umia binds the bidder wallet into the proof context:

ReclaimProofRequest.init(appId, appSecret, providerId)
proofRequest.setContext(walletAddress, "Auction verification")

That wallet binding is critical. It means the proof is not just "someone has this credential". It is "this credential was issued for this wallet context".

5. We verify off-chain before the user bids

When the extension returns a proof, the API validates the proof off-chain and applies Umia-specific policy checks:

  • the auction must actually use a zkTLS hook;
  • the requested step must be enabled;
  • the proof's providerHash must match one of the step's accepted providers;
  • the proof's contextAddress must equal the authenticated wallet;
  • the proof must pass Reclaim verification;
  • the proof is normalized to the earliest step that accepts that provider.

That last point is important for monotonic access. If a proof qualifies a user for an earlier locked step, Umia records the earliest valid step so later bids can reuse that stronger eligibility.

6. We store the proof and reuse it at bid time

After off-chain verification, the proof is stored in the API database and cached locally in the browser. On bid submission, the frontend prefers, in order:

  • an in-memory freshly verified proof;
  • a locally cached stored proof;
  • a backend-stored proof fetched for the wallet;
  • a server permit, if that step supports permits;
  • empty hookData if the wallet is already on-chain verified.

What Goes On-Chain

The bid path still ends at the CCA's normal submitBid(...) call, but now hookData may carry verification material.

For Reclaim proofs, Umia encodes:

hookData = abi.encodePacked(uint256 proofStep) ++ abi.encode(Reclaim.Proof)

The validation hook then:

  1. resolves the current auction step;
  2. checks whether that step is gated;
  3. checks whether the wallet is already verified from an earlier step;
  4. if not, decodes hookData and verifies the proof for proofStep;
  5. stores verifiedFromStep for monotonic access.

This means verification is part of bid admission, not part of price formation.

How This Affects CCA

Reclaim changes who can submit a valid bid in a given step, but it does not change the core economic mechanics of the auction.

CCA surfaceEffect of Reclaim integration
Bid entryA bid may require valid hookData before it is accepted
Clearing priceUnchanged
Fill logicUnchanged
Settlement and liquidity seedingUnchanged
Auction step timingSame CCA steps, but some steps are gated
User stateOnce verified from step N, the user stays eligible for N and later steps

In other words, Reclaim adds an admission-control layer around the auction. It does not fork or replace the CCA itself.

The Privacy Model in Practice

What is private

Umia does not require public KYC and does not need a real-world legal identity to gate an auction. The bidder proves eligibility through a signed Reclaim proof that is bound to their wallet.

What is intentionally bound

The wallet address is intentionally inserted into the proof context. That is how the system prevents replay across wallets.

What is not guaranteed by Umia alone

Privacy depends on what the Reclaim provider includes in the signed context and extractedParameters fields.

If the provider emits a privacy-preserving pseudonymous identifier, Umia can enforce one-wallet-per-identity without learning a raw username. If the provider emits a raw handle, then that handle may be present in the proof payload and privacy is correspondingly weaker.

Important privacy nuance

Umia's integration is privacy-preserving by architecture, but not magically data-free. The actual privacy level depends on provider design. The safest provider design is to expose only the minimum fields needed for wallet binding, provider selection, and sybil resistance.

The Privacy-Preserving OPRF Piece

The sybil-resistance design is built around a provider-scoped stable identity, represented in Umia as:

identityHash = keccak256(providerHash || extractedParameters_substring)

Two details matter here:

  • providerHash namespaces the identity by provider/version, so the same source account under two different providers does not collide;
  • extractedParameters_substring is taken verbatim from the signed Reclaim context both off-chain and on-chain, so both layers compute the same identityHash byte-for-byte.

Why this is useful:

  • if Reclaim provides an OPRF-derived pseudonymous identifier, the same real-world account maps to the same stable provider-scoped identity without exposing the raw account identifier;
  • Umia only needs the stable pseudonym to enforce one-wallet-per-identity;
  • the contract and API never need a traditional user database keyed by a Web2 username.

What Umia does not do is run the OPRF ceremony itself. Umia consumes the signed output that comes back inside the Reclaim proof context and then derives identityHash from it.

Sybil Resistance

Umia enforces sybil resistance in two places.

Off-chain gate

When the API stores a proof, it computes identityHash and tries to claim that identity for the current hook.

It uses:

  • a transaction-level advisory lock on (hookId, identityHash);
  • a unique database index on (hook_id, identity_hash);
  • same-wallet re-verification logic that replaces older proof rows.

If a different wallet already claimed that identity, the API rejects the proof with a conflict instead of letting the user proceed to bid.

On-chain gate

The validation hook independently enforces the same identity claim on-chain:

  • _identityToUser[providerHash][identityHash] stores the wallet that owns that provider-scoped identity;
  • first claim wins;
  • re-verification by the same wallet is idempotent;
  • a different wallet reverts with IdentityAlreadyClaimed(...).

This means the backend improves UX and reduces wasted bid attempts, while the contract remains the final enforcement layer.

Submission Modes

Umia supports three verification modes in the same hook:

ModeHow it worksTypical use
Pre-submitted Reclaim proofSomeone calls submitProof(user, stepIndex, proofData) before biddingRelayed or keeper-driven flow
Inline Reclaim proofBid carries proofStep + Reclaim.Proof in hookDataCurrent default Hub UX
Server permitBid carries an EIP-712 permit or user pre-submits oneAdmin-curated or fallback allowlists

The same auction can mix Reclaim steps and permit-enabled steps.

Why the Monotonic Model Matters

Verification is monotonic: if a wallet verifies for step 0, it is also valid for steps 1, 2, 3, and so on.

That matters because Tailored Auctions often want a funnel like:

  • early blocks reserved for a narrow cohort;
  • later blocks widened to a broader cohort;
  • final blocks fully open.

Without monotonic registration, users would need to re-prove eligibility at every step transition. With monotonic registration, one strong proof unlocks the rest of the auction path that should logically include that user.

Tradeoffs and Design Intent

This integration intentionally chooses:

  • on-chain enforcement over trust in the frontend;
  • wallet-bound proofs over reusable anonymous bearer credentials;
  • provider-scoped sybil resistance over fully open one-wallet-many-wallet behavior;
  • optional backend prechecks for UX, while keeping the contract as the source of truth.

The tradeoff is that privacy quality depends on provider design, and the first gated bid carries more verification data than a fully open bid.

Summary

Reclaim gives Umia a way to add offchain audience targeting to an otherwise fully onchain auction.

  • Reclaim proves eligibility.
  • Umia decides which providers are allowed for which auction steps.
  • The API binds proofs to wallets, stores proofs, and blocks obvious sybil reuse early.
  • The validation hook enforces the same rules on-chain during validate().
  • The CCA keeps its native auction mechanics; only bid admission changes.

For the user-facing overview, see Umia zkTLS Extension. For the contract-level interface, see Validation Hook.