Class WalletAppKit
- java.lang.Object
-
- com.google.common.util.concurrent.AbstractIdleService
-
- org.bitcoinj.kits.WalletAppKit
-
- All Implemented Interfaces:
com.google.common.util.concurrent.Service
,java.io.Closeable
,java.lang.AutoCloseable
public class WalletAppKit extends com.google.common.util.concurrent.AbstractIdleService implements java.io.Closeable
Utility class that wraps the boilerplate needed to set up a new SPV bitcoinj app. Instantiate it with a directory and file prefix, optionally configure a few things, then use startAsync and optionally awaitRunning. The object will construct and configure a
BlockChain
,SPVBlockStore
,Wallet
andPeerGroup
. Depending on the value of the blockingStartup property, startup will be considered complete once the block chain has fully synchronized, so it can take a while.To add listeners and modify the objects that are constructed, you can either do that by overriding the
onSetupCompleted()
method (which will run on a background thread) and make your changes there, or by waiting for the service to start and then accessing the objects from wherever you want. However, you cannot access the objects this class creates until startup is complete.The asynchronous design of this class may seem puzzling (just use
AbstractIdleService.awaitRunning()
if you don't want that). It is to make it easier to fit bitcoinj into GUI apps, which require a high degree of responsiveness on their main thread which handles all the animation and user interaction. Even when blockingStart is false, initializing bitcoinj means doing potentially blocking file IO, generating keys and other potentially intensive operations. By running it on a background thread, there's no risk of accidentally causing UI lag.Note that
AbstractIdleService.awaitRunning()
can throw an uncheckedIllegalStateException
if anything goes wrong during startup - you should probably handle it and useThrowable.getCause()
to figure out what went wrong more precisely. Same thing if you just use theAbstractIdleService.startAsync()
method.
-
-
Field Summary
Fields Modifier and Type Field Description protected boolean
autoStop
protected boolean
blockingStartup
protected java.io.InputStream
checkpoints
protected java.io.File
directory
protected PeerDiscovery
discovery
protected DownloadProgressTracker
downloadListener
protected java.lang.String
filePrefix
protected static org.slf4j.Logger
log
protected BitcoinNetwork
network
protected NetworkParameters
params
protected PeerAddress[]
peerAddresses
protected ScriptType
preferredOutputScriptType
protected DeterministicKey
restoreFromKey
protected DeterministicSeed
restoreFromSeed
protected KeyChainGroupStructure
structure
protected boolean
useAutoSave
protected java.lang.String
userAgent
protected BlockChain
vChain
protected java.lang.String
version
protected PeerGroup
vPeerGroup
protected SPVBlockStore
vStore
protected Wallet
vWallet
protected java.io.File
vWalletFile
protected WalletProtobufSerializer.WalletFactory
walletFactory
-
Constructor Summary
Constructors Constructor Description WalletAppKit(BitcoinNetwork network, ScriptType preferredOutputScriptType, KeyChainGroupStructure structure, java.io.File directory, java.lang.String filePrefix)
Creates a new WalletAppKit, on the specifiedBitcoinNetwork
.WalletAppKit(NetworkParameters params, java.io.File directory, java.lang.String filePrefix)
WalletAppKit(NetworkParameters params, ScriptType preferredOutputScriptType, KeyChainGroupStructure structure, java.io.File directory, java.lang.String filePrefix)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description BlockChain
chain()
void
close()
Close and release resources.WalletAppKit
connectToLocalHost()
Will only connect to localhost.protected PeerGroup
createPeerGroup()
protected Wallet
createWallet()
java.io.File
directory()
boolean
isChainFileLocked()
Tests to see if the spvchain file has an operating system file lock on it.static WalletAppKit
launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix)
Launch an instance of WalletAppKit with asynchronous startup.static WalletAppKit
launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix, int maxConnections)
Launch an instance of WalletAppKit with asynchronous startup.static WalletAppKit
launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix, java.util.function.Consumer<WalletAppKit> configurer)
Launch an instance of WalletAppKit with asynchronous startup.static WalletAppKit
launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix, java.util.function.Consumer<WalletAppKit> configurer, int maxConnections)
Launch an instance of WalletAppKit with asynchronous startup.BitcoinNetwork
network()
protected void
onSetupCompleted()
This method is invoked on a background thread after all objects are initialised, but before the peer group or block chain download is started.NetworkParameters
params()
PeerGroup
peerGroup()
protected java.util.List<WalletExtension>
provideWalletExtensions()
Override this to return wallet extensions if any are necessary.WalletAppKit
restoreWalletFromKey(DeterministicKey accountKey)
If an account key is set here then any existing wallet that matches the file name will be renamed to a backup name, the chain file will be deleted, and the wallet object will be instantiated with the given key instead of a fresh seed being created.WalletAppKit
restoreWalletFromSeed(DeterministicSeed seed)
If a seed is set here then any existing wallet that matches the file name will be renamed to a backup name, the chain file will be deleted, and the wallet object will be instantiated with the given seed instead of a fresh one being created.WalletAppKit
setAutoSave(boolean value)
If true, the wallet will save itself to disk automatically whenever it changes.WalletAppKit
setAutoStop(boolean autoStop)
If true, will register a shutdown hook to stop the library.WalletAppKit
setBlockingStartup(boolean blockingStartup)
If true (the default) then the startup of this service won't be considered complete until the network has been brought up, peer connections established and the block chain synchronised.WalletAppKit
setCheckpoints(java.io.InputStream checkpoints)
If set, the file is expected to contain a checkpoints file calculated with BuildCheckpoints.WalletAppKit
setDiscovery(PeerDiscovery discovery)
Sets the peer discovery class to use.WalletAppKit
setDownloadListener(DownloadProgressTracker listener)
If you want to learn about the sync process, you can provide a listener here.WalletAppKit
setPeerNodes(PeerAddress... addresses)
Will only connect to the given addresses.protected void
setupAutoSave(Wallet wallet)
WalletAppKit
setUserAgent(java.lang.String userAgent, java.lang.String version)
Sets the string that will appear in the subver field of the version message.WalletAppKit
setWalletFactory(WalletProtobufSerializer.WalletFactory walletFactory)
Sets a wallet factory which will be used when the kit creates a new wallet.protected void
shutDown()
protected void
startUp()
BlockStore
store()
Wallet
wallet()
-
-
-
Field Detail
-
log
protected static final org.slf4j.Logger log
-
network
protected final BitcoinNetwork network
-
params
protected final NetworkParameters params
-
preferredOutputScriptType
protected final ScriptType preferredOutputScriptType
-
structure
protected final KeyChainGroupStructure structure
-
filePrefix
protected final java.lang.String filePrefix
-
vChain
protected volatile BlockChain vChain
-
vStore
protected volatile SPVBlockStore vStore
-
vWallet
protected volatile Wallet vWallet
-
vPeerGroup
protected volatile PeerGroup vPeerGroup
-
directory
protected final java.io.File directory
-
vWalletFile
protected volatile java.io.File vWalletFile
-
useAutoSave
protected boolean useAutoSave
-
peerAddresses
protected PeerAddress[] peerAddresses
-
downloadListener
protected DownloadProgressTracker downloadListener
-
autoStop
protected boolean autoStop
-
checkpoints
protected java.io.InputStream checkpoints
-
blockingStartup
protected boolean blockingStartup
-
userAgent
protected java.lang.String userAgent
-
version
protected java.lang.String version
-
walletFactory
@Nonnull protected WalletProtobufSerializer.WalletFactory walletFactory
-
restoreFromSeed
@Nullable protected DeterministicSeed restoreFromSeed
-
restoreFromKey
@Nullable protected DeterministicKey restoreFromKey
-
discovery
@Nullable protected PeerDiscovery discovery
-
-
Constructor Detail
-
WalletAppKit
@Deprecated public WalletAppKit(NetworkParameters params, java.io.File directory, java.lang.String filePrefix)
Creates a new WalletAppKit, with a newly createdContext
. Files will be stored in the given directory.
-
WalletAppKit
@Deprecated public WalletAppKit(NetworkParameters params, ScriptType preferredOutputScriptType, @Nullable KeyChainGroupStructure structure, java.io.File directory, java.lang.String filePrefix)
Creates a new WalletAppKit, with a newly createdContext
. Files will be stored in the given directory.
-
WalletAppKit
public WalletAppKit(BitcoinNetwork network, ScriptType preferredOutputScriptType, KeyChainGroupStructure structure, java.io.File directory, java.lang.String filePrefix)
Creates a new WalletAppKit, on the specifiedBitcoinNetwork
. Files will be stored in the given directory.- Parameters:
network
- The network the wallet connects topreferredOutputScriptType
- The output script type (and thereforeAddress
type) of the walletstructure
- The keychain group structure (e.g.KeyChainGroupStructure.BIP43
orKeyChainGroupStructure.BIP32
directory
- The directory for creating.wallet
and.spvchain
filesfilePrefix
- The base name for the.wallet
and.spvchain
files
-
-
Method Detail
-
launch
public static WalletAppKit launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix)
Launch an instance of WalletAppKit with asynchronous startup. Wait until the PeerGroup is initialized.- Parameters:
network
- The network the wallet connects todirectory
- The directory for creating.wallet
and.spvchain
filesfilePrefix
- The base name for the.wallet
and.spvchain
files- Returns:
- the instance
-
launch
public static WalletAppKit launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix, java.util.function.Consumer<WalletAppKit> configurer)
Launch an instance of WalletAppKit with asynchronous startup. Wait until the PeerGroup is initialized.- Parameters:
network
- The network the wallet connects todirectory
- The directory for creating.wallet
and.spvchain
filesfilePrefix
- The base name for the.wallet
and.spvchain
filesconfigurer
- Callback to allow configuring the kit before it is started- Returns:
- the instance
-
launch
public static WalletAppKit launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix, int maxConnections)
Launch an instance of WalletAppKit with asynchronous startup. Wait until the PeerGroup is initialized.- Parameters:
network
- The network the wallet connects todirectory
- The directory for creating.wallet
and.spvchain
filesfilePrefix
- The base name for the.wallet
and.spvchain
filesmaxConnections
- maximum number of peer connections.- Returns:
- the instance
-
launch
public static WalletAppKit launch(BitcoinNetwork network, java.io.File directory, java.lang.String filePrefix, java.util.function.Consumer<WalletAppKit> configurer, int maxConnections)
Launch an instance of WalletAppKit with asynchronous startup. Wait until the PeerGroup is initialized.- Parameters:
network
- The network the wallet connects todirectory
- The directory for creating.wallet
and.spvchain
filesfilePrefix
- The base name for the.wallet
and.spvchain
filesconfigurer
- Callback to allow configuring the kit before it is startedmaxConnections
- maximum number of peer connections.- Returns:
- the instance
-
setPeerNodes
public WalletAppKit setPeerNodes(PeerAddress... addresses)
Will only connect to the given addresses. Cannot be called after startup.
-
connectToLocalHost
public WalletAppKit connectToLocalHost()
Will only connect to localhost. Cannot be called after startup.
-
setAutoSave
public WalletAppKit setAutoSave(boolean value)
If true, the wallet will save itself to disk automatically whenever it changes.
-
setDownloadListener
public WalletAppKit setDownloadListener(DownloadProgressTracker listener)
If you want to learn about the sync process, you can provide a listener here. For instance, aDownloadProgressTracker
is a good choice. This has no effect unless setBlockingStartup(false) has been called too, due to some missing implementation code.
-
setAutoStop
public WalletAppKit setAutoStop(boolean autoStop)
If true, will register a shutdown hook to stop the library. Defaults to true.
-
setCheckpoints
public WalletAppKit setCheckpoints(java.io.InputStream checkpoints)
If set, the file is expected to contain a checkpoints file calculated with BuildCheckpoints. It makes initial block sync faster for new users - please refer to the documentation on the bitcoinj website (https://bitcoinj.github.io/speeding-up-chain-sync) for further details.
-
setBlockingStartup
public WalletAppKit setBlockingStartup(boolean blockingStartup)
If true (the default) then the startup of this service won't be considered complete until the network has been brought up, peer connections established and the block chain synchronised. ThereforeAbstractIdleService.awaitRunning()
can potentially take a very long time. If false, then startup is considered complete once the network activity begins and peer connections/block chain sync will continue in the background.
-
setUserAgent
public WalletAppKit setUserAgent(java.lang.String userAgent, java.lang.String version)
Sets the string that will appear in the subver field of the version message.- Parameters:
userAgent
- A short string that should be the name of your app, e.g. "My Wallet"version
- A short string that contains the version number, e.g. "1.0-BETA"
-
setWalletFactory
public WalletAppKit setWalletFactory(@Nonnull WalletProtobufSerializer.WalletFactory walletFactory)
Sets a wallet factory which will be used when the kit creates a new wallet.- Parameters:
walletFactory
- Factory for making new wallets (UseWalletProtobufSerializer.WalletFactory.DEFAULT
for default behavior)- Returns:
- WalletAppKit for method chaining purposes
-
restoreWalletFromSeed
public WalletAppKit restoreWalletFromSeed(DeterministicSeed seed)
If a seed is set here then any existing wallet that matches the file name will be renamed to a backup name, the chain file will be deleted, and the wallet object will be instantiated with the given seed instead of a fresh one being created. This is intended for restoring a wallet from the original seed. To implement restore you would shut down the existing appkit, if any, then recreate it with the seed given by the user, then start up the new kit. The next time your app starts it should work as normal (that is, don't keep calling this each time).
-
restoreWalletFromKey
public WalletAppKit restoreWalletFromKey(DeterministicKey accountKey)
If an account key is set here then any existing wallet that matches the file name will be renamed to a backup name, the chain file will be deleted, and the wallet object will be instantiated with the given key instead of a fresh seed being created. This is intended for restoring a wallet from an account key. To implement restore you would shut down the existing appkit, if any, then recreate it with the key given by the user, then start up the new kit. The next time your app starts it should work as normal (that is, don't keep calling this each time).
-
setDiscovery
public WalletAppKit setDiscovery(@Nullable PeerDiscovery discovery)
Sets the peer discovery class to use. If none is provided then DNS is used, which is a reasonable default.
-
provideWalletExtensions
protected java.util.List<WalletExtension> provideWalletExtensions() throws java.lang.Exception
Override this to return wallet extensions if any are necessary.
When this is called, chain(), store(), and peerGroup() will return the created objects, however they are not initialized/started.
- Throws:
java.lang.Exception
-
onSetupCompleted
protected void onSetupCompleted()
This method is invoked on a background thread after all objects are initialised, but before the peer group or block chain download is started. You can tweak the objects configuration here.
-
isChainFileLocked
public boolean isChainFileLocked() throws java.io.IOException
Tests to see if the spvchain file has an operating system file lock on it. Useful for checking if your app is already running. If another copy of your app is running and you start the appkit anyway, an exception will be thrown during the startup process. Returns false if the chain file does not exist or is a directory.- Throws:
java.io.IOException
-
startUp
protected void startUp() throws java.lang.Exception
- Specified by:
startUp
in classcom.google.common.util.concurrent.AbstractIdleService
- Throws:
java.lang.Exception
-
setupAutoSave
protected void setupAutoSave(Wallet wallet)
-
createWallet
protected Wallet createWallet()
-
createPeerGroup
protected PeerGroup createPeerGroup()
-
shutDown
protected void shutDown() throws java.lang.Exception
- Specified by:
shutDown
in classcom.google.common.util.concurrent.AbstractIdleService
- Throws:
java.lang.Exception
-
close
public void close()
Close and release resources. ImplementsCloseable
. This should be idempotent.- Specified by:
close
in interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
-
network
public BitcoinNetwork network()
-
params
public NetworkParameters params()
-
chain
public BlockChain chain()
-
store
public BlockStore store()
-
wallet
public Wallet wallet()
-
peerGroup
public PeerGroup peerGroup()
-
directory
public java.io.File directory()
-
-