NFC Crypto Kit docs
v1.0.0
Live demo Get help
● Ship · Stores and desktop

Build and release
signed builds for the App Store, Google Play and the desktop.

Release builds use your own Apple team and Android signing key. Do the white-label steps first: bundle IDs and signing keys cannot change once an app is published.

flutter build appbundleflutter build ipakey.propertiesPyInstaller

01Before the first release build

  • Your app names, colours, bundle IDs and icons are set (White label).
  • Your card domain serves the app-link files with your Team ID (Card host setup).
  • Your own RPC providers and API keys are in place (Networks, Configuration).
  • The tests pass in each app (commands).
  • Raise version in pubspec.yaml (and APP_VERSION / APP_BUILD in NFC Crypto's .env) for every store upload.

02Android release

  1. Create an upload key once and keep it safe (losing it blocks updates):
    keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
  2. Create android/key.properties in the app folder (git ignores it):
    Windows

    The commands on this page are written for macOS and Linux shells. On Windows run them in PowerShell, Git Bash or WSL; iOS builds need a Mac.

    storeFile=/path/to/upload-keystore.jks
    storePassword=your-store-password
    keyAlias=upload
    keyPassword=your-key-password
    Use the full path for storeFile.
  3. Build the bundle for Google Play.
AppSigningBuild command
NFC Cryptoandroid/key.properties as above, or the variables ANDROID_KEYSTORE_PATH, ANDROID_KEYSTORE_PASSWORD, ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD (for CI). Without them, the release build falls back to the debug key.flutter build appbundle --release --dart-define-from-file=.env
CryptoCard Walletandroid/key.properties as above. Without it, the release build uses the debug key.flutter build appbundle --release
NFC RecoveryAlways the debug key: android/app/build.gradle.kts has no release signing config. Add one (as in the Flutter Android deployment guide) before publishing.flutter build appbundle --release

The bundle is in build/app/outputs/bundle/release/app-release.aab. For a direct install test use flutter build apk --release (build/app/outputs/flutter-apk/app-release.apk).

Never publish a debug-signed build

A debug key is the same on every developer machine. Check with keytool -printcert -jarfile app-release.apk that the certificate is yours.

After the first upload with Play App Signing, copy the "App signing key certificate" SHA-256 into assetlinks.json (details).

03iOS release

  1. Set your team (Set your Apple team) and make sure the App ID has NFC Tag Reading, plus Associated Domains for NFC Crypto and CryptoCard.
  2. Install pods if Flutter has not done it yet:
    cd ios
    LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 pod install
    cd ..
    CocoaPods can fail on a non-UTF-8 locale; setting LANG avoids it. NFC Crypto's Podfile sets it already; the other two apps do not.
  3. Build the archive:
    # NFC Crypto
    flutter build ipa --release --dart-define-from-file=.env
    # CryptoCard Wallet, NFC Recovery
    flutter build ipa --release
  4. Upload build/ios/ipa/*.ipa with Xcode's Organizer or Apple's Transporter app, or open build/ios/archive/Runner.xcarchive in Xcode and choose Distribute App.

NFC Crypto also has ios/ExportOptions.plist (App Store Connect) and ios/ExportOptions_AdHoc.plist (release testing). Put your Team ID in place of YOUR_TEAM_ID before you use them, for example with flutter build ipa --release --dart-define-from-file=.env --export-options-plist=ios/ExportOptions.plist.

04Simulator builds

flutter build ios --simulator --no-codesign

Simulators have no NFC; use them to check screens. With Xcode 27 on Apple silicon, the simulator app must be built for arm64 only. All three Flutter apps already set this in their ios/Flutter/*.xcconfig files (EXCLUDED_ARCHS[sdk=iphonesimulator*] = x86_64). If you see Flutter.framework/Flutter does not contain architectures "arm64 x86_64", check that this line is still there. Device and App Store builds are not affected.

05Card Studio for your team

Your operators can run Card Studio from the folder with run.sh or run.bat; nothing needs to be built. To hand out a double-click app, package it with PyInstaller on each platform and sign it: see Package it as an app.

06Check on real phones with real cards

The automated tests do not use a real NFC chip. Before you publish, run this on at least one iPhone (XS or newer) and one Android phone, with the release build and your own card domain:

  • Pair a blank NTAG215 card; the first card is the Owner. Pair a second card; it joins as Backup.
  • Close the app and tap the card: the app opens (iPhone needs your apple-app-site-association live).
  • Turn on Require the card → To open the app; lock and reopen: the app asks for the card.
  • Turn on For payments and swaps; send a small amount on a test or low-fee network: the card is asked.
  • Make a card a Spender with a small daily limit; pay under the limit with it; then try over the limit: the app asks for the Owner or Backup card.
  • Save the recovery backup on a card; check it with Check backup; read it in NFC Recovery with the PIN.
  • Share the address on one card; on another phone, Send → Tap recipient's card: the address appears for confirmation.
  • Program, clone and erase cards in Card Studio with the real reader; read the clone in the apps.
  • CryptoCard Wallet: create a wallet on a blank card on Sepolia, receive test ETH, send it back with tap and PIN.

07Store review notes

  • Explain in the review notes that the app needs an NFC card, and how the reviewer can test without one. Card screens open without a card; signing does not need a card until "Require the card" is turned on.
  • Describe the card honestly in the listing: a second factor and backup carrier, not a hardware wallet.
  • Apple and Google have their own rules for crypto wallet apps; check them for your region before you submit.