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.
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
- UnzipUse a path without spaces. You get
crypto_wallet/andcrypto_wallet_admin/. - Install Flutter packages
cd crypto_wallet flutter pub get cd ../crypto_wallet_admin flutter pub get - Install the backend packages
cd crypto_wallet/functions npm ci npm run build
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
- Create the projectconsole.firebase.google.com → Add project, for example
mywallet-prod. - Switch to BlazeProject settings → Usage and billing → Blaze. Set a budget alert while you are there.
- Turn on Email/Password sign-inBuild → Authentication → Get started → Email/Password. Admins sign in this way.
- Create the databaseBuild → Firestore Database → Create → production mode. Pick a location near your users; it cannot be changed later.
- 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;
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
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).
- 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 - Set the three secrets
OWNER_UID,CLAUDE_API_KEYandADMIN_SETUP_TOKENlive in Google Secret Manager, not in.env. Delete theOWNER_UID=line fromfunctions/.env, then set all three. Don't know your UID yet? Typeunsetand change it after the first login. Not using Portfolio Brain? TypeunsetforCLAUDE_API_KEY.ADMIN_SETUP_TOKENis 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 - 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.
- Create your loginFirebase console → Authentication → Users → Add user, with your email and a strong password.
- Make it a super adminReplace the project ID, the email and the setup token:
The answer containscurl -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>"}}'"success":true, youruidand"role":"superAdmin". Copy the uid. The function then locks itself for good; you can setADMIN_SETUP_TOKENtounsetafterwards. - Save your UID as the owner
cd crypto_wallet firebase functions:secrets:set OWNER_UID # paste your uid firebase deploy --only functions:setAdminClaim - Sign in and turn on the authenticatorRun the admin (
flutter run -d chrome), sign in, then Security → Set Up MFA. See Admin → Security.

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_configparameter. - 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.jsonopens and returns JSON.