Background
After the SQL store series lands, wallet/ will have many public APIs routed
through the new store stack. Current coverage is strong at the store and unit
levels, but we are missing a true integration-test foundation that boots a real
wallet with a real SQL backend and exercises the public wallet APIs end-to-end.
This issue tracks adding baseline contract coverage for every non-legacy public
wallet/ API, then building broader scenario tests on top of that foundation.
Goals
Add representative happy-path, unhappy-path, and boundary coverage for each
non-legacy public wallet/ API.
Run these tests against real SQL-backed wallets, starting with sqlite and
extending to postgres where practical.
For APIs that mutate durable state, verify behavior after wallet reload.
Establish a foundation for larger scenario-based integration tests.
Scope
The primary public components are:
Manager: Create, Load
Controller: Start, Stop, Unlock, Lock, ChangePassphrase, Info,
Resync, Rescan
AccountManager: NewAccount, ListAccounts, ListAccountsByScope,
ListAccountsByName, GetAccount, RenameAccount, ImportAccount
AddressManager: NewAddress, GetUnusedAddress, GetAddressInfo,
ListAddresses, ImportPublicKey, ImportTaprootScript, ScriptForOutput,
GetDerivationInfo
UtxoManager: ListUnspent, GetUtxo, LeaseOutput, ReleaseOutput,
ListLeasedOutputs
TxCreator: CreateTransaction
TxPublisher: CheckMempoolAcceptance, Broadcast
TxReader: GetTx, ListTxns
TxWriter: LabelTx
PsbtManager: DecorateInputs, FundPsbt, SignPsbt, FinalizePsbt,
CombinePsbt
Signer: DerivePubKey, ECDH, SignDigest, ComputeUnlockingScript,
ComputeRawSig
UnsafeSigner: DerivePrivKey, GetPrivKeyForAddress
Exclusions
This issue should not target legacy APIs:
wallet.Interface
- methods in
deprecated.go
- methods suffixed
Deprecated
- transitional
DB* methods in db_ops.go
- old RPC/JSON-shaped helpers such as legacy transaction and UTXO APIs
Test Shape
For each API, add representative contract coverage rather than exactly one
happy-path and one unhappy-path case.
Representative coverage should include successful behavior, expected errors,
meaningful boundary cases, and state-dependent behavior such as stopped,
started, locked, unlocked, watch-only, missing resource, duplicate resource, and
unsupported input cases where relevant.
For mutating APIs, tests should verify both immediate behavior and durable
state after wallet reload.
The integration layer should use real SQL stores rather than mocks. Mock-heavy
tests can still exist at the unit-test layer, but they should not be the only
coverage for public wallet behavior.
Example Coverage
NewAccount should cover normal account creation, duplicate names, invalid
names, unknown scopes, and watch-only behavior.
NewAddress should cover external and internal address generation, unsupported
address types, missing accounts, and imported-account rejection.
CreateTransaction should cover automatic coin selection, manual inputs,
insufficient funds, locked UTXOs, invalid inputs, and bad change sources.
SignPsbt should cover fully signable PSBTs, partially owned PSBTs, unknown
inputs, already-signed inputs, locked wallets, and watch-only wallets.
LeaseOutput should cover valid leases, unknown outpoints, repeated leases by
the same lock ID, leases held by another lock ID, release behavior, and expired
lease cleanup.
Follow-Up Scenario Tests
After the API contract layer exists, add scenario-based tests that combine
multiple public APIs into realistic wallet flows.
Important scenarios include wallet create/load/reload, account and address
creation, receiving funds, listing balances and UTXOs, SQL-only account
derivation and signing, transaction creation/signing/publishing, PSBT
fund/decorate/sign/finalize, sync and rollback behavior, and multi-wallet SQL
isolation.
Acceptance Criteria
Every non-legacy public wallet/ API has baseline integration coverage.
Representative happy-path, unhappy-path, and boundary cases are covered for each
API.
Mutating APIs verify durable state after wallet reload where applicable.
The integration tests use real SQL store backends rather than mocks.
Broader scenario tests are added after the per-API contract layer exists.
Background
After the SQL store series lands,
wallet/will have many public APIs routedthrough the new store stack. Current coverage is strong at the store and unit
levels, but we are missing a true integration-test foundation that boots a real
wallet with a real SQL backend and exercises the public wallet APIs end-to-end.
This issue tracks adding baseline contract coverage for every non-legacy public
wallet/API, then building broader scenario tests on top of that foundation.Goals
Add representative happy-path, unhappy-path, and boundary coverage for each
non-legacy public
wallet/API.Run these tests against real SQL-backed wallets, starting with sqlite and
extending to postgres where practical.
For APIs that mutate durable state, verify behavior after wallet reload.
Establish a foundation for larger scenario-based integration tests.
Scope
The primary public components are:
Manager:Create,LoadController:Start,Stop,Unlock,Lock,ChangePassphrase,Info,Resync,RescanAccountManager:NewAccount,ListAccounts,ListAccountsByScope,ListAccountsByName,GetAccount,RenameAccount,ImportAccountAddressManager:NewAddress,GetUnusedAddress,GetAddressInfo,ListAddresses,ImportPublicKey,ImportTaprootScript,ScriptForOutput,GetDerivationInfoUtxoManager:ListUnspent,GetUtxo,LeaseOutput,ReleaseOutput,ListLeasedOutputsTxCreator:CreateTransactionTxPublisher:CheckMempoolAcceptance,BroadcastTxReader:GetTx,ListTxnsTxWriter:LabelTxPsbtManager:DecorateInputs,FundPsbt,SignPsbt,FinalizePsbt,CombinePsbtSigner:DerivePubKey,ECDH,SignDigest,ComputeUnlockingScript,ComputeRawSigUnsafeSigner:DerivePrivKey,GetPrivKeyForAddressExclusions
This issue should not target legacy APIs:
wallet.Interfacedeprecated.goDeprecatedDB*methods indb_ops.goTest Shape
For each API, add representative contract coverage rather than exactly one
happy-path and one unhappy-path case.
Representative coverage should include successful behavior, expected errors,
meaningful boundary cases, and state-dependent behavior such as stopped,
started, locked, unlocked, watch-only, missing resource, duplicate resource, and
unsupported input cases where relevant.
For mutating APIs, tests should verify both immediate behavior and durable
state after wallet reload.
The integration layer should use real SQL stores rather than mocks. Mock-heavy
tests can still exist at the unit-test layer, but they should not be the only
coverage for public wallet behavior.
Example Coverage
NewAccountshould cover normal account creation, duplicate names, invalidnames, unknown scopes, and watch-only behavior.
NewAddressshould cover external and internal address generation, unsupportedaddress types, missing accounts, and imported-account rejection.
CreateTransactionshould cover automatic coin selection, manual inputs,insufficient funds, locked UTXOs, invalid inputs, and bad change sources.
SignPsbtshould cover fully signable PSBTs, partially owned PSBTs, unknowninputs, already-signed inputs, locked wallets, and watch-only wallets.
LeaseOutputshould cover valid leases, unknown outpoints, repeated leases bythe same lock ID, leases held by another lock ID, release behavior, and expired
lease cleanup.
Follow-Up Scenario Tests
After the API contract layer exists, add scenario-based tests that combine
multiple public APIs into realistic wallet flows.
Important scenarios include wallet create/load/reload, account and address
creation, receiving funds, listing balances and UTXOs, SQL-only account
derivation and signing, transaction creation/signing/publishing, PSBT
fund/decorate/sign/finalize, sync and rollback behavior, and multi-wallet SQL
isolation.
Acceptance Criteria
Every non-legacy public
wallet/API has baseline integration coverage.Representative happy-path, unhappy-path, and boundary cases are covered for each
API.
Mutating APIs verify durable state after wallet reload where applicable.
The integration tests use real SQL store backends rather than mocks.
Broader scenario tests are added after the per-API contract layer exists.