Package: pippin-wallet
Pippin is a production-ready, high-performance developer wallet forNanoandBANANO. Pippin's API is a drop-in replacement for the Nano developer wallet that is built in to the Nano node software.About PippinPippin is written in Python. It achieves high performance across the board using libraries such asasyncio,uvloop,aiohttp,asyncpg/aiosqlite/aiomysql, andrapidjson.For block signing and work generation, Pippin usesnanopy, which is a high-performance library that utilizes C-bindings for blake2b and ed25519.Benefits of PippinThe Nano developer wallet (aka "node wallet") is not recommended for production use. One of the goals of Pippin is to provide a production-ready external key management that can be used by developers who are using Nano.Pippin is the first drop-in replacement for the Nano developer wallet. It's incredibly easy to transition to Pippin if you are already using the Nano developer wallet.Pippin is independent of the node. You can use Pippin with any public RPC, so you don't have to run your own nodePippin is extremely fast and lightweightPippin supports encrypted secret keysPippin natively supportsBPoWPippin supports multiple database backends (SQLite, PostgreSQL, and MySQL)Pippin can be used by exchanges, games, payment processors, tip bots, faucets, casinos, and a lot more.Pippin PerformanceThe benchmark script that was used is availablehereThere were 3 independent runs for each wallet, 62 blocks each, same node, and the same work peer. Pippin was consistentlytwice as fastversus the node wallet.How Pippin WorksPippin provides an API that mimics theNano Wallet RPC ProtocolEvery wallet-related RPC gets intercepted by Pippin and handled internally. It builds the blocks and signs them using locally-stored keys, it uses a node to publish the blocks.Every non-wallet related RPC gets proxied to the publishing node. Which means you can make all of your RPC requests directly to Pippin whether they are wallet-related or not.API DocumentationRecommended reference is theNANO RPC documentation, Pippin's APIs are mostly identical.You send an HTTP Post request to pippin with the desired action and parameters, example:{
    "action": "accounts_create",
    "wallet": "12345",
    "count": 100
}Supportedwallet_createaccount_createaccounts_createaccount_listreceivesend- Use theidparameter to prevent duplicate sends!account_representative_setpassword_change- This will also set a password, if one isn't already setpassword_enterpassword_validwallet_representative_setwallet_add- This is for adding ad-hoc private keys to a walletwallet_lockwallet_lockedwallet_balanceswallet_frontierswallet_pendingwallet_destroywallet_change_seedwallet_containswallet_representativereceive_all- Not in the nano API, it takes awalletand it will receive every pending block in that wallet (respectingreceive_minimum).Differences: Pippin vs NANO Node WalletThese are the known differences between Pippin's API and the Nano node wallet APIDifferent BehaviorAPIs that are different between Pippin and the Nano node wallet.account_listaccepts acountparameter that defaults to 1000Pippin has anauto_receive_on_sendoption that will automatically receive pending blocks when you do asend, it will only do this if balance isnt high enough to make the transaction.account_createdoes not accept an indexFuzzy BehaviorThe Nano documentation isn't perfectly clear on these, but these are how Pippin behaves.wallet_change_seedwill result in the wallet no longer being locked, if it is. The wallet has to already be unlocked before you can use this RPC, though.Missing/Not ImplementedAPIs that the Nano node wallet supports but are not implemented in Pippin.account_moveaccount_removereceive_minimum- Receive minimum can be set inconfig.yamlreceive_minimum_setwallet_add_watchwallet_historysearch_pendingsearch_pending_allwallet_exportwallet_ledgerwallet_republishwallet_work_getwork_getwork_setCLI DocumentationPippin has a CLI interface available, you can see available subcommands with:pippin-cli --helpThe primary goal of the CLI is key management. It's a more secure way to import a seed and backup your seed.For example a typical flow of creating a new wallet with a specific seed might look like (add --encrypt to wallet_change_seed if you want to lock the wallet with a password):% pippin-cli wallet_create
Wallet created, ID: d897b5ec-1897-4e7e-8a90-4526f454c8de
First account: nano_31a7wzm4rayik1hthahzkekntsqz86u6dko5adg8jxueehzt5yhmhsqsuzdy
% pippin-cli wallet_change_seed --wallet d897b5ec-1897-4e7e-8a90-4526f454c8de
Enter new wallet seed: <hidden_input>
Seed changed for wallet d897b5ec-1897-4e7e-8a90-4526f454c8de
First account: nano_3ejy6ha1iuqhi5cshhifu57p5othdcymfbzsmxhjucdks53eh41yd4qpjtxfTo backup a seed (warning:this prints seed to stdout)% pippin-cli wallet_view_seed --wallet <id>Setting up PippinRequirementsPython 3.6 or newerGCC, for MacOS and LinuxA Redis serverMacOS InstructionsInstallhomebrew, if it isn't already installedInstall Redis (skip if you already have done so)% brew install gcc@9 python redis
% launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plistTo start redis at boot (optional):% ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgentsYou may find it convenient to priorize homebrew binaries by including the install location first in your PATH.% export PATH=/usr/local/bin:$PATHTo make it permanent:# Catalina
% echo "export PATH=/usr/local/bin:$PATH" >> ~/.zprofile
# Others
% echo "export PATH=/usr/local/bin:$PATH" >> ~/.profileUbuntu 18.04Instructions for other debian-based Linux distributions should be similar.% sudo apt install build-essential python3.6 python3.6-dev python3-pip redis-serverCentOS 8Install the required developer tools:# dnf install gcc redis python3-develThe above may require the EPEL and PowerTools repos to be configured first:# dnf install -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
# dnf config-manager --set-enabled PowerToolsRedis basics for CentOS 8After installing Redis, create directories for the Redis config and runtime files:# mkdir /etc/redis /var/redis /var/redis/6379By default, the dnf install places Redis config files in /etc, move them to your dedicated folders:# mv /etc/redis-sentinel.conf /etc/redis/
# mv /etc/redis.conf /etc/redis/6379.confUpdate your Redis config file to allow it to run in the background as a daemon, supervised by systemd:# vim /etc/redis/6379.conf
	Set daemonize to yes (by default it is set to no).
	Set the pidfile to /var/run/redis_6379.pid (modify the port if needed).
	Change the port if necessary (6379 is the default).
	Set the logfile to /var/log/redis_6379.log
	Set the working dir to /var/redis/6379
	supervised systemdCreate the Systemd service to have Redis start automatically:# vim /etc/systemd/system/redis.service
[Unit]
Description=Redis
After=syslog.target

[Service]
Type=notify
PIDFile=/var/run/redis_6379.pid
ExecStart=/usr/bin/redis-server /etc/redis/6379.conf --supervised systemd
Restart=on-failure

[Install]
WantedBy=multi-user.targetEnable and start the service:# systemctl enable --now /etc/systemd/system/redis.serviceVerify that Redis is running:# systemctl status redis
# redis-cli pingInstalling PippinFirst, update PIP to latest version.% pip3 install -U pipFor MacOS you might need to set the following environment variable:export CC=/usr/local/bin/gcc-9To install Pippin on macos or Linux% pip install --user pippin-walletWindows requires visual c++ and should be prefixed with USE_VC=1% USE_VC=1 pip install pippin-walletTo upgrade Pippin in the future, add --upgrade% pip install --upgrade pippin-walletConfiguring PippinPippin creates aPippinDatadirectory in your home directory.Run:pippin-server --generate-configto generate a sample in~/PippinData/sample.config.yamlUsing BoomPoWWant to useBPoW?Pippin will use them automatically for work generation if the key is present in the environment.For BPoW:% echo "BPOW_KEY=service:mybpowkey" >> ~/PippinData/.envConfiguring PostgreSQL or MySQLPippin uses SQLite by default, which requires no extra configuration.To use postgres or mysql, you need to put your database information in some environment variablesPostgres:Required (replacedatabase_name,user_name, andmypasswordwith the actual values):% echo "POSTGRES_DB=database_name" >> ~/PippinData/.env
% echo "POSTGRES_USER=user_name" >> ~/PippinData/.env
% echo "POSTGRES_PASSWORD=mypassword" >> ~/PippinData/.envOptional:# 127.0.0.1 is default
% echo "POSTGRES_HOST=127.0.0.1" >> ~/PippinData/.env
# 5432 is default
% echo "POSTGRES_PORT=5432" >> ~/PippinData/.envMySQL:Required (replacedatabase_name,user_name, andmypasswordwith the actual values):% echo "MYSQL_DB=database_name" >> ~/PippinData/.env
% echo "MYSQL_USER=user_name" >> ~/PippinData/.env
% echo "MYSQL_PASSWORD=mypassword" >> ~/PippinData/.envOptional:# 127.0.0.1 is default
% echo "MYSQL_HOST=127.0.0.1" >> ~/PippinData/.env
# 3306 is default
% echo "MYSQL_PORT=3306" >> ~/PippinData/.envChanging Redis Host/PortPippin uses Redis for distributed locks, so that every account works on its own chain in a synchronous fashion.By default, it will look for redis on127.0.0.1on port6379and use db0, you can also change these with environment variables.echo "REDIS_HOST=127.0.0.1" >> ~/PippinData/.env
echo "REDIS_PORT=6379" >> ~/PippinData/.env
echo "REDIS_DB=0" >> ~/PippinData/.env
echo "REDIS_PW=supersecretpassword" >> ~/PippinData/.envPippin ConfigurationPippin uses ayamlbased configuration for everything else.All available options are in asample file.You can override any default by creating a file called~/PippinData/config.yamland choosing your own settings.It must be in your users home directory in a folder calledPippinDataConfiguring Pippin for BANANOInconfig.yamlset banano: true# Settings for the pippin wallet
wallet:
  # Run in banano mode
  # If true, the wallet will operate based on the BANANO protocol
  # Default: false
  banano: trueConfiguring the nodeAt the bare minimum, Pippin requires a node for the RPC api. It will default tohttp://[::1]:7076for Nano, orhttp://[::1]:7072for BANANO. If you want to change it tohttps://coolnanonode.com/rpcthen it would look like this:server:
  # The RPC URL of the remote node to connect to
  # Non-wallet RPCs will be routed to this node
  # Default: http://[::1]:7076 for nano, https://[::1]:7072 for banano
  node_rpc_url: https://coolnanonode.com/rpcRunning PippinOnce configured, just start it withpippin-serverIt can be started on boot using systemd (Linux)Create a file/etc/systemd/system/pippin.serviceWith the contents:[Unit]
Description=Pippin Wallet
After=network.target

[Service]
Type=simple
User=YOUR_LINUX_USER
Group=YOUR_LINUX_USER
ExecStart=/home/myuser/.local/bin/pippin-server

[Install]
WantedBy=multi-user.targetIf you aren't sure what the full path of pippin-server is, runwhich pippin-serverThen enable and start% sudo systemctl enable pippin
% sudo systemctl start pippinEndpointsSend HTTP POST requests to Pippin just like you would a normal node.% curl -g -d '{"action":"wallet_create"}' localhost:11338
% curl -g -d '{"action":"account_balance", "account": "nano_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse"}' localhost:11338Auto-receive & Dynamic PoWTo automatically pocket pending transactions as they arrive, callback is required.Hooking up the websocket also adds support fordynamic PoWwhich means that blocks will get confirmed faster if the active difficulty is higher than the minimum.Pippin only supports the websocket callback, which can be setup like so inconfig.yaml:server:
  # The WebSocket URL of the node to connect to
  # Optional, but required to receive transactions as they arrive to accounts
  # Default: None
  #node_ws_url: ws://[::1]:7078Feature requestsNotice an API that's missing a feature or not behaving the same as nano's APIs?Open a bug report/feature request on theissues page