Journal

Solana Blink Mobile Wrapper UI in SwiftUI: How to Build It

A blink turns a link into an on-chain action. Here is the native SwiftUI wrapper that renders it, with signing handed to the wallet.

Solana Blink Mobile Wrapper UI in SwiftUI: How to Build It: a glowing iPhone home-screen icon on a purple and blue gradient

TL;DR

A Solana blink is a link that resolves to a real on-chain action, and a mobile wrapper renders that action as a native screen: icon, title, buttons, and a signing step handed to a wallet. In SwiftUI the wrapper is a fetch, render, sign pipeline: load the action's metadata, draw the card natively, deep link to the user's wallet for the signature, and never hold keys yourself. The strongest free starting point is a VP0 wallet-style design whose machine-readable source page an agent like Claude Code or Cursor extends while you wire the Solana side. Plan App Store review early, because wallet functionality carries organization-level requirements.

A Solana blink is a link that carries a real on-chain action. Behind the URL sits a Solana Action endpoint, a small API that describes itself with an icon, a title, a description, and one or more buttons, and that returns a ready-to-sign transaction when a button is pressed. A blink client reads that metadata and unfurls the link into an interactive card, so “claim this airdrop” or “buy this ticket” becomes a button instead of a wall of instructions. Solana keeps fees low enough that these one-tap actions make sense for small transactions, which is why the pattern took off there first.

A mobile wrapper is the iOS surface for that pattern: an app that takes a blink or action URL, fetches the metadata, and renders it as a native screen rather than a browser preview. The classic content for it is exactly what crypto apps already show, a claim screen, a payment confirmation, a mint button, except the data and the buttons come from the action endpoint instead of being hardcoded.

The wrapper renders a blink in three steps: fetch the action’s JSON metadata, draw the card natively in SwiftUI, and map each button to the POST request that returns a transaction for signing. The metadata gives you everything the card needs, the icon, the title, the description, the button labels, so the SwiftUI side is a clean, focused layout: an image, two text blocks, a button row, and a status area for the signing flow.

Because the card’s contents are remote, the layout has to absorb whatever arrives. Titles run long, icons load slowly or not at all, and descriptions vary from one line to five, so the card needs a placeholder for the image, line limits with truncation that never hides an amount, and type that scales with Dynamic Type. Test it with the worst real action you can find, not the prettiest one.

What separates a trustworthy wrapper from a toy is the trust chrome around that card. The domain the action came from should be visible, because the card’s contents are remote and a user is about to sign something based on them. Amounts should be shown in full, never truncated. And the state machine matters: a button that was tapped is pending, not done, and the screen should distinguish submitted, confirmed, and failed honestly. A blink card that looks beautiful but hides where it came from gets the trust model backwards.

The three integration levels

There are three depths at which an iOS app can host blinks, and they differ mainly in how native the experience feels and how much responsibility you take on.

ApproachWhat you getThe work
Native SwiftUI renderer, wallet handles signingNative card, native trust chrome, no custodyFetch and render the action metadata, deep link out for signatures
SFSafariViewController to a hosted blink pageFastest to ship, browser-grade UIAlmost none, but it feels like a web shell
Full wallet built inOne app does everythingKey management, custody, and wallet-grade review scrutiny

The native renderer in the first row is the practical middle: the experience feels like an app, and the keys stay someone else’s problem. For the screen itself, the strongest free starting point is a VP0 wallet-style design, served with a machine-readable source page that an agent like Claude Code or Cursor reads from a pasted link, so the card, the button row, and the status states arrive already shaped while you wire the action endpoints. The Solana side leans on a mature stack, the core web3.js library pulls roughly 1,823,011 weekly npm downloads, so the thin part of the project really is the UI and the routing, not the chain plumbing. A broader set of screens for the same product family lives in a crypto wallet UI kit.

How do you handle signing without holding keys?

The wrapper should never see a seed phrase. When a button’s POST returns a transaction, hand it to a wallet the user already has, through the wallet’s deep link or SDK, and receive the signature result back. The user approves inside the wallet app, where their keys live, and your wrapper’s job is to represent that round trip honestly: a clear handoff (“continuing in your wallet”), a pending state while the wallet is open, and a confirmed or failed state when control returns. The return path needs the same care as the outbound link, a callback URL the wallet can open so your app regains the foreground with the result, plus a timeout state for the user who switches apps and never comes back.

This split is worth defending even when it feels clumsy, because the alternative changes what you are building. The moment the app generates or stores keys, it is a wallet, with everything that implies: secure enclave storage, backup ceremonies, and the kind of seed phrase recovery screen that has to be designed as a security ritual rather than a form. A render-and-route wrapper stays small precisely because it refuses that responsibility, and most blink products do not need it.

A blink wrapper can pass review when it is scoped and described honestly, and the scoping is the part to get right early. Apple’s App Store Review Guidelines treat crypto functionality with specific care: wallet functionality must come from developers enrolled as an organization, not as an individual, and anything that looks like custody pulls the app into that category. A wrapper that renders actions and routes signing to an external wallet sits in a lighter category, but the review notes should say exactly that, what the app does, what it never does, and where keys live.

Two practical habits help. First, make the app useful before any wallet is connected, with browseable content and a clear explanation, because a screen that demands a wallet at launch reads as a shell. Second, never gamify the transactions; the app presents actions, it does not push them. Review outcomes follow the honesty of the framing more than the category of the app.

Common mistakes when vibe coding the wrapper

The most common failure is treating every blink as trusted. The card is remote content that ends in a signature, so unknown actions deserve the same suspicion a browser gives an unknown download: show the origin, warn on unregistered sources, and never auto-trigger a POST. Agents skip this because the happy path demos well without it.

Three more show up in almost every generated draft. The agent hallucinates an SDK surface instead of using the two real requests, a GET for metadata and a POST for the transaction, so pin the prompt to the actual spec. The signing flow gets collapsed into one optimistic state, where tapping a button immediately shows success; the wrapper must wait for the wallet’s answer. And the transaction preview gets skipped entirely, when showing what is about to be signed, the amounts and the destination, is the difference between a tool and a trap. The same preview discipline that a swap confirmation screen needs applies here unchanged.

  • A blink is remote UI that ends in a signature. Fetch the action metadata, render it natively, treat it as untrusted content.
  • The wrapper is a fetch-render-sign pipeline. GET for the card, POST for the transaction, a wallet for the signature.
  • Never hold keys. Deep link to the user’s wallet; custody turns the project into a wallet with wallet-grade obligations.
  • Trust chrome is the product. Visible origin, full amounts, honest pending and failed states.
  • Start from a free VP0 wallet-style design. The card and states arrive shaped; you wire the Solana side.

The practical way to ship it

Build the native renderer with wallet-handled signing. It is the level that feels like a real app, keeps you out of custody, and leaves the hard, well-solved problems, keys and signatures, with software built for them. Start the screens from a free VP0 wallet-style design and let your agent extend the card, the button row, and the status states from the source page, then spend your own attention on the action fetching, the origin checks, and the wallet round trip, because that is where the product earns trust. If your audience lives entirely on the web and X, a hosted blink page may serve them without an app at all; and if your roadmap genuinely requires holding keys, plan it as a wallet from day one rather than letting a wrapper drift into custody.

Frequently asked questions

How do I build a Solana blink wrapper UI in SwiftUI? Fetch the action’s metadata with a GET request, render the icon, title, description, and buttons as a native SwiftUI card, and map each button to the POST request that returns a transaction. Hand that transaction to the user’s wallet through a deep link, then reflect the result with honest pending, confirmed, and failed states. Keep the origin domain visible on the card and show full amounts before any signature. A free VP0 wallet-style design gives an agent the card and states to extend while you wire the endpoints.

What is a Solana blink compared to a regular deep link? A regular deep link opens a screen; a blink carries an interactive on-chain action. The URL resolves to an Action endpoint that describes itself, icon, title, buttons, and that returns a ready-to-sign transaction when a button is chosen. So a blink is closer to a tiny remote app than to a navigation shortcut, and that is why rendering one demands trust signals, origin, amounts, and confirmation states, that an ordinary link never needs.

Is there a free template for a Solana blink wrapper app? The useful free starting point is a wallet-style design with the action card, button row, and transaction states already shaped. VP0 provides exactly that, free, with a machine-readable source page that Claude Code, Cursor, or another agent reads from a pasted link and extends into the wrapper, while you connect the Solana Actions endpoints and the wallet deep links. The chain integration stays your work, which is the right split, because the UI is reusable and the routing is specific to your product.

Does a blink wrapper app need its own wallet? No, and it is usually better without one. The wrapper renders actions and routes transactions to a wallet the user already has, receiving the signature result back. Building in a wallet means generating and storing keys, secure backup flows, and a heavier review path, and it changes the product into a custody app. Reach for that only when the roadmap truly requires it, and then design it as a wallet from the start rather than as a wrapper that grew keys.

Will Apple approve a Solana blink wrapper app? Approval is realistic when the scope is honest. Apple requires wallet functionality to come from developers enrolled as an organization, so a wrapper should either stay out of custody entirely, rendering actions and deep linking to external wallets, or accept that it is a wallet and meet those requirements. Make the app useful before any wallet connects, explain in the review notes exactly where keys live and do not live, and present transactions plainly instead of gamifying them.

Questions from the community

How do I build a Solana blink wrapper UI in SwiftUI?

Fetch the action's metadata with a GET request, render the icon, title, description, and buttons as a native SwiftUI card, and map each button to the POST request that returns a transaction. Hand that transaction to the user's wallet through a deep link, then reflect the result with honest pending, confirmed, and failed states. Keep the origin domain visible on the card and show full amounts before any signature. A free VP0 wallet-style design gives an agent the card and states to extend while you wire the endpoints.

What is a Solana blink compared to a regular deep link?

A regular deep link opens a screen; a blink carries an interactive on-chain action. The URL resolves to an Action endpoint that describes itself, icon, title, buttons, and that returns a ready-to-sign transaction when a button is chosen. So a blink is closer to a tiny remote app than to a navigation shortcut, and that is why rendering one demands trust signals, origin, amounts, and confirmation states, that an ordinary link never needs.

Is there a free template for a Solana blink wrapper app?

The useful free starting point is a wallet-style design with the action card, button row, and transaction states already shaped. VP0 provides exactly that, free, with a machine-readable source page that Claude Code, Cursor, or another agent reads from a pasted link and extends into the wrapper, while you connect the Solana Actions endpoints and the wallet deep links. The chain integration stays your work, which is the right split, because the UI is reusable and the routing is specific to your product.

Does a blink wrapper app need its own wallet?

No, and it is usually better without one. The wrapper renders actions and routes transactions to a wallet the user already has, receiving the signature result back. Building in a wallet means generating and storing keys, secure backup flows, and a heavier review path, and it changes the product into a custody app. Reach for that only when the roadmap truly requires it, and then design it as a wallet from the start rather than as a wrapper that grew keys.

Will Apple approve a Solana blink wrapper app?

Approval is realistic when the scope is honest. Apple requires wallet functionality to come from developers enrolled as an organization, so a wrapper should either stay out of custody entirely, rendering actions and deep linking to external wallets, or accept that it is a wallet and meet those requirements. Make the app useful before any wallet connects, explain in the review notes exactly where keys live and do not live, and present transactions plainly instead of gamifying them.

Part of the Web3, Telegram Mini-Apps & Crypto UI hub. Browse all VP0 topics →

Keep reading

Seed Phrase Recovery Screen: An iOS Security Template: a glossy App Store icon on a blue, pink and orange gradient with bubbles
Guides 6 min read

Seed Phrase Recovery Screen: An iOS Security Template

The seed phrase is the wallet, so its recovery screen is a security ceremony: generate on-device, reveal deliberately, force confirmation, and never transmit it.

Lawrence Arya · June 7, 2026
Telegram Dark Mode Color Palette in SwiftUI: a glass iPhone UI wireframe icon on a holographic purple gradient
Guides 4 min read

Telegram Dark Mode Color Palette in SwiftUI

Build a Telegram-style theming system in SwiftUI: semantic colors that adapt to light and dark and match Telegram's theme, from a free VP0 design.

Lawrence Arya · May 31, 2026
Crypto Portfolio Profit/Loss Chart in SwiftUI: Best Way: a reflective 3D App Store icon on a blue and purple gradient
Guides 5 min read

Crypto Portfolio Profit/Loss Chart in SwiftUI: Best Way

How to build a crypto portfolio profit and loss chart in SwiftUI: cost basis math, price feeds, Swift Charts baselines, and the honesty rules that keep trust.

Lawrence Arya · June 4, 2026
bKash App Clone UI in SwiftUI, Free for iOS: a vivid neon 3D App Store icon on an orange, pink and blue gradient
Guides 5 min read

bKash App Clone UI in SwiftUI, Free for iOS

Want a bKash style wallet clone UI in SwiftUI? Clone the mobile-money pattern from a free template and build it with Claude Code or Cursor. The legal way.

Lawrence Arya · June 1, 2026
DePIN Network Map UI for iOS, Free Template: a glass iPhone app-grid icon on a mint and teal gradient
Guides 5 min read

DePIN Network Map UI for iOS, Free Template

Build a DePIN (decentralized physical infrastructure) network map UI for iOS from a free template. Nodes, coverage, and status with Claude Code or Cursor.

Lawrence Arya · June 1, 2026
Decentralized VPN Node Selector UI in SwiftUI, Free: the App Store logo on a glass tile over a blue gradient with bubbles
Guides 5 min read

Decentralized VPN Node Selector UI in SwiftUI, Free

Build a decentralized VPN node selector UI in SwiftUI from a free template. Browse nodes, see status, and connect, with the tunnel caveat handled honestly.

Lawrence Arya · June 1, 2026