SuperWallet docs
v1.1.0
Wallet demoAdmin demo Get help
● Set up · Keys and settings

Configuration
keys, settings, publishing.

Where each setting lives: build-time keys in .env, backend settings in functions/.env, and everything else in the admin panel, delivered to the app through Remote Config.

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.

01Three places, one rule

WhereWhat goes thereChange needs
crypto_wallet/.envClient API keys (Reown, 0x, 1inch, RPC providers…)A new build — or Admin → System Config → Remote API Keys
crypto_wallet/functions/.env + Secret ManagerServer secrets: store validation, owner UIDRedeploying the functions
Admin panel → Firestore → Remote ConfigFee, prices, branding, chains, tokens, dApps, switchesSave + Publish to mobile app. No new build.
Build-time and remote keys are readable

Everything passed with --dart-define is compiled into the app and can be extracted from it, and keys entered under Admin → System Config → Remote API Keys are served publicly in /config.json. Put only client-side keys in either place and restrict each key in its provider dashboard (bundle ID, domain, rate limits). Real secrets never go into the app (Secrets & backups).

02App keys (.env)

cd crypto_wallet
cp .env.example .env
# every run and build then adds:
flutter run --dart-define-from-file=.env
VariablePurposeGet it at
REOWN_PROJECT_ID RequiredWalletConnect pairingcloud.reown.com
ZEROX_API_KEY0x swap quotes on EVM chains. Spell it exactly like this.dashboard.0x.org
ONEINCH_API_KEY1inch swap quotes on EVM chainsportal.1inch.dev
ALCHEMY_API_KEYMain EVM RPCalchemy.com
HELIUS_API_KEYSolana RPC and asset datahelius.xyz
MORALIS_API_KEYNFT metadata, prices, historyadmin.moralis.io
ETHERSCAN_API_KEY, BSCSCAN_API_KEY, POLYGONSCAN_API_KEY, ARBISCAN_API_KEY, OPTIMISM_ETHERSCAN_API_KEY, BASESCAN_API_KEYTransaction history per chainEach explorer's API page
BIRDEYE_API_KEYOptional Solana market databirdeye.so
COINGECKO_API_KEYOptional. Public CoinGecko endpoints work without it.coingecko.com/en/api
TRANSAK_API_KEYBuy crypto screenTransak partner dashboard
ADMIN_CONFIG_URL RecommendedAddress of your admin's config.json. Empty (the default) = Remote Config only.Your admin hosting address (how)
IAP_PRO_WEEKLY_IDStore product ID of the weekly PRO subscriptionYou choose it (Earnings → PRO)
IAP_PRO_MONTHLY_ID, IAP_PRO_ANNUAL_IDExtra plans. Leave empty unless you sell them.

Leave these empty. They are in .env.example but this version does not use them: TENDERLY_*, INFURA_API_KEY, QUICKNODE_*, OPENSEA_API_KEY, FCM_SERVER_KEY, MIXPANEL_TOKEN, AMPLITUDE_API_KEY, FORCE_ENABLE_*, FORCE_DEBUG_LOGGING, APP_ENV, FEE_WALLET_ADDRESS, FEE_BPS. The fee is set in the admin, not here. CLAUDE_API_KEY must never be in the app's .env; it is a backend secret.

Without keys

MissingWhat happens
REOWN_PROJECT_IDWalletConnect screens open but cannot connect.
ZEROX_API_KEY0x is skipped; 1inch is tried.
Both swap keysEVM quotes come only from direct DEX routers where the app knows one (no fee is collected on those), otherwise an estimate marked ~ Indicative via CoinGecko that cannot be executed.

03Backend settings (functions/.env)

Read by the Cloud Functions at deploy time. Never shipped inside the app. The provider accounts behind these keys (Apple, Google, Anthropic) and your Firebase Blaze plan are your own, and they may charge usage fees that you pay.

VariablePurposeWhere to get it
APP_NAMEName shown in authenticator apps for admin sign-in codesYour choice
ANDROID_PACKAGE_NAMEYour Android application ID. Google Play purchases are checked against this app only.Your application ID
APP_STORE_ALLOW_SANDBOXtrue only while testing with TestFlight or sandbox purchases; empty in production, so sandbox purchases never unlock PRO.Your choice
APPLE_BUNDLE_IDYour iOS bundle ID. App Store purchases for any other app are refused. Defaults to ANDROID_PACKAGE_NAME.Your bundle ID
PRO_WEEKLY_PRODUCT_ID, PRO_MONTHLY_PRODUCT_ID, PRO_ANNUAL_PRODUCT_IDStore product IDs the backend accepts. Same values as IAP_PRO_*.App Store Connect, Play Console
APP_STORE_KEY_ID, APP_STORE_ISSUER_ID, APP_STORE_PRIVATE_KEYChecks iOS purchases. The private key is the text of your .p8 file, in double quotes, line breaks written as \n.An App Store Connect API key for the App Store Server API (Apple: creating API keys)
GOOGLE_PLAY_SERVICE_ACCOUNT_JSONChecks Android purchases. The service-account JSON on one line.A Google Cloud service account with access to your Play Console app (Google: Play Developer API setup)
WEBHOOK_SECRETSigns the optional "new PRO subscriber" webhook. 16+ characters.Make one: openssl rand -hex 32
Secret (Secret Manager)Purpose
OWNER_UIDFirebase UID of the owner, who can always manage admin rights.
CLAUDE_API_KEYAnthropic key for the optional Portfolio Brain PRO feature.
ADMIN_SETUP_TOKENOne-time token that bootstrapFirstAdmin requires to create the first admin (how). 24 characters or more; unset after the first admin exists.

Portfolio Brain limits

callPortfolioBrain answers only callers that have an active, paid PRO plan verified by the server (store purchase, crypto payment or admin grant; the free trial does not include Portfolio Brain) and a valid App Check token, and it accepts structured portfolio data only, never a free-text prompt (questions are capped at 500 characters). Two daily caps in functions/.env bound your Anthropic bill; counters are kept per UTC day in the _ai_usage_daily collection.

SettingDefaultMeaning
PORTFOLIO_BRAIN_USER_DAILY_LIMIT30Calls per user per day
PORTFOLIO_BRAIN_GLOBAL_DAILY_LIMIT1000Calls per day for your whole deployment

App Check

The app activates Firebase App Check right after Firebase starts (lib/core/firebase/app_check_service.dart). Portfolio Brain needs it; nothing else depends on it.

  1. Register your appsIn App Check (Firebase guide) register Play Integrity for Android (add your release SHA-256 fingerprint in the project settings), App Attest for iOS and macOS (DeviceCheck is the fallback), reCAPTCHA v3 for the web.
  2. iOS: App Attest capabilityApp Attest works only when the app is signed with the App Attest entitlement. ios/Runner/Runner.entitlements already contains com.apple.developer.devicecheck.appattest-environment (production; the debug file uses development). In Xcode open ios/Runner.xcworkspace → Runner target → Signing & Capabilities and check that App Attest is listed (add it with + Capability if it is not), so it is also enabled on your App ID and in your provisioning profile. Without it, iOS release builds get no App Check token and Portfolio Brain falls back to its on-device summary.
  3. Web site keyBuild the web app with --dart-define=APP_CHECK_WEB_RECAPTCHA_SITE_KEY=<your site key>. Without it App Check stays off on the web and Portfolio Brain falls back to its on-device summary there.
  4. Debug buildsDebug builds use the debug provider: run once, copy the debug token from the console log into App Check as a debug token (Firebase: debug provider).
cd crypto_wallet
firebase functions:secrets:set OWNER_UID
firebase deploy --only functions      # after every change to functions/.env or a secret

04Runtime config: how a change reaches phones

  1. SaveEach admin page has its own save button (Apply Fee Config, Save Branding…). Saving writes to Firestore (app_config/runtime_admin_config) and updates the live /config.json at once.
  2. PublishPublish to mobile app (bottom-right of every page) calls publishAdminRemoteConfig, which updates the admin_config value in Firebase Remote Config.
  3. Users get itRelease builds fetch Remote Config at most once an hour; debug builds on every start. An open app also applies Remote Config's live updates. The config.json copy is refreshed in the background on each cold start.
Testing tip

To see a change on a test phone: publish, then fully close and reopen the app.

05Remote Config values

You normally change these through the admin pages. The table helps when you look at the admin_config parameter in Remote Config (Firebase: Remote Config parameters).

KeyMeaningAdmin page
maintenance_mode, maintenance_messageShows a maintenance screen instead of the walletRemote Config, System Config
swap_enabled, bridge_enabled, buy_enabled, sell_enabled, send_enabled, walletconnect_enabled, discover_enabled, push_enabledOn/off switch per featureRemote Config
min_app_versionForce-update gate (x.y.z). Empty = off.Remote Config
announcement_banner, announcement_urlBanner text and HTTPS link inside the appRemote Config, Campaigns
fee_wallet_address, fee_bpsEVM fee wallet and fee size (100 bps = 1 %). Default: empty and 0. Maximum 200 bps (2 %).Monetization
solana_fee_wallet_addressSolana fee wallet: its token accounts receive the fee on Jupiter swaps. Default: empty.Monetization
pro_fee_waiverPRO users swap without your feeMonetization
pro_weekly_price_eur, pro_trial_daysPRO price shown in the app; free trial length in days (0 = no trial: no trial button, server refuses; max 30)Monetization, System Config
pro_crypto_payment_*, pro_crypto_required_amount_eur (weekly), pro_crypto_monthly_amount_eur, pro_crypto_annual_amount_eurPay-PRO-in-crypto settings; a plan priced at 0 is not sold for cryptoSystem Config
admin_chains, admin_tokens, admin_dapps, featured_tokens, default_home_tokensContent lists pushed to the appChains, Tokens, DApps
app_name, tagline, primary_color, logo_url, support_url, websiteBranding shown in the appBranding
support_email, terms_url, privacy_url, about_text, swap_disclaimerStored, but the wallet in this version does not display them (details)Branding, System Config
config_versionGoes up with each publishPublish Config

Editing the JSON by hand works, but the next publish from the admin overwrites it, and the admin checks addresses and ranges for you.

06Where data is stored

Firestore collectionContains
app_config/runtime_admin_configThe full admin config; source of /config.json
app_config/globalSystem Config values, including the Remote API Keys. Public read, like all of app_config.
admin_config/*Admin-only: IP allowlist. Exception: admin_config/onramp (Transak settings) is public read.
chains, tokens, dapps, admin_nft_collectionsContent you curate
swap_config, branding/globalSwap routing, bridge settings, branding
campaigns, scheduled_campaigns, notification_templatesCampaigns and push messages
fee_events, users, premium_entitlements, pro_crypto_paymentsWritten by the app and functions; shown in Revenue, Users, Analytics
admin_users, admin_audit_log, config_versionsAdmins and roles, Activity Log entries, config snapshots

Who can read and write each collection is decided by crypto_wallet/firestore.rules.