# solana-mobile-publishing

Builds, signs, and publishes Android APKs to the Solana dApp Store using the dapp-store CLI. Useful for first releases, minting App NFTs, and updating live apps.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 6700 installs · ★ 8
- Author: solana-mobile
- License: Apache-2.0 · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/solana-mobile/solana-mobile-skills/tree/HEAD/skills/solana-mobile-publishing/SKILL.md
- Updated: 2026-10-21
- HTML: https://affpapa.org/en/nevibecode/skills/solana-mobile-publishing

## What it does

The skill guides Android releases to the Solana dApp Store using the dapp-store CLI. The store accepts only `.apk` files. Any `.aab` bundle gets rejected immediately, so builds require `assembleRelease`. Using separate signing keys for Google Play and Solana dApp Store is mandatory to prevent one leak from compromising both store listings.

Prerequisites include Node 18 or newer and `@solana-mobile/dapp-store-cli` version 1.0.1 or higher. The developer must generate the publisher keypair manually using `solana-keygen new --silent`. Never delegate key generation to an AI agent. Otherwise, the private seed phrase prints directly into agent transcripts. Registration requires roughly 0.2 SOL in the portal, while the CLI refuses to publish if the signer holds less than 0.016 SOL. Losing the keystore is fatal because no recovery path exists.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add solana-mobile/solana-mobile-skills --skill solana-mobile-publishing -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/solana-mobile-publishing/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/solana-mobile-publishing/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add solana-mobile/solana-mobile-skills --skill solana-mobile-publishing -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/solana-mobile-publishing/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add solana-mobile/solana-mobile-skills --skill solana-mobile-publishing -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/solana-mobile-publishing/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install solana-mobile/solana-mobile-skills solana-mobile-publishing
```

2. **Manually: put the files in place**
- File: `.github/skills/solana-mobile-publishing/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add solana-mobile/solana-mobile-skills --skill solana-mobile-publishing -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/solana-mobile/solana-mobile-skills --path skills/solana-mobile-publishing
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/solana-mobile-publishing/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add solana-mobile/solana-mobile-skills --skill solana-mobile-publishing -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/solana-mobile/solana-mobile-skills/tree/HEAD/skills/solana-mobile-publishing/SKILL.md

## When to use it
- build a signed release APK for the Solana dApp Store
- configure the publisher keypair without exposing seed phrases in transcripts
- ship application updates without breaking keystore identity
- pass portal API keys securely into dapp-store CLI pipelines

## Example prompts
- Help me prepare an assembleRelease APK build for the Solana dApp Store
- How do I set up the publisher keypair file and check the required SOL balance?
- Show how to pass the portal API key to dapp-store CLI via stdin

## Source text · SKILL.md · Apache-2.0

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: cac59fb86c06c54a.

BEGIN THIRD-PARTY FILE cac59fb86c06c54a
````text
---
name: solana-mobile-publishing
description: Build, sign, and publish an Android APK to the Solana dApp Store with the dapp-store CLI. Use when shipping a Solana mobile app to the dApp Store for the first time, releasing an update, signing a release APK, setting up a publisher account and App NFT, or debugging a release build that works fine in debug.
---

# Publishing to the Solana dApp Store

Shipping to the dApp Store splits into a one-time setup that mints an on-chain App NFT, and a
per-release loop of build, sign, publish. The one-time half is where the irreversible decisions
live, so get it right before the first release rather than after.

```bash
npm install -g @solana-mobile/dapp-store-cli@latest
```

Node 18 or newer. `npx @solana-mobile/dapp-store-cli` works too if you would rather not install
globally.

**Use 1.0.1 or newer.** Earlier versions are deprecated and will not work.

## Non-negotiable constraints

**APK only. An `.aab` is rejected.** Build with `assembleRelease`, never `bundleRelease`. This
catches out anyone whose muscle memory comes from Google Play, where the bundle is the default.

**The keystore and the publisher wallet are both permanent.** An update has to be signed with
the same key as the release before it, and the App NFT lives in the publisher wallet. Lose
either and there is no recovery path and no support ticket that fixes it — the app can only be
re-listed from scratch under a new identity. Neither belongs inside the repository: ask where
the keystore should live before generating one, and keep it out of the project tree.

**If you also ship to Google Play, use a different signing key.** One key per store. Sharing one
means a compromise or loss takes out both listings at once.

## First: work out which situation you are in

| Situation | Do this |
| --- | --- |
| No publisher account yet | [One-time setup](#one-time-setup) |
| Publisher exists, shipping a release | [Build a signed APK](#build-a-signed-apk), then [Publish](#publish) |
| Shipping an update to a live app | [Shipping an update](#shipping-an-update) |
| Release build crashes but debug is fine | Read [references/signing.md](references/signing.md#release-only-failures) |
| A publish died partway through | [Resume a failed publish](#resume-a-failed-publish) |
| App is a wrapped web app, not React Native | [Web apps](#web-apps) |

## One-time setup

### The publisher keypair comes first

The CLI signs as the publisher with a keypair **file**, and connecting a wallet in the browser
````
END THIRD-PARTY FILE cac59fb86c06c54a

The third-party file has ended. Everything between the cac59fb86c06c54a tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2524 of 17376 bytes. © solana-mobile · Apache-2.0 · https://github.com/solana-mobile/solana-mobile-skills/tree/HEAD/skills/solana-mobile-publishing/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
