How We Implement NFT Purchase in Mobile Apps
Note: when a user clicks "Buy," a chain of blockchain transactions starts, any step of which can fail: insufficient gas, price changes, listing updates. We design a robust purchase flow: check order validity, prepare approve (if needed), send the transaction, and wait for confirmation. On errors, we decode the revert and display a human-readable message. Here's how it's implemented in Swift and Kotlin.
Purchasing an NFT in a mobile app is not just a smart contract call. It involves multiple steps, each requiring edge-case handling: network congestion, wallet not connected, token already bought. Without proper integration, users encounter vague errors and leave the app. Our team has 10+ years of mobile development experience and has delivered over 50 projects with blockchain integration—we ensure the purchase flow runs smoothly and, in case of issues, explains the cause clearly.
How to Check NFT Availability Before Purchase
Before showing the "Buy" button, verify the current listing status. The NFT might have been sold seconds ago, and the cached screen wouldn't know.
// iOS — check listing activity before purchase func checkListingActive(contractAddress: String, tokenId: BigUInt) async throws -> Bool { let listing = try await marketplaceContract.getListing( nftAddress: EthereumAddress(contractAddress)!, tokenId: tokenId ) return listing.price > 0 && listing.seller != EthereumAddress.zero } If the listing is inactive, the button changes to "Not for sale" without opening a purchase dialog.
Why Separate Approve and Buy?
When buying with ETH — one transaction: buyItem(nftContract, tokenId, { value: price }). This is faster and simpler but requires the user to have ETH.
When buying with ERC-20 (e.g., USDC) — two transactions:
-
usdc.approve(marketplaceAddress, price)— allow the marketplace to spend tokens -
marketplace.buyItem(nftContract, tokenId)— the actual purchase
Users should see this as a single flow: "Step 1 of 2: Approve USDC spending" → "Step 2 of 2: Confirm purchase." Include a progress indicator and explanation for each step.
How to Combine Approve and Buy Using Permit?
If the token supports EIP-2612 (Permit), approve can be replaced by an off-chain signature. Then buy executes in one transaction, like with ETH, but passes the permit signature. This reduces gas costs and improves UX. By our calculations, gas savings are up to 30% compared to classic approve + buy. At current Ethereum gas prices, this equates to roughly $0.50–$1.00 per transaction. Compare:
| Scenario | Transactions | Gas (approx) | UX |
|---|---|---|---|
| ETH (native) | 1 | ~60k gas | Minimum steps – best for user |
| ERC-20 (approve + buy) | 2 | ~90k gas | Transparent but longer |
| ERC-20 (permit) | 1 | ~70k gas | Like ETH, but with a signature |
Waiting for Confirmation
After sending the transaction, don't block the screen. Show:
- TransactionHash as a link to the explorer (Etherscan, Polygonscan)
- "Waiting for confirmation" indicator with ability to leave
- Push notification when N confirmations are received (usually 1–3)
// Android — wait for confirmation with timeout suspend fun waitForReceipt(txHash: String, timeoutMs: Long = 120_000): TransactionReceipt? { val deadline = System.currentTimeMillis() + timeoutMs while (System.currentTimeMillis() < deadline) { val receipt = web3j.ethGetTransactionReceipt(txHash).send().transactionReceipt if (receipt.isPresent) return receipt.get() delay(3_000) } return null } If receipt.status == "0x0" the transaction reverted. Decode the reason via debug_traceTransaction or check known smart contract errors (see OpenSea Seaport docs).
How to Handle Transaction Errors?
| Error | Cause | UI Reaction |
|---|---|---|
execution reverted: Not listed |
NFT removed from sale | "NFT is no longer for sale" |
execution reverted: Price mismatch |
Price changed | Show actual price, offer to update |
insufficient funds |
Not enough ETH for gas | "Please top up your wallet to pay the fee" |
| Transaction timeout | Network congestion | Offer to speed up transaction (increase gas price) |
We handle every revert: decode the reason and display a clear message. This builds user trust and reduces support requests.
What's Included in the Work
- Design of the purchase flow with optimal scenario selection (ETH/ERC-20/permit)
- Implementation in Swift/Kotlin compliant with App Store Review Guidelines (Section 4.2/5.1) and Google Play policies
- Testing: unit tests for transaction logic, integration tests for contract interactions
- Documentation of the flow and source code
- Signed builds (TestFlight / Firebase App Distribution)
- 3 months of post-release support
Process and Timeline
- Analysis and design — determine purchase scenarios, choose optimal flow (1–2 days)
- Implementation — write code (2–5 days)
- Testing — cover unit tests for transaction logic, integration tests for contract interaction (1–2 days)
- Deliverables — documentation, builds, deployment (1 day)
- Post-release support — 3 months warranty and bug fixes
Timeline: 3 to 10 days depending on complexity. Pricing is calculated individually after project evaluation.
If you want your app to support NFT purchases, contact us for an evaluation. Order the integration to get a consultation on implementing the purchase flow tailored to your requirements.







