Chapter 27 · Why Crypto Products Differ from Web2 Products
Why can crypto products not simply copy Web2 workflows?
- Capabilities practiced
- BuilderSystem ThinkingAI Literacy
- Hands on
- Capture each step of a dApp's first-use flow and mark exactly what every signature authorizes.
- AI Lab
- Have AI draft a feature PRD. Manually add the failure paths it missed: failed transactions, stalls, and front-running.
A Real-World Problem
Someone with eight years of Web2 product experience joins an on-chain team.
Their first assignment is simple: a one-click buy button that swaps stablecoins for another asset. They follow a familiar workflow—loading states, progress bars, success screens, retries, analytics, and A/B testing controls.
Two weeks after launch, support tickets and data reveal six problems:
- Some users click and nothing happens. Their wallet lacks the native token needed for gas: they can afford the purchase but cannot submit the transaction.
- Someone clicks three times. After forty seconds without a visible response, they assume it is stuck and click twice more. All three transactions execute on-chain.
- After seeing the success page, someone asks: “When can I cancel?”
- Someone sends to the wrong address and requests a refund from support.
- A wallet popup displays hexadecimal text. The user confirms it. Three weeks later, their money disappears: the confirmation granted an unlimited allowance.
- Someone complains: “The displayed price was 1.02, but I received 0.97.” The interface never explained what could happen in between.
Web2 has standard answers: balance checks, button debouncing, cancellation endpoints, support refunds, readable permission dialogs, and locked prices. None of those answers works here as assumed.
The problem is not a lack of skill. The familiar workflow rests on three assumptions, none of which holds on-chain.
This chapter asks: what are those assumptions, and what must change in product design when they disappear?
Thought Experiment
Do not consider all of crypto at once. Remove one assumption at a time and see what happens to the product.
Step one: remove undo from your product.
Do not hide the button. Make undo physically impossible. Once users confirm, it happens, and nobody can reverse it—including you, your database, or a court.
Several designs collapse:
- Confirmation changes from a formality into the main interface. In a reversible world it is courtesy; in an irreversible one it is the last defense.
- Support changes from solving problems to explaining them. Half your support scripts describe remedies. That half no longer applies.
- You cannot experiment on live traffic. Gradual rollout is a favorite Web2 tool: roll back if something breaks. Here, rollback cannot restore the affected users' lost money.
- Onboarding must happen beforehand. Users cannot try first and fix it later.
Step two: require users to produce a key and sign every action in person.
You do not hold this key and cannot act in their place or keep it for them. Every signature opens a wallet window containing text they probably do not understand, leaving them to decide whether to approve.
More assumptions collapse:
- Step count becomes a cost you must reduce. An extra Web2 step is a usability issue. An extra signature is a drop-off point plus a risk point.
- Your copy may not be what users see. The wallet renders the popup. You can influence it, but cannot control it.
- Remember my choice becomes extremely dangerous. On-chain, it can mean one approval, forever, with unlimited allowance.
Step three: let anyone connect another product to yours without telling you.
No application, contract, or permission is needed. They read your contract interface and write code to call it.
This step brings the greatest benefits and the greatest difficulties:
- Distribution can happen without you doing anything. Someone integrates you, and their users become yours.
- Your usage assumptions break. You expect a person, but receive a contract; you expect individual calls, but receive a hundred within one transaction.
- You cannot change interfaces unilaterally. Integrations break together, and you may not know who integrated you.
After these three steps, you are no longer holding Web2 with a blockchain added, but a product with entirely different constraints.
Your Decision
Design a specific feature: one-click reinvestment. Users have earned yield and want to put it back in. On-chain this requires three operations: claim, approve, and deposit.
What Happens
The four choices lead to one conclusion:
The difficulty of on-chain products lies in redrawn boundaries of state and trust, rather than the feature itself.
Many default Web2 designs rest on three implicit assumptions. Compare them with on-chain reality:
| Implicit Web2 assumption | On-chain reality | What the product must add |
|---|---|---|
| Mistakes can be corrected | Once confirmed, nobody can change it | Complete pre-confirmation information, simulation, and repeated amount/address checks |
| My server acts for the user | Every step requires the user's signature | Fewer signatures, readable explanations, and bounded permissions |
| I control my interfaces and users | Anyone can integrate; calls may come from contracts | Interface stability commitments, unusual-call handling, and composition checks |
| Request success means completion | Transactions have intermediate states and can be reorganized | A complete state machine and waiting-state copy |
| Users act for free | Every write costs money | Fee checks, explanations of failed-transaction fees, and sponsorship trade-offs |
Rows four and five are additional gaps that are easily missed.
Row four: Web2 requests succeed or fail, with loading as the intermediate state. An on-chain transaction may be signed but unbroadcast, waiting in the mempool, included but not finalized, or removed by a reorganization. Each means something different to users.
Row five: on-chain operations are not free. Trying something has a price, and pricing changes behavior: users hesitate, batch actions, or stay away when fees are high.
Build a Model
Three Non-Negotiable Constraints
- Irreversible
- Requires signatures
- Composable
| Constraint | What it removes | Designs it demands |
|---|---|---|
| Irreversible | Undo, refunds, rollback, and live rollout experiments | Earlier confirmation, simulation, limits, and allowlists |
| Requires signatures | Server actions on users' behalf and silent renewals | Fewer steps, readable explanations, bounded amounts and expiry |
| Composable | Control over callers and freedom to change interfaces | Stable interfaces, defensive assumptions, batch and contract-call handling |
The third is easily mistaken for a purely technical issue, but it is a positioning question. Composability means your product can be someone's entry point or someone's component. Entry points need usability; components need stable interfaces, clear documentation, and predictable behavior. Most teams do not choose clearly and end up doing neither well enough.
Six Transaction States
Product teams must internalize this state machine. Every box needs an interface and copy. Missing one leaves users to imagine what happened, usually the worst possibility.
- Constructing
- Awaiting signature
- Broadcast
- Awaiting confirmation
- Confirmed
- Final
| State | What users experience | Common product mistake |
|---|---|---|
| Constructing | The interface calculates amounts, routes, and fees | No explanation of why quoted and executed prices may differ |
| Awaiting signature | A wallet popup opens | No explanation of what this signature does |
| Broadcast | The transaction entered the network but is not included | No transaction receipt for users to inspect |
| Awaiting confirmation | Included, but not enough confirmations | Displaying success—the most expensive mistake |
| Confirmed | The confirmation threshold is reached | Not explaining the threshold |
| Final | Practically no longer changeable | Treating it as identical to the previous state |
State four deserves attention. Displaying success with insufficient confirmations promises something you cannot guarantee. Chapter 1 distinguished displayed receipt from completed settlement; on-chain, the product must express the gap.
Failure-Path Checklist
This is the table most worth taking away. Check every row when writing a PRD for a transaction feature:
| Failure | What users see | What the product should do |
|---|---|---|
| No native token for gas | Clicking does nothing | Check beforehand, explain what is missing and where to obtain it |
| Insufficient asset balance | A cryptic wallet error | Check beforehand and offer the available maximum in the input |
| Insufficient allowance | Failure, with fees still charged | Check allowances and explain approval versus execution |
| Slippage exceeds tolerance | Transaction reverts | Explain why and offer adjustment; do not increase it by default |
| Front-running | Execution worse than the quote | Explain price protection and quote expiry |
| Stuck in the mempool | Endless spinner | Give a transaction receipt, lookup link, and available actions |
| Contract execution fails midway | Failure without fee refund | Simulate beforehand, blocking certain failures before signing |
| User rejects in the wallet | Return to the original interface | Distinguish cancellation from failure instead of treating both as errors |
| Congestion and fee spikes | Long wait for inclusion | Show current fees and allow users to wait |
| Chain reorganization | A transaction shown as successful disappears | Exactly why state four must not say success |
Seven of these ten can be blocked before signing. One extra pre-signature check offers the highest return in on-chain product work: less drop-off, fewer losses, and fewer support requests.
Four Signature Types
A wallet confirmation can mean four entirely different things. Your interface must distinguish them because the wallet may not.
| Type | What it does | Reversible? | What the product must explain |
|---|---|---|---|
| Transfer signature | Sends assets away | No | Recipient, amount, and that the action ends here |
| Approval signature | Lets a contract use a particular asset | Yes, but requires active revocation | Amount, expiry, and whether the target contract is upgradeable |
| Message signature | Proves address control without an on-chain transaction or fee | Not applicable | It does not move funds—say so explicitly, or users may be afraid |
| Offline-order signature | Signs authorization someone else can execute on-chain | Depends on design | Expiry, permitted executors, and invalidation method |
The second is the entry to the “you signed it yourself” risk path in Chapter 24. Three concrete actions minimize it: approve only what is needed, set expiry, and provide a place to view and revoke past approvals.
The fourth is often misunderstood because it is free and off-chain, resembling a message signature. But it is executable authorization, and users do not choose when execution occurs. Any such feature must explain expiry and invalidation in its own interface.
What It Is Called
Users approve every operation your product initiates through an application you do not control.
This is a distinctive structure: your critical conversion step occurs in someone else's interface. You can explain the content on your side and reduce how often users must switch over.
Wallets differ enormously in display, support for limits and expiry, and interpretation of call data. Ask during design how the same instruction appears in three major wallets. T13 covers implementation differences.
Authorization of content with a private key—the only “I agree” in the on-chain world.
Three properties matter: it cannot be forged (only the key holder produces it), it cannot be denied (you cannot later claim you did not sign), and its effect depends on the content, not the setting (the same signature has the same effect elsewhere).
The third creates product risk: a user taught to approve every popup will carry that habit to phishing sites. Teaching users to read signatures is part of the product, not merely security education.
The fee users pay for the network to execute an operation.
Three properties reshape design: payment requires the native token (a newcomer holding only stablecoins cannot proceed), fees vary dramatically with congestion, and failed transactions also incur fees.
The third particularly needs product handling. Simulating and blocking a certain failure before signing saves both fees and frustration.
Some designs let others pay these fees, greatly reducing first-use friction. But the cost moves to the product provider and attracts addresses seeking to exploit it—the problem Chapter 28 examines.
The point at which a transaction is practically no longer changeable.
It is a curve, not a switch: more confirmations reduce the chance of change. Chains vary significantly (Chapter 8 compared them). Choose a threshold for your chain and tell users what it is.
The green success check should appear after your selected threshold, not merely upon inclusion in a block.
After confirmation, nobody can undo the action.
This is the product meaning of “more like cash” in Chapter 1. Cash handed over stays handed over; there is no support desk.
Its design requirement fits one sentence: move the effort Web2 spends after mistakes to before mistakes. Confirmation screens, checks, simulation, limits, and address verification become core functionality rather than optional polish.
Anyone can call your contracts and integrate your product without your approval.
Distribution can happen by itself: others integrate you, their users become yours, and you spend nothing. Chapter 9 described this distinctive smart-contract property.
The cost is losing three things: control over callers, freedom to change interfaces, and assumptions about usage. The third is dangerous: you expect people but receive contracts, or one call but receive a hundred in one transaction. Before encoding an assumption, ask whether it still holds when the caller is code.
Hands-on
The goal is to break the workflow into frames, not simply use the product. Go slowly and screenshot every step.
Prepare a new, clean wallet address, not your everyday wallet. Obtain a little native token from a testnet faucet. Choose a DApp you have never used.
Screenshot from the homepage through your first meaningful action.
Capture every screen, including loading states, errors, and wallet popups. Capture the whole wallet popup, including expandable sections.
Count total screens, screens requiring a decision, and signatures. These three numbers describe the product's first-use cost.
Analyze every signature popup using this table.
| Signature number | Wallet display | Which of the four types? | Allowance | Expiry | Explained in product UI? |
|---|---|---|---|---|---|
| 1 | |||||
| 2 |
Allowance is the key column. For approval signatures, check whether the requested amount matches the operation or is an enormous number. The latter means unlimited approval.
If the popup is unclear, copy its contents and inspect the contract and interface name in a block explorer. Repeating this builds intuition for common signature types.
Deliberately trigger three failures and screenshot each.
| Trigger | What to observe |
|---|---|
| Spend the native token, then initiate an operation | Does the product check beforehand? Is the message readable or an error code? |
| Enter more than your balance | Does validation happen during input or after signing? |
| Reject the wallet popup | Does the product distinguish user cancellation from transaction failure? |
The third reveals product maturity especially well. Reporting intentional cancellation as “Transaction failed, please retry” is common and harmful.
Record every state transition's timing.
Start timing at confirmation. Note the first interface change, the transaction receipt's appearance, and the success message.
Use the receipt to check the block explorer: how many confirmations existed when the product displayed success?
This is the lab's most valuable number. Compare it with the interface wording: success, submitted, or awaiting confirmation?
Audit approvals, then revoke them.
Use an approval inspection tool, or read contracts through a block explorer, to find this address's approvals and amounts.
The operation may already have left a permanent, unlimited approval. Revoke it and record the steps and fees required.
This closes the “you signed it yourself” path from Chapter 24. Afterward, audit your everyday wallet as well.
Write a three-part conclusion.
Three things this product does well:
Three failure paths it omitted:
The first thing I would change:Use the failure checklist to check the second part. Typically three to five of the ten are unhandled, representing the next quarter's work.
AI Lab
The division of work is clear, making this a useful way to understand AI's boundaries in product work:
What models do well: expand a feature description into a structured document with goals, roles, flows, interface elements, analytics, and acceptance criteria. They write this quickly and consistently, saving considerable labor.
What models systematically do poorly: failure paths. Training materials contain far more Web2 PRDs, where failures are fewer and usually repairable. The omissions are structural, not occasional.
Write a PRD draft for this feature:
<Description, such as swapping asset A for asset B in one operation>
Target chain: <chain>. Target users: <newcomers / experienced users>.
Part one: main flow. For each step specify:
- What the user sees
- Whether a signature is required, and its type: transfer / approval / message / offline order
- For approvals, the allowance and expiry, with reasons
Part two: transaction states. For constructing / awaiting signature / broadcast /
awaiting confirmation / confirmed / final, describe interface copy and available actions.
State exactly when success appears and its criteria.
Part three: failure paths. For each, give triggers, user-visible behavior, and handling:
No native token / insufficient balance / insufficient allowance / excess slippage /
front-running / stuck in mempool / contract execution failure / user cancellation /
network congestion / chain reorganization
Part four: list uncertainties separately.
Rules:
- Do not propose undo, rollback, or refunds unless you explain their on-chain implementation.
- Give concrete interface copy for every failure; do not merely say “show a friendly message.”Notice that the prompt supplies all ten failure paths. Deliberately: omit them and the model omits them; list them and it writes them well. The missing piece is the checklist, not capability, and a person must supply that checklist.
After receiving the draft, do three things:
- Inspect all ten paths in part three. Are they complete? Is each response feasible on-chain?
- Compare part two with your lab observations. At which state did the tested product show success? Does the model do the same?
- Find invented features. Common examples are one-click undo of the previous transaction and automatic retries with refunded gas. The former does not exist; the latter cannot recover the gas.
Four common errors, ordered by danger:
- Importing Web2 reversibility assumptions. Requirements such as cancellation within fifteen minutes have no on-chain implementation.
- Showing success at broadcast. Reducing the state machine to two boxes causes many of the six support problems above.
- Defaulting to unlimited approvals. “Request approval on first use” without an amount usually becomes unlimited in implementation.
- Ignoring front-running. Without a Web2 equivalent, models rarely raise it themselves. T24 covers the mechanism.
Save your additions separately. After three features, the repeated additions become your own on-chain product checklist, more useful than any template.
Verify these points yourself after using AI
- Does its success path confuse transaction broadcast with completed execution?
- How many of the ten failure paths are covered? Missing native tokens, insufficient allowance, and excess slippage are commonly omitted
- Does it handle wallet rejection separately from transaction failure?
- Does every signature step specify its type, allowance, and expiry?
- Does approval default to unlimited or required-only allowance?
- Does it describe the interface and user actions for a transaction stuck in the mempool?
- Does it omit front-running, or provide a concrete product response?
- Most importantly, are its retry, undo, and rollback behaviors actually possible on-chain?
Real-World Case
Early products requested enormous allowances on first approval to reduce interactions: approve once, never see another popup. This solved a real usability problem, became convention, and was copied by later products.
Years later, the cost appeared: wallets accumulated forgotten, permanent, unlimited approvals, some targeting upgradeable contracts. Most losses through the fifth outflow path in Chapter 24 happen here.
The lesson is not criticism of the original choice, but the lifespan of product defaults: a decision made to save one click can remain effective in wallets long after the product dies.
A product displays a green check and “Transaction successful” immediately upon block inclusion. Usually this seems fine.
Then a small reorganization replaces the block, and the transaction is not included again. The user has already seen success, closed the page, and acted on the assumption of receipt.
Reorganizations are normal system behavior. The product's mistake is making a promise it had no right to make.
The fix is simple: before the threshold, show “Submitted, awaiting confirmation (2/12).” Only then show success. One more state, one fewer category of incident.
A user accepts a displayed quote. The transaction enters a public mempool, visible to everyone before execution.
A program notices the order can move the price, places a transaction before it and another afterward, and captures the difference. The user receives a worse price than quoted.
Everything on-chain works normally. No contract is compromised. This is a natural consequence of public mempools, not a malfunction.
Products can disclose quote expiry, explain tolerance rather than inviting blind adjustments, flag large-order risks, or use submission routes outside the public mempool. First acknowledge the issue in the interface; the worst option is leaving users to guess afterward. T24 explains the mechanism.
A protocol launches assuming callers are people, using its own interface, one operation at a time. Rate limits, risk controls, and analytics all rest on this assumption.
Months later another team integrates it. Users act elsewhere and calls arrive here: a contract address sends dozens of calls in one transaction, with no interface-side preliminary checks.
Daily activity immediately becomes distorted (the aggregator issue in Chapter 23), rate limits stop working, and business assumptions may fail outright.
This is composability's cost, not someone's fault. Design must ask whether every assumption still holds if the caller is code rather than a person.
Change One Variable
First-use friction falls substantially. Users no longer need native tokens from elsewhere, eliminating the most common failure path.
Three consequences follow. Costs move to you, fluctuating with congestion beyond your control. You need abuse prevention, because addresses will seek to exhaust sponsored allowances—the economics Chapter 28 examines. Users lose awareness of costs, changing their understanding of why other products charge fees.
More subtly, sponsorship usually requires offline authorization that you execute on-chain. This changes the signature from type one to type four, and changes its risks. Users still sign, but different content—the interface must explain this even when the experience feels smoother.
The six-state machine seems compressed: little waiting, negligible fees, cheap retries. Many designs can indeed be simpler.
But all three constraints remain. Irreversibility remains: faster confirmation means it arrives sooner. Signatures remain: their cost changes from waiting to interruption, which still causes drop-off. Composability remains.
A reverse effect also matters: cheap experimentation makes wash activity and incentive farming cheaper. What you save in product friction may return as growth-side problems.
Do not assume a faster, cheaper chain permits Web2 product design. It changes parameters, not constraints.
This is a product-form decision rather than merely better onboarding, with three paths.
First, educate: teach wallets, signatures, and gas. Conversion will be low, but retained users understand their actions.
Second, hide: remove the visible wallet. Carefully answer who holds the private key. If you do, you are a custodian. If users hold an abstracted key, explain how they recover control if you disappear.
Third, change users: acknowledge the feature is unsuitable for complete beginners and serve wallet users first.
All are legitimate, but choose explicitly. A common failure combines hidden complexity with avoidance of custody responsibility, producing something that looks custodial without custodial protections.
You move from entry point to component, changing the evaluation criteria entirely.
What matters more: interface stability, documentation, predictable behavior, batch and contract-call support, and low integration costs.
What matters less: visuals, onboarding, and conversion funnels. Integrators handle those.
What becomes very difficult: knowing who your users are. Calls come from other contracts and you see addresses. Chapter 26's income statement remains calculable, but Chapter 28's retention analysis becomes difficult.
Distribution can happen by itself, but growth depends on other teams' product decisions. Much of Chapter 29's BD work promotes these integrations.
Takeaway Questions
This chapter adds an on-chain follow-up: is the caller a person or a contract?
An integrated protocol sees code as its caller. This can invalidate product assumptions about user behavior, beyond distorting analytics. Before any feature ask: does this assumption hold if the caller is code?
At the product layer: after this signature, what is the worst outcome, and who bears the loss?
An approval can permit all assets within the allowance to be taken. An offline order can execute at an unfavorable time. A feature unable to state these risks should not launch.
The human version is: what permissions does this signature grant, for how much, and until when?
An approval unable to answer all three opens the risk path in Chapter 24. Product actions are clear: approve as needed, add expiry, provide visibility and revocation. Doing these well protects users more than security education alone.
On-chain products give an unambiguous answer: a person must approve the final step of any irreversible fund movement.
This follows because irreversible errors cannot be corrected by another attempt, rather than automation being inherently unreliable. Design should ask how to give people enough information before confirmation, the entire purpose of the failure checklist.
Chapter Check
Irreversibility removes undo, refunds, rollback, and live rollout experiments. Move effort before mistakes through confirmation, checks, simulation, limits, and address verification.
Signatures remove server actions on users' behalf. Users approve each step in an interface outside your control. Signature count is a cost; explaining content is your responsibility.
Composability removes control over callers and freedom to change interfaces. Anyone can integrate you, and the supposed user may be code.
Together: this is a product with different constraints, not Web2 with blockchain added. Copied workflows fail because their premises have disappeared.
It promises something the product cannot guarantee.
Inclusion only places the transaction in a block. Without enough confirmations, the block can be replaced and the transaction disappear. The user has already seen success, closed the page, and acted on receipt.
Separate broadcast, awaiting confirmation with progress and threshold, confirmed, and final. One more status message prevents a category of incidents.
This is Chapter 1's distinction between displayed receipt and completed settlement. Web2 backends absorb the gap; on-chain interfaces must express it.
Transfer signature: sends assets irreversibly in one action.
Approval signature: lets a contract use an asset. One signature can remain effective until active revocation, often with unlimited allowance. This is the riskiest type.
Message signature: proves address control without an on-chain action, fee, or asset movement. Explain this proactively so users do not assume a transaction.
Offline-order signature: authorization someone else can execute. Free and off-chain resembles a message, but it is executable, and users do not control execution timing.
Distinguish these in your interface because the wallet may not. For approvals, add required-only limits, expiry, and revocation access.
It has seen far more Web2 documents, where failures are fewer and usually repairable. The learned complete-PRD template lacks this section.
Four errors follow: imported reversibility assumptions, success at broadcast, unlimited approvals by default, and no front-running coverage.
Respond by providing the ten-path checklist directly in the prompt. With it, the model writes well; without it, it omits them. The missing checklist must come from a person.
This repeats the stage's division of labor: models fill the structure; people add knowledge learned from operating in this environment.
There is no standard answer. Check:
- Did you actually trigger failures or guess from screens? Test at least three.
- Does missing native gas trigger a pre-submission check or an error after signing?
- Does it distinguish cancellation from transaction failure?
- At what state does it show success? Did you verify confirmations in an explorer?
- Are approvals required-only or unlimited? Do they expire?
- Can users view and revoke previous approvals in the product?
- Does the interface acknowledge front-running?
In practice, missing three to five paths is common, especially mempool stalls, front-running, and reorganizations. All lack direct Web2 equivalents, making imported product intuition likely to skip them.
Compare your conclusion with actual retention data. Poor failure handling usually concentrates drop-off in first use, which Chapter 28 quantifies.
Key idea
Irreversibility, signatures, and composability reshape almost every product decision.