SuperWallet docs
v1.1.0
Wallet demoAdmin demo Get help
● Start · Step by step

Installation
app, admin, Firebase.

From the unzipped folder to a working wallet, a working admin panel and a deployed backend, all on your own Firebase project. Plan about 45 minutes the first time.

On Windows

The commands on this page are written for macOS and Linux shells. On Windows, run them in Git Bash or WSL, where they work as written. In PowerShell, set a variable with $env:NAME="value" instead of export. Flutter, Node.js and the Firebase and FlutterFire CLIs run natively on Windows; iOS and macOS builds need a Mac.

01Unzip and install packages

  1. UnzipUse a path without spaces. You get crypto_wallet/ and crypto_wallet_admin/.
  2. Install Flutter packages
    cd crypto_wallet
    flutter pub get
    cd ../crypto_wallet_admin
    flutter pub get
  3. Install the backend packages
    cd crypto_wallet/functions
    npm ci
    npm run build
Tip

Open each app folder in its own editor window. Every box on this page starts with the cd it needs, so you can always paste from the unzipped folder.

02Create your Firebase project

  1. Create the projectconsole.firebase.google.com → Add project, for example mywallet-prod.
  2. Switch to BlazeProject settings → Usage and billing → Blaze. Set a budget alert while you are there.
  3. Turn on Email/Password sign-inBuild → Authentication → Get started → Email/Password. Admins sign in this way.
  4. Create the databaseBuild → Firestore Database → Create → production mode. Pick a location near your users; it cannot be changed later.
  5. Log the CLI in
    firebase login

03Connect the wallet app

If you already know your own bundle ID, change it first (Rebranding → Bundle IDs); FlutterFire registers the app under the current one. You can also run this step again later.

cd crypto_wallet
flutterfire configure --platforms=ios,android,web
# point firebase deploy at your project
rm -f .firebaserc
firebase use --add      # pick your project, alias: default

Required The package ships only a placeholder lib/firebase_options.dart, which keeps Firebase off. This command replaces it and writes android/app/google-services.json and ios/Runner/GoogleService-Info.plist. All three are in .gitignore; keep them out of public repositories.

Required Then add one line to the generated file, inside class DefaultFirebaseOptions {. The wallet reads it at start-up and the build fails without it (details). Repeat this after every flutterfire configure.

  static const bool isPlaceholder = false;
Prefer one script?

crypto_wallet/setup_firebase.sh runs login, FlutterFire, rules and functions in one go: FIREBASE_PROJECT_ID=your-project ./setup_firebase.sh (the variable is required; it uses flutter and dart from your PATH, override with FLUTTER=… / DART=…). Read its notes first; this page stays the reference.

04Connect the admin panel

Required The admin also needs its own lib/firebase_options.dart, written by this command. It does not need the extra line.

cd crypto_wallet_admin
flutterfire configure --platforms=web
rm -f .firebaserc
firebase use --add      # same project, alias: default

Then add the domain you will host the admin on under Firebase → Authentication → Settings → Authorized domains. localhost is already there.

05Rules, indexes and Remote Config

The template crypto_wallet/remoteconfig.template.json ships with the swap fee off and every wallet address empty (fee_wallet_address, the Solana fee wallet, pro_crypto_payment_address). Leave it that way; you set your own wallets in the admin later. If you edit the template, use only wallets you control.

cd crypto_wallet
firebase deploy --only firestore:rules,firestore:indexes,remoteconfig
Only once

Deploying remoteconfig replaces the live Remote Config with the template. After the first setup, change settings in the admin panel instead, or you overwrite them.

06Cloud Functions

All functions run in the europe-west1 region. The app and the admin call that region, so keep it unless you change it everywhere (search the code for europe-west1).

  1. Create the backend settings fileFill only what you use; everything may stay empty for the first deploy. The table is in Configuration → Backend settings.
    cd crypto_wallet/functions
    cp .env.example .env
  2. Set the three secretsOWNER_UID, CLAUDE_API_KEY and ADMIN_SETUP_TOKEN live in Google Secret Manager, not in .env. Delete the OWNER_UID= line from functions/.env, then set all three. Don't know your UID yet? Type unset and change it after the first login. Not using Portfolio Brain? Type unset for CLAUDE_API_KEY. ADMIN_SETUP_TOKEN is a one-time password for creating the first admin: paste a long random value (at least 24 characters) and keep a copy for the next section.
    cd crypto_wallet
    openssl rand -hex 32      # copy the output: this is your setup token
    firebase functions:secrets:set ADMIN_SETUP_TOKEN      # paste it
    firebase functions:secrets:set OWNER_UID
    firebase functions:secrets:set CLAUDE_API_KEY
  3. DeployThe first deploy takes a few minutes and may ask to enable Google Cloud APIs. Answer yes.
    cd crypto_wallet
    firebase deploy --only functions

Firebase console → Functions should now list 30 functions, among them bootstrapFirstAdmin, publishAdminRemoteConfig, getRuntimeConfigJson and recordFeeEvent.

07Create the first admin

Only accounts listed in the admin_users collection can enter the admin panel. The first one is created by bootstrapFirstAdmin, which works exactly once and only for a caller who sends the ADMIN_SETUP_TOKEN you set above (or who is signed in as OWNER_UID). Without one of those secrets it refuses every call, even while admin_users is empty, so nobody else can claim your panel between the deploy and your own call.

  1. Create your loginFirebase console → Authentication → Users → Add user, with your email and a strong password.
  2. Make it a super adminReplace the project ID, the email and the setup token:
    curl -X POST "https://europe-west1-<your-project-id>.cloudfunctions.net/bootstrapFirstAdmin" \
      -H "Content-Type: application/json" \
      -d '{"data":{"targetEmail":"you@example.com","setupToken":"<your ADMIN_SETUP_TOKEN>"}}'
    The answer contains "success":true, your uid and "role":"superAdmin". Copy the uid. The function then locks itself for good; you can set ADMIN_SETUP_TOKEN to unset afterwards.
  3. Save your UID as the owner
    cd crypto_wallet
    firebase functions:secrets:set OWNER_UID      # paste your uid
    firebase deploy --only functions:setAdminClaim
  4. Sign in and turn on the authenticatorRun the admin (flutter run -d chrome), sign in, then Security → Set Up MFA. See Admin → Security.
Admin sign-in screen
Admin sign-in screen

08Point the wallet at your admin

Besides Remote Config, the wallet can download its settings from https://<your-admin-site>/config.json, which is faster to update. The address is a build setting called ADMIN_CONFIG_URL. It is empty by default, which means the app uses Remote Config only; nothing breaks if you leave it empty.

To use it, add one line to crypto_wallet/.env. Every run and build already reads that file through --dart-define-from-file=.env:

ADMIN_CONFIG_URL=https://<your-admin-site>/config.json

Or pass it on its own:

cd crypto_wallet
flutter run --dart-define-from-file=.env --dart-define=ADMIN_CONFIG_URL=https://<your-admin-site>/config.json

Use your admin's hosting address (for example https://mywallet-admin.web.app, see Deployment). Changing it needs a new build of the app.

The admin Overview Config Status card checks the same address: it uses ADMIN_RUNTIME_CONFIG_URL if you build the admin with it (--dart-define=ADMIN_RUNTIME_CONFIG_URL=https://…), otherwise https://<your Firebase project id>.web.app, otherwise it stays empty.

09Checklist: is everything connected?

  • Firebase console → Functions lists 30 functions in europe-west1.
  • Firebase console → Remote Config shows an admin_config parameter.
  • The wallet starts without a Firebase error in the terminal.
  • You can sign in to the admin panel and pass the authenticator step.
  • After hosting the admin: https://<your-admin-site>/config.json opens and returns JSON.