Summary
When FULMINE_UNLOCKER_PASSWORD and FULMINE_UNLOCKER_TYPE environment variables are set, the user should not be prompted for a password during wallet creation — the env vars already provide that information.
Current Behavior
The wallet creation flow (via gRPC CreateWallet / HTTP POST /v1/wallet/create) requires the caller to supply a password field in CreateWalletRequest. This is validated in internal/interface/grpc/handlers/utils.go by parsePassword(), which returns "missing password" if the field is empty — even if the operator has already configured FULMINE_UNLOCKER_PASSWORD via the environment.
Expected Behavior
If both FULMINE_UNLOCKER_PASSWORD and FULMINE_UNLOCKER_TYPE (set to "env") are configured, CreateWallet should:
- Accept an empty
password field in the request
- Fall back to calling
unlockerSvc.GetPassword(ctx) to retrieve the password from the configured unlocker
- Proceed with wallet setup using that password — no interactive prompt needed
This mirrors how autoUnlock in internal/interface/grpc/service.go (line 325) already uses the unlocker to unlock after startup.
Why
This improves the automated/headless deployment experience. Operators running fulmine in Docker with env vars already know the password — requiring it again on first run forces an interactive fulmine createwallet call or scripted API call with the password in plaintext, defeating the purpose of the unlocker abstraction.
Affected Components
| File |
Relevance |
internal/interface/grpc/handlers/wallet_handler.go |
CreateWallet handler — calls parsePassword(req.GetPassword()) unconditionally |
internal/interface/grpc/handlers/utils.go |
parsePassword() — rejects empty password (line 33–41) |
internal/interface/grpc/service.go |
Has access to unlockerSvc — already uses it for autoUnlock |
internal/core/application/service.go |
Setup() — the function that actually initializes the wallet with the password |
internal/config/config.go |
FULMINE_UNLOCKER_PASSWORD, FULMINE_UNLOCKER_TYPE env vars (lines 88–90); initUnlockerService() |
internal/infrastructure/unlocker/env/service.go |
envunlocker.NewService — returns password from env |
internal/core/ports/unlocker.go |
Unlocker interface — GetPassword(ctx) |
Suggested Approach
Option A — handle in WalletHandler: Pass the unlockerSvc into the wallet handler and modify CreateWallet to call unlockerSvc.GetPassword(ctx) if req.GetPassword() is empty and an unlocker is configured.
Option B — handle in gRPC service.go: After svc.Start(), check if the wallet is uninitialized and an unlocker is configured. If so, auto-create the wallet is out of scope — but the service could expose a helper that allows CreateWallet with an empty password field to use the unlocker (similar to the autoUnlock pattern).
Option A is simpler and keeps the change local to the wallet handler.
Requested by kukks via Slack #fulmine
Summary
When
FULMINE_UNLOCKER_PASSWORDandFULMINE_UNLOCKER_TYPEenvironment variables are set, the user should not be prompted for a password during wallet creation — the env vars already provide that information.Current Behavior
The wallet creation flow (via gRPC
CreateWallet/ HTTPPOST /v1/wallet/create) requires the caller to supply apasswordfield inCreateWalletRequest. This is validated ininternal/interface/grpc/handlers/utils.gobyparsePassword(), which returns"missing password"if the field is empty — even if the operator has already configuredFULMINE_UNLOCKER_PASSWORDvia the environment.Expected Behavior
If both
FULMINE_UNLOCKER_PASSWORDandFULMINE_UNLOCKER_TYPE(set to"env") are configured,CreateWalletshould:passwordfield in the requestunlockerSvc.GetPassword(ctx)to retrieve the password from the configured unlockerThis mirrors how
autoUnlockininternal/interface/grpc/service.go(line 325) already uses the unlocker to unlock after startup.Why
This improves the automated/headless deployment experience. Operators running fulmine in Docker with env vars already know the password — requiring it again on first run forces an interactive
fulmine createwalletcall or scripted API call with the password in plaintext, defeating the purpose of the unlocker abstraction.Affected Components
internal/interface/grpc/handlers/wallet_handler.goCreateWallethandler — callsparsePassword(req.GetPassword())unconditionallyinternal/interface/grpc/handlers/utils.goparsePassword()— rejects empty password (line 33–41)internal/interface/grpc/service.gounlockerSvc— already uses it forautoUnlockinternal/core/application/service.goSetup()— the function that actually initializes the wallet with the passwordinternal/config/config.goFULMINE_UNLOCKER_PASSWORD,FULMINE_UNLOCKER_TYPEenv vars (lines 88–90);initUnlockerService()internal/infrastructure/unlocker/env/service.goenvunlocker.NewService— returns password from envinternal/core/ports/unlocker.goUnlockerinterface —GetPassword(ctx)Suggested Approach
Option A — handle in
WalletHandler: Pass theunlockerSvcinto the wallet handler and modifyCreateWalletto callunlockerSvc.GetPassword(ctx)ifreq.GetPassword()is empty and an unlocker is configured.Option B — handle in gRPC
service.go: Aftersvc.Start(), check if the wallet is uninitialized and an unlocker is configured. If so, auto-create the wallet is out of scope — but the service could expose a helper that allowsCreateWalletwith an empty password field to use the unlocker (similar to theautoUnlockpattern).Option A is simpler and keeps the change local to the wallet handler.
Requested by kukks via Slack #fulmine