diff --git a/.gitignore b/.gitignore index b32e317f3a..d8b2a20067 100644 --- a/.gitignore +++ b/.gitignore @@ -80,8 +80,8 @@ src/qt/bitcoin-qt.includes # Compilation and Qt preprocessor part *.qm Makefile -bitcoin-qt -Bitcoin-Qt.app +elements-qt +Elements-Qt.app background.tiff* # Unit-tests diff --git a/.travis.yml b/.travis.yml index eed2515e86..b771900afe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,7 @@ env: - CCACHE_DIR=$HOME/.ccache - BASE_OUTDIR=$TRAVIS_BUILD_DIR/out - SDK_URL=https://bitcoincore.org/depends-sources/sdks + - COMMON_PACKAGES="icnsutils librsvg2-bin imagemagick" - WINEDEBUG=fixme-all - DOCKER_PACKAGES="build-essential libtool autotools-dev automake pkg-config bsdmainutils curl git ca-certificates ccache" before_install: diff --git a/.travis/test_04_install.sh b/.travis/test_04_install.sh index ef595287b7..ef8928daa0 100755 --- a/.travis/test_04_install.sh +++ b/.travis/test_04_install.sh @@ -22,5 +22,5 @@ if [ -n "$DPKG_ADD_ARCH" ]; then fi travis_retry DOCKER_EXEC apt-get update -travis_retry DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES $DOCKER_PACKAGES +travis_retry DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq $COMMON_PACKAGES $PACKAGES $DOCKER_PACKAGES diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d5dc3221b..a688b3dd82 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -78,7 +78,7 @@ the pull request affects. Valid areas as: - *Consensus* for changes to consensus critical code - *Docs* for changes to the documentation - - *Qt* for changes to bitcoin-qt + - *Qt* for changes to elements-qt - *Mining* for changes to the mining code - *Net* or *P2P* for changes to the peer-to-peer network code - *RPC/REST/ZMQ* for changes to the RPC, REST or ZMQ APIs diff --git a/Makefile.am b/Makefile.am index 291e09c535..c145d307ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,7 +33,7 @@ OSX_BACKGROUND_IMAGE_DPIS=36 72 OSX_DSSTORE_GEN=$(top_srcdir)/contrib/macdeploy/custom_dsstore.py OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_FANCY_PLIST=$(top_srcdir)/contrib/macdeploy/fancy.plist -OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns +OSX_INSTALLER_ICONS=src/qt/res/rendered_icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW @@ -50,9 +50,9 @@ DIST_SHARE = \ BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ $(top_srcdir)/contrib/devtools/security-check.py -WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \ +WINDOWS_PACKAGING = src/qt/res/rendered_icons/bitcoin.ico \ $(top_srcdir)/share/pixmaps/nsis-header.bmp \ - $(top_srcdir)/share/pixmaps/nsis-wizard.bmp \ + src/qt/res/rendered_icons/nsis-wizard.bmp \ $(top_srcdir)/doc/README_windows.txt OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ @@ -90,11 +90,14 @@ $(OSX_APP)/Contents/Info.plist: $(OSX_PLIST) $(MKDIR_P) $(@D) $(INSTALL_DATA) $< $@ +src/qt/res/rendered_icons/%: FORCE + $(MAKE) -C src $(patsubst src/%,%,$@) + $(OSX_APP)/Contents/Resources/bitcoin.icns: $(OSX_INSTALLER_ICONS) $(MKDIR_P) $(@D) $(INSTALL_DATA) $< $@ -$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: all-recursive +$(OSX_APP)/Contents/MacOS/Elements-Qt: all-recursive $(MKDIR_P) $(@D) STRIPPROG="$(STRIP)" $(INSTALL_STRIP_PROGRAM) $(BITCOIN_QT_BIN) $@ @@ -104,7 +107,7 @@ $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings: OSX_APP_BUILT=$(OSX_APP)/Contents/PkgInfo $(OSX_APP)/Contents/Resources/empty.lproj \ $(OSX_APP)/Contents/Resources/bitcoin.icns $(OSX_APP)/Contents/Info.plist \ - $(OSX_APP)/Contents/MacOS/Bitcoin-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings + $(OSX_APP)/Contents/MacOS/Elements-Qt $(OSX_APP)/Contents/Resources/Base.lproj/InfoPlist.strings osx_volname: echo $(OSX_VOLNAME) >$@ @@ -129,7 +132,7 @@ $(APP_DIST_DIR)/Applications: @rm -f $@ @cd $(@D); $(LN_S) /Applications $(@F) -$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt +$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Elements-Qt $(OSX_DMG): $(APP_DIST_EXTRAS) $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist @@ -144,7 +147,7 @@ $(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIF $(APP_DIST_DIR)/.DS_Store: $(OSX_DSSTORE_GEN) $(PYTHON) $< "$@" "$(OSX_VOLNAME)" -$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Bitcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) +$(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/Elements-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) -translations-dir=$(QT_TRANSLATION_DIR) -add-qt-tr $(OSX_QT_TRANSLATIONS) -verbose 2 deploydir: $(APP_DIST_EXTRAS) diff --git a/configure.ac b/configure.ac index 10b6cd1224..f020551eb6 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) BITCOIN_DAEMON_NAME=elementsd -BITCOIN_GUI_NAME=bitcoin-qt +BITCOIN_GUI_NAME=elements-qt BITCOIN_CLI_NAME=elements-cli BITCOIN_TX_NAME=elements-tx @@ -418,6 +418,17 @@ AC_ARG_WITH([daemon], [build_bitcoind=$withval], [build_bitcoind=yes]) +can_render_icons=yes +AC_PATH_PROGS([RSVG_CONVERT],[rsvg-convert rsvg],no) +AC_PATH_PROGS([IMAGEMAGICK_CONVERT],[convert],no) +AC_PATH_PROGS([PNG2ICNS],[png2icns],no) + +if test x$RSVG_CONVERT = xno; then + can_render_icons='rsvg-convert' +elif test x$IMAGEMAGICK_CONVERT = xno; then + can_render_icons='(ImageMagick) convert' +fi + use_pkgconfig=yes case $host in *mingw*) @@ -482,6 +493,10 @@ case $host in ;; *darwin*) + if test x$PNG2ICNS = xno; then + can_render_icons='png2icns' + fi + TARGET_OS=darwin LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then @@ -531,8 +546,6 @@ case $host in AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) - AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) - AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) dnl libtool will try to strip the static lib, which is a problem for @@ -582,6 +595,8 @@ case $host in ;; esac +AM_CONDITIONAL([CAN_RENDER_ICONS], [test x$can_render_icons = xyes]) + if test x$use_pkgconfig = xyes; then m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) m4_ifdef([PKG_PROG_PKG_CONFIG], [ diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 0bd08c4556..52f0ce400c 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -23,6 +23,9 @@ packages: - "gcc-8-multilib" - "binutils-gold" - "git" +- "icnsutils" +- "imagemagick" +- "librsvg2-bin" - "pkg-config" - "autoconf" - "libtool" @@ -59,6 +62,10 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi + ls librsvg*.deb || wget http://mirrors.kernel.org/ubuntu/pool/main/libr/librsvg/librsvg2-2_2.40.13-3_amd64.deb + dpkg -x librsvg*.deb new-rsvg + export LD_LIBRARY_PATH="$(echo $PWD/new-rsvg/usr/lib/*/)" + function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 057c2a345a..4b0798a5c7 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -10,6 +10,7 @@ packages: - "curl" - "g++" - "git" +- "icnsutils" - "pkg-config" - "autoconf" - "librsvg2-bin" @@ -54,6 +55,10 @@ script: | export ZERO_AR_DATE=1 + ls librsvg*.deb || wget http://mirrors.kernel.org/ubuntu/pool/main/libr/librsvg/librsvg2-2_2.40.13-3_amd64.deb + dpkg -x librsvg*.deb new-rsvg + export LD_LIBRARY_PATH="$(echo $PWD/new-rsvg/usr/lib/*/)" + function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} @@ -156,9 +161,6 @@ script: | ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg cd installed - find . -name "lib*.la" -delete - find . -name "lib*.a" -delete - rm -rf ${DISTNAME}/lib/pkgconfig find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz cd ../../ done diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index d12dcbffee..60ccda7cd8 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -9,6 +9,9 @@ packages: - "curl" - "g++" - "git" +- "icnsutils" +- "imagemagick" +- "librsvg2-bin" - "pkg-config" - "autoconf" - "libtool" @@ -48,6 +51,10 @@ script: | mkdir -p ${BASE_CACHE} ${SOURCES_PATH} fi + ls librsvg*.deb || wget http://mirrors.kernel.org/ubuntu/pool/main/libr/librsvg/librsvg2-2_2.40.13-3_amd64.deb + dpkg -x librsvg*.deb new-rsvg + export LD_LIBRARY_PATH="$(echo $PWD/new-rsvg/usr/lib/*/)" + function create_global_faketime_wrappers { for prog in ${FAKETIME_PROGS}; do echo '#!/usr/bin/env bash' > ${WRAP_DIR}/${prog} @@ -159,12 +166,7 @@ script: | rename 's/-setup\.exe$/-setup-unsigned.exe/' *-setup.exe cp -f elements-*setup*.exe $OUTDIR/ cd installed - mv ${DISTNAME}/bin/*.dll ${DISTNAME}/lib/ - find . -name "lib*.la" -delete - find . -name "lib*.a" -delete - rm -rf ${DISTNAME}/lib/pkgconfig find ${DISTNAME}/bin -type f -executable -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; - find ${DISTNAME}/lib -type f -exec ${i}-objcopy --only-keep-debug {} {}.dbg \; -exec ${i}-strip -s {} \; -exec ${i}-objcopy --add-gnu-debuglink={}.dbg {} \; find ${DISTNAME} -not -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip find ${DISTNAME} -name "*.dbg" -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}-debug.zip cd ../../ diff --git a/contrib/macdeploy/detached-sig-create.sh b/contrib/macdeploy/detached-sig-create.sh index 5281ebcc47..fd467e3f1e 100755 --- a/contrib/macdeploy/detached-sig-create.sh +++ b/contrib/macdeploy/detached-sig-create.sh @@ -7,7 +7,7 @@ export LC_ALL=C set -e ROOTDIR=dist -BUNDLE="${ROOTDIR}/Bitcoin-Qt.app" +BUNDLE="${ROOTDIR}/Elements-Qt.app" CODESIGN=codesign TEMPDIR=sign.temp TEMPLIST=${TEMPDIR}/signatures.txt diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist index ef277a7f14..3491d6c53a 100644 --- a/contrib/macdeploy/fancy.plist +++ b/contrib/macdeploy/fancy.plist @@ -22,7 +22,7 @@ 370 156 - Bitcoin-Qt.app + Elements-Qt.app 128 156 diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 17ce6c44f9..2df26bfb99 100755 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -154,7 +154,7 @@ class FrameworkInfo(object): class ApplicationBundleInfo(object): def __init__(self, path): self.path = path - appName = "Bitcoin-Qt" + appName = "Elements-Qt" self.binaryPath = os.path.join(path, "Contents", "MacOS", appName) if not os.path.exists(self.binaryPath): raise RuntimeError("Could not find bundle binary for " + path) @@ -602,7 +602,7 @@ else: # ------------------------------------------------ -target = os.path.join("dist", "Bitcoin-Qt.app") +target = os.path.join("dist", "Elements-Qt.app") if verbose >= 2: print("+ Copying source bundle +") diff --git a/doc/README.md b/doc/README.md index 499c0b1459..e4d0f04c55 100644 --- a/doc/README.md +++ b/doc/README.md @@ -16,11 +16,11 @@ The following are some helpful notes on how to run Bitcoin Core on your native p Unpack the files into a directory and run: - `bin/elementsd` (headless) -- `bin/elements-qt` (GUI) (currently not provided) +- `bin/elements-qt` (GUI) ### Windows -Unpack the files into a directory, and then run bitcoin-qt.exe. +Unpack the files into a directory, and then run elements-qt.exe. ### macOS diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 07d61b3bda..936a117841 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,23 +1,23 @@ -Bitcoin Core -============= - -Intro ------ -Bitcoin is a free open source peer-to-peer electronic cash system that is -completely decentralized, without the need for a central server or trusted -parties. Users hold the crypto keys to their own money and transact directly -with each other, with the help of a P2P network to check for double-spending. - - -Setup ------ -Unpack the files into a directory and run bitcoin-qt.exe. - -Bitcoin Core is the original Bitcoin client and it builds the backbone of the network. -However, it downloads and stores the entire history of Bitcoin transactions; -depending on the speed of your computer and network connection, the synchronization -process can take anywhere from a few hours to a day or more. - -See the bitcoin wiki at: - https://en.bitcoin.it/wiki/Main_Page -for more help and information. +Bitcoin Core +============= + +Intro +----- +Bitcoin is a free open source peer-to-peer electronic cash system that is +completely decentralized, without the need for a central server or trusted +parties. Users hold the crypto keys to their own money and transact directly +with each other, with the help of a P2P network to check for double-spending. + + +Setup +----- +Unpack the files into a directory and run elements-qt.exe. + +Bitcoin Core is the original Bitcoin client and it builds the backbone of the network. +However, it downloads and stores the entire history of Bitcoin transactions; +depending on the speed of your computer and network connection, the synchronization +process can take anywhere from a few hours to a day or more. + +See the bitcoin wiki at: + https://en.bitcoin.it/wiki/Main_Page +for more help and information. diff --git a/doc/build-unix.md b/doc/build-unix.md index d30cb02062..aca07199ca 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -24,7 +24,7 @@ make make install # optional ``` -This will build bitcoin-qt as well if the dependencies are met. +This will build elements-qt as well if the dependencies are met. Dependencies --------------------- @@ -99,19 +99,21 @@ ZMQ dependencies (provides ZMQ API 4.x): #### Dependencies for the GUI -If you want to build bitcoin-qt, make sure that the required packages for Qt development +If you want to build Elements-Qt, make sure that the required packages for Qt development are installed. Qt 5 is necessary to build the GUI. To build without GUI pass `--without-gui`. To build with Qt 5 you need the following: - sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler + sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler imagemagick librsvg2-bin + +The last two dependencies are required to generate Elements images that don't exist in Bitcoin Core. libqrencode (optional) can be installed with: sudo apt-get install libqrencode-dev -Once these are installed, they will be found by configure and a bitcoin-qt executable will be +Once these are installed, they will be found by configure and a elements-qt executable will be built by default. diff --git a/share/examples/liquid.conf b/share/examples/liquid.conf new file mode 100644 index 0000000000..703420f745 --- /dev/null +++ b/share/examples/liquid.conf @@ -0,0 +1,416 @@ +### Liquid Core Daemon configuration file example + +# Chain is Liquid +chain=liquidv1 + +# Execute command when a relevant alert is received or we see a really +# long fork (%s in cmd is replaced by message) +# alertnotify= + +# Execute command when the best block changes (%s in cmd is replaced by +# block hash) +# blocknotify= + +# If this block is in the chain assume that it and its ancestors are valid +# and potentially skip their script verification (0 to verify all, +# default: 0000000000000000000000000000000000000000000000000000000000000000) +# assumevalid= + +# Specify configuration file (default: liquid.conf) +# conf= + +# Run in the background as a daemon and accept commands +# daemon=1 + +# Specify data directory +# datadir= + +# Set database cache size in megabytes (4 to 16384, default: 450) +# dbcache=450 + +# Imports blocks from external blk000??.dat file on startup +# loadblock= + +# Keep at most unconnectable transactions in memory (default: 100) +# maxorphantx=100 + +# Keep the transaction memory pool below megabytes (default: 300) +# maxmempool=300 + +# Do not keep transactions in the mempool longer than hours (default: +# 336) +# mempoolexpiry= + +# Extra transactions to keep in memory for compact block reconstructions +# (default: 100) +# blockreconstructionextratxn=100 + +# Set the number of script verification threads (-2 to 16, 0 = auto, <0 = +# leave that many cores free, default: 0) +# par=0 + +# Specify pid file (default: liquidd.pid) +# pid= + +# Reduce storage requirements by enabling pruning (deleting) of old +# blocks. This allows the pruneblockchain RPC to be called to +# delete specific blocks, and enables automatic pruning of old +# blocks if a target size in MiB is provided. This mode is +# incompatible with -txindex and -rescan. Warning: Reverting this +# setting requires re-downloading the entire blockchain. (default: +# 0 = disable pruning blocks, 1 = allow manual pruning via RPC, +# >550 = automatically prune block files to stay under the +# specified target size in MiB) +# prune=0 + +# Rebuild chain state from the currently indexed blocks +# reindex-chainstate + +# Rebuild chain state and block index from the blk*.dat files on disk +# reindex + +# Create new files with system default permissions, instead of umask 077 +# (only effective with disabled wallet functionality) +# sysperms + +# Maintain a full transaction index, used by the getrawtransaction rpc +# call (default: 0) +# txindex=0 + +### Connection options: + +# Add a node to connect to and attempt to keep the connection open +# addnode= + +# Threshold for disconnecting misbehaving peers (default: 100) +# banscore= + +# Number of seconds to keep misbehaving peers from reconnecting (default: +# 86400) +# bantime= + +# Bind to given address and always listen on it. Use [host]:port notation +# for IPv6 +# bind= + +# Connect only to the specified node(s); -noconnect or -connect=0 alone to +# disable automatic connections +# connect= + +# Discover own IP addresses (default: 1 when listening and no -externalip +# or -proxy) +# discover=1 + +# Allow DNS lookups for -addnode, -seednode and -connect (default: 1) +# dns=1 + +# Query for peer addresses via DNS lookup, if low on addresses (default: 1 +# unless -connect/-noconnect) +# dnsseed=1 + +# Specify your own public address +# externalip= + +# Always query for peer addresses via DNS lookup (default: 0) +# forcednsseed=0 + +# Accept connections from outside (default: 1 if no -proxy or +# connect/-noconnect) +# listen=1 + +# Automatically create Tor hidden service (default: 1) +# listenonion=1 + +# Maintain at most connections to peers (default: 125) +# maxconnections=125 + +# Maximum per-connection receive buffer, *1000 bytes (default: 5000) +# maxreceivebuffer=5000 + +# Maximum per-connection send buffer, *1000 bytes (default: 1000) +# maxsendbuffer=1000 + +# Maximum allowed median peer time offset adjustment. Local perspective of +# time may be influenced by peers forward or backward by this +# amount. (default: 4200 seconds) +# maxtimeadjustment=4200 + +# Use separate SOCKS5 proxy to reach peers via Tor hidden services +# (default: -proxy) +# onion= + +# Only connect to nodes in network (ipv4, ipv6 or onion) +# onlynet= + +# Relay non-P2SH multisig (default: 1) +# permitbaremultisig=1 + +# Support filtering of blocks and transaction with bloom filters (default: +#0) +# peerbloomfilters=0 + +# Listen for connections on (default: 7042) +# port=7042 + +# Connect through SOCKS5 proxy +# proxy= + +# Randomize credentials for every proxy connection. This enables Tor +# tream isolation (default: 1) +# proxyrandomize=1 + +# Sets the serialization of raw transaction or block hex returned in +# non-verbose mode, non-segwit(0) or segwit(1) (default: 1) +# rpcserialversion=1 + +# Connect to a node to retrieve peer addresses, and disconnect +# seednode= + +# Specify connection timeout in milliseconds (minimum: 1, default: 5000) +# timeout=5000 + +# Tor control port to use if onion listening enabled (default: +# 127.0.0.1:9051) +# torcontrol=127.0.0.1:9051 + +# Tor control port password (default: empty) +# torpassword= + +# Use UPnP to map the listening port (default: 0) +# upnp=0 + +# Bind to given address and whitelist peers connecting to it. Use +# [host]:port notation for IPv6 +# whitebind= + +# Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or +# CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple +# times. Whitelisted peers cannot be DoS banned and their +# transactions are always relayed, even if they are already in the +# mempool, useful e.g. for a gateway +# whitelist= + +# Accept relayed transactions received from whitelisted peers even when +# not relaying transactions (default: 1) +# whitelistrelay=1 + +# Force relay of transactions from whitelisted peers even if they violate +# local relay policy (default: 1) +# whitelistforcerelay=1 + +# Tries to keep outbound traffic under the given target (in MiB per 24h), +# 0 = no limit (default: 0) +# maxuploadtarget=0 + +### Wallet options: + +# Do not load the wallet and disable wallet RPC calls +# disablewallet=0 + +# Set key pool size to (default: 100) +# keypool=100 + +# A fee rate (in BTC/kB) that will be used when fee estimation has +# insufficient data (default: 0.00001) +# fallbackfee=0.00001 + +# Fees (in BTC/kB) smaller than this are considered zero fee for +# transaction creation (default: 0.00001) +# mintxfee=0.00001 + +# Fee (in BTC/kB) to add to transactions you send (default: 0.00) +# paytxfee=0.00 + +# Rescan the block chain for missing wallet transactions on startup +# rescan=0 + +# Attempt to recover private keys from a corrupt wallet on startup +# salvagewallet=0 + +# Spend unconfirmed change when sending transactions (default: 1) +# pendzeroconfchange=0 + +# If paytxfee is not set, include enough fee so transactions begin +# confirmation on average within n blocks (default: 6) +# txconfirmtarget=6 + +# Use hierarchical deterministic key generation (HD) after BIP32. Only has +# effect during wallet creation/first start (default: 1) +# usehd=1 + +# Upgrade wallet to latest format on startup +# upgradewallet=0 + +# Specify wallet file (within data directory) (default: wallet.dat) +# wallet= + +# Make the wallet broadcast transactions (default: 1) +# walletbroadcast=1 + +# Execute command when a wallet transaction changes (%s in cmd is replaced +# by TxID) +# walletnotify= + +# Delete all wallet transactions and only recover those parts of the +# blockchain through -rescan on startup (1 = keep tx meta data e.g. +# account owner and payment request information, 2 = drop tx meta +# data) +# zapwallettxes= + +### ZeroMQ notification options: + +# Enable publish hash block in
+# zmqpubhashblock=
+ +# Enable publish hash transaction in
+# zmqpubhashtx=
+ +# Enable publish raw block in
+# zmqpubrawblock=
+ +# Enable publish raw transaction in
+# zmqpubrawtx=
+ +### Debugging/Testing options: + +# Append comment to the user agent string +# uacomment= + +# Output debugging information (default: 0, supplying is +# optional). If is not supplied or if = 1, +# output all debugging information. can be: addrman, +# alert, bench, cmpctblock, coindb, db, http, libevent, lock, +# mempool, mempoolrej, net, proxy, prune, rand, reindex, rpc, +# electcoins, tor, zmq. +# debug=0 + +### Show all debugging options (usage: --help -help-debug) +# help-debug + +# Include IP addresses in debug output (default: 0) +# logips=0 + +# Prepend debug output with timestamp (default: 1) +# logtimestamps=1 + +# Asset ID (hex) for mempool/relay fees (default: +# f44259d4fe4b055254b512efe86a88f44d3473039fbee77f6b21060b80c91464) +# feeasset= + +# Fees (in BTC/kB) smaller than this are considered zero fee for relaying, +# mining and transaction creation (default: 0.00001) +# minrelaytxfee=0.00001 + +# Maximum total fees (in BTC) to use in a single wallet transaction or raw +# transaction; setting this too low may abort large transactions +# (default: 0.10) +# maxtxfee=0.10 + +# Send trace/debug info to console instead of debug.log file +# printtoconsole=0 + +# Shrink debug.log file on client startup (default: 1 when no -debug) +# hrinkdebugfile=1 + +### Chain selection options: + +# Use the chain (default: liquidregtest). Anything except main is +# allowed +# chain= + +### Node relay options: + +# Equivalent bytes per sigop in transactions for relay and mining +# (default: 20) +# bytespersigop=20 + +### Relay and mine data carrier transactions (default: 1) +# datacarrier=1 + +# Maximum size of data in data carrier transactions we relay and mine +# (default: 83) +# datacarriersize=83 + +### Block creation options: + +# Set maximum BIP141 block weight (default: 4000000) +# blockmaxweight=4000000 + +# Set maximum block size in bytes (default: 1000000) +# blockmaxsize=1000000 + +# Set maximum size of high-priority/low-fee transactions in bytes +# (default: 200000) +# blockprioritysize=200000 + +# Set lowest fee rate (in BTC/kB) for transactions to be included in block +# creation. (default: 0.00001) +# blockmintxfee=0.00001 + +### RPC server options: + +# Accept command line and JSON-RPC commands +# server=1 + +# Accept public REST requests (default: 0) +# rest=0 + +# Bind to given address to listen for JSON-RPC connections. Use +# [host]:port notation for IPv6. This option can be specified +# multiple times (default: bind to all interfaces) +# rpcbind= + +# Location of the auth cookie (default: data dir) +# rpccookiefile= + +# Username for JSON-RPC connections +# rpcuser= + +# Password for JSON-RPC connections +# rpcpassword= + +# Username and hashed password for JSON-RPC connections. The field +# comes in the format: :$. A +# canonical python script is included in share/rpcuser. The client +# then connects normally using the +# rpcuser=/rpcpassword= pair of arguments. This +# option can be specified multiple times +# rpcauth= + +# Listen for JSON-RPC connections on (default: 8332) +# rpcport=8332 + +# Allow JSON-RPC connections from specified source. Valid for are a +# single IP (e.g. 1.2.3.4), a network/netmask (e.g. +# 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This +# option can be specified multiple times +# rpcallowip= + +# Set the number of threads to service RPC calls (default: 4) +# rpcthreads=4 + +### Federated peg options: + +# Validate pegin claims. All functionaries must run this. (default: 1) +# validatepegin=1 + +# The address which the daemon will try to connect to validate peg-ins, if +# enabled. (default: cookie auth) +# mainchainrpchost= + +# The port which the daemon will try to connect to validate peg-ins, if +# enabled. (default: cookie auth) +# mainchainrpcport= + +# The rpc username that the daemon will use to connect to validate +# peg-ins, if enabled. (default: cookie auth) +# mainchainrpcuser= + +# The rpc password which the daemon will use to connect to validate +# peg-ins, if enabled. (default: cookie auth) +# mainchainrpcpassword= + +# The bitcoind cookie auth path which the daemon will use to connect to +# validate peg-ins, if enabled. (default: default bitcoind datadir) +# mainchainrpccookiefile= + diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 17b4ee47de..bb31afe4aa 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -29,16 +29,16 @@ ???? CFBundleExecutable - Bitcoin-Qt + Elements-Qt CFBundleName - Bitcoin-Qt + Elements-Qt LSHasLocalizedDisplayName CFBundleIdentifier - org.bitcoinfoundation.Bitcoin-Qt + org.elementsproject.Elements-Qt CFBundleURLTypes diff --git a/share/setup.nsi.in b/share/setup.nsi.in index b58a84e02d..ebd5836f41 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -10,8 +10,8 @@ SetCompressor /SOLID lzma !define URL @PACKAGE_URL@ # MUI Symbol Definitions -!define MUI_ICON "@abs_top_srcdir@/share/pixmaps/bitcoin.ico" -!define MUI_WELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" +!define MUI_ICON "@abs_top_srcdir@/src/qt/res/rendered_icons/bitcoin.ico" +!define MUI_WELCOMEFINISHPAGE_BITMAP "@abs_top_builddir@/src/qt/res/rendered_icons/nsis-wizard.bmp" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_RIGHT !define MUI_HEADERIMAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-header.bmp" @@ -23,7 +23,7 @@ SetCompressor /SOLID lzma !define MUI_FINISHPAGE_RUN "$WINDIR\explorer.exe" !define MUI_FINISHPAGE_RUN_PARAMETERS $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_builddir@/src/qt/res/rendered_icons/nsis-wizard.bmp" !define MUI_UNFINISHPAGE_NOAUTOCLOSE # Included files diff --git a/src/Makefile.am b/src/Makefile.am index a1f4620f41..f8b615459d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -626,6 +626,60 @@ if EMBEDDED_LEVELDB include Makefile.leveldb.include endif +# Rendered icons must be here, not in Makefile.qt.include, since they are distributed with the source tarball + +RES_RENDERED_ICON_SRC = qt/res/src/bitcoin.svg + +RES_RENDERED_ICONS = \ + qt/res/rendered_icons/about.png \ + qt/res/rendered_icons/bitcoin.ico \ + qt/res/rendered_icons/bitcoin_testnet.ico \ + qt/res/rendered_icons/bitcoin1024.png + +RES_ALL_RENDERED_ICONS = $(RES_RENDERED_ICONS) \ + qt/res/rendered_icons/about.svg \ + $(patsubst %,qt/res/rendered_icons/bitcoin%.png,16 32 48 256 512 1024) \ + qt/res/rendered_icons/bitcoin.icns \ + qt/res/rendered_icons/nsis-wizard.svg \ + qt/res/rendered_icons/nsis-wizard.bmp + +EXTRA_DIST += $(RES_RENDERED_ICON_SRC) $(RES_ALL_RENDERED_ICONS) + +if CAN_RENDER_ICONS + +qt/res/rendered_icons/about.png: qt/res/rendered_icons/about.svg + $(RSVG_CONVERT) -f png -d 142 -p 142 < $< | $(IMAGEMAGICK_CONVERT) - -crop 64x78+0+31 -bordercolor transparent -border 7x0 -colorspace Gray -strip $@ + +qt/res/rendered_icons/about.svg: qt/res/src/bitcoin.svg + @$(MKDIR_P) $(@D) + sed '/fill="#000"/d;s/fill="[^"]*"//g' < $< > $@ + +qt/res/rendered_icons/bitcoin%.png: qt/res/src/bitcoin.svg + @$(MKDIR_P) $(@D) + $(RSVG_CONVERT) -f png -d $* -p $* < $< > $@ + +# NOTE: ImageMagick will never convert transparent PNGs to 8-bit ICOs, but GIF is fine +qt/res/rendered_icons/bitcoin%d8.gif: qt/res/rendered_icons/bitcoin%.png + $(IMAGEMAGICK_CONVERT) $^ -colors 256 -channel A -threshold '50%' $@ + +qt/res/rendered_icons/bitcoin.icns: $(patsubst %,qt/res/rendered_icons/bitcoin%.png,256 512 1024 32 16) + $(PNG2ICNS) $@ $^ + +qt/res/rendered_icons/bitcoin.ico: qt/res/rendered_icons/bitcoin32d8.gif $(patsubst %,qt/res/rendered_icons/bitcoin%.png,256 64 48 32 20 16) + $(IMAGEMAGICK_CONVERT) $^ $@ + +qt/res/rendered_icons/bitcoin_testnet.ico: qt/res/rendered_icons/bitcoin.ico + $(IMAGEMAGICK_CONVERT) $^ -modulate 100,87,9 $@ + +qt/res/rendered_icons/nsis-wizard.svg: qt/res/src/bitcoin.svg + @$(MKDIR_P) $(@D) + sed '/fill="#000"/d' < $< > $@ + +qt/res/rendered_icons/nsis-wizard.bmp: qt/res/rendered_icons/nsis-wizard.svg + $(RSVG_CONVERT) -f png -d 360 -p 360 < $< | $(IMAGEMAGICK_CONVERT) - -crop 164x290+0+35 -border 0x12 -strip BMP3:$@ + +endif + if ENABLE_TESTS include Makefile.test.include endif diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index c7a1963135..d529169d0d 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -2,7 +2,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -bin_PROGRAMS += qt/bitcoin-qt +bin_PROGRAMS += qt/elements-qt EXTRA_LIBRARIES += qt/libbitcoinqt.a # bitcoin qt core # @@ -175,6 +175,7 @@ QT_MOC = \ QT_QRC_CPP = qt/qrc_bitcoin.cpp QT_QRC = qt/bitcoin.qrc +QT_QRC_BUILD = qt/qrc_bitcoin_build.qrc QT_QRC_LOCALE_CPP = qt/qrc_bitcoin_locale.cpp QT_QRC_LOCALE = qt/bitcoin_locale.qrc @@ -237,14 +238,10 @@ BITCOIN_QT_H = \ qt/walletview.h \ qt/winshutdownmonitor.h -RES_ICONS = \ +RES_ICONS = $(RES_RENDERED_ICONS) \ qt/res/icons/add.png \ qt/res/icons/address-book.png \ - qt/res/icons/about.png \ qt/res/icons/about_qt.png \ - qt/res/icons/bitcoin.ico \ - qt/res/icons/bitcoin_testnet.ico \ - qt/res/icons/bitcoin.png \ qt/res/icons/chevron.png \ qt/res/icons/clock1.png \ qt/res/icons/clock2.png \ @@ -382,7 +379,7 @@ QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI: # Most files will depend on the forms and moc files as includes. Generate them # before anything else. $(QT_MOC): $(QT_FORMS_H) -$(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) : | $(QT_MOC) +$(qt_libbitcoinqt_a_OBJECTS) $(qt_elements_qt_OBJECTS) : | $(QT_MOC) #Generating these with a half-written protobuf header leads to wacky results. #This makes sure it's done. @@ -390,29 +387,29 @@ $(QT_MOC): $(PROTOBUF_H) $(QT_MOC_CPP): $(PROTOBUF_H) # bitcoin-qt binary # -qt_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ +qt_elements_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) -qt_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) +qt_elements_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) -qt_bitcoin_qt_SOURCES = qt/bitcoin.cpp +qt_elements_qt_SOURCES = qt/bitcoin.cpp if TARGET_DARWIN - qt_bitcoin_qt_SOURCES += $(BITCOIN_MM) + qt_elements_qt_SOURCES += $(BITCOIN_MM) endif if TARGET_WINDOWS - qt_bitcoin_qt_SOURCES += $(BITCOIN_RC) + qt_elements_qt_SOURCES += $(BITCOIN_RC) endif -qt_bitcoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) +qt_elements_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) if ENABLE_WALLET -qt_bitcoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) +qt_elements_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) endif if ENABLE_ZMQ -qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +qt_elements_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif -qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ +qt_elements_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -qt_bitcoin_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX +qt_elements_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +qt_elements_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX #locale/foo.ts -> locale/foo.qm QT_QM=$(QT_TS:.ts=.qm) @@ -434,19 +431,22 @@ $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ @rm $(@D)/temp_$("$@" + +$(QT_QRC_CPP): $(QT_QRC_BUILD) $(QT_FORMS_H) $(RES_ICONS) $(RES_IMAGES) $(RES_MOVIES) $(PROTOBUF_H) @test -f $(RCC) $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(RCC) -name bitcoin $< | \ $(SED) -e '/^\*\*.*Created:/d' -e '/^\*\*.*by:/d' > $@ -CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_bitcoin_locale.qrc +CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_bitcoin_locale.qrc $(QT_QRC_BUILD) CLEANFILES += $(CLEAN_QT) -bitcoin_qt_clean: FORCE - rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_bitcoin_qt_OBJECTS) qt/bitcoin-qt$(EXEEXT) $(LIBBITCOINQT) +elements_qt_clean: FORCE + rm -f $(CLEAN_QT) $(qt_libbitcoinqt_a_OBJECTS) $(qt_elements_qt_OBJECTS) qt/elements-qt$(EXEEXT) $(LIBBITCOINQT) -bitcoin_qt : qt/bitcoin-qt$(EXEEXT) +elements_qt : qt/elements-qt$(EXEEXT) ui_%.h: %.ui @test -f $(UIC) diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 4b14212b2e..2849ada759 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -2,8 +2,8 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -bin_PROGRAMS += qt/test/test_bitcoin-qt -TESTS += qt/test/test_bitcoin-qt +bin_PROGRAMS += qt/test/test_elements-qt +TESTS += qt/test/test_elements-qt TEST_QT_MOC_CPP = \ qt/test/moc_compattests.cpp \ @@ -33,10 +33,10 @@ TEST_BITCOIN_CPP = \ TEST_BITCOIN_H = \ test/test_bitcoin.h -qt_test_test_bitcoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ +qt_test_test_elements_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) -qt_test_test_bitcoin_qt_SOURCES = \ +qt_test_test_elements_qt_SOURCES = \ qt/test/compattests.cpp \ qt/test/rpcnestedtests.cpp \ qt/test/test_main.cpp \ @@ -46,37 +46,37 @@ qt_test_test_bitcoin_qt_SOURCES = \ $(TEST_BITCOIN_CPP) \ $(TEST_BITCOIN_H) if ENABLE_WALLET -qt_test_test_bitcoin_qt_SOURCES += \ +qt_test_test_elements_qt_SOURCES += \ qt/test/addressbooktests.cpp \ qt/test/paymentservertests.cpp \ qt/test/wallettests.cpp \ wallet/test/wallet_test_fixture.cpp endif -nodist_qt_test_test_bitcoin_qt_SOURCES = $(TEST_QT_MOC_CPP) +nodist_qt_test_test_elements_qt_SOURCES = $(TEST_QT_MOC_CPP) -qt_test_test_bitcoin_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) +qt_test_test_elements_qt_LDADD = $(LIBBITCOINQT) $(LIBBITCOIN_SERVER) if ENABLE_WALLET -qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) +qt_test_test_elements_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) endif if ENABLE_ZMQ -qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) +qt_test_test_elements_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif -qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ +qt_test_test_elements_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -qt_test_test_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) +qt_test_test_elements_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +qt_test_test_elements_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno CLEANFILES += $(CLEAN_BITCOIN_QT_TEST) -test_bitcoin_qt : qt/test/test_bitcoin-qt$(EXEEXT) +test_elements_qt : qt/test/test_elements-qt$(EXEEXT) -test_bitcoin_qt_check : qt/test/test_bitcoin-qt$(EXEEXT) FORCE +test_elements_qt_check : qt/test/test_elements-qt$(EXEEXT) FORCE $(MAKE) check-TESTS TESTS=$^ -test_bitcoin_qt_clean: FORCE - rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_bitcoin_qt_OBJECTS) +test_elements_qt_clean: FORCE + rm -f $(CLEAN_BITCOIN_QT_TEST) $(qt_test_test_elements_qt_OBJECTS) diff --git a/src/asset.cpp b/src/asset.cpp index 9831c7ea5c..70c5a91154 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -121,6 +121,14 @@ bool operator!=(const CAmountMap& a, const CAmountMap& b) return !(a == b); } +bool operator!(const CAmountMap& a) +{ + for (const auto& it : a) { + if (it.second) return false; + } + return true; +} + bool hasNegativeValue(const CAmountMap& amount) { for(std::map::const_iterator it = amount.begin(); it != amount.end(); ++it) { diff --git a/src/asset.h b/src/asset.h index 381df84c4f..483170df32 100644 --- a/src/asset.h +++ b/src/asset.h @@ -93,6 +93,7 @@ bool operator>(const CAmountMap& a, const CAmountMap& b); bool operator>=(const CAmountMap& a, const CAmountMap& b); bool operator==(const CAmountMap& a, const CAmountMap& b); bool operator!=(const CAmountMap& a, const CAmountMap& b); +bool operator!(const CAmountMap& a); // Check if all values are 0 inline bool MoneyRange(const CAmountMap& mapValue) { for(CAmountMap::const_iterator it = mapValue.begin(); it != mapValue.end(); it++) { diff --git a/src/assetsdir.cpp b/src/assetsdir.cpp index 0b897828a3..8ac47edd47 100644 --- a/src/assetsdir.cpp +++ b/src/assetsdir.cpp @@ -72,6 +72,13 @@ std::string CAssetsDir::GetLabel(const CAsset& asset) const return GetMetadata(asset).GetLabel(); } +std::string CAssetsDir::GetIdentifier(const CAsset& asset) const +{ + const std::string label = GetMetadata(asset).GetLabel(); + if (!label.empty()) return label; + return asset.GetHex(); +} + std::vector CAssetsDir::GetKnownAssets() const { std::vector knownAssets; diff --git a/src/assetsdir.h b/src/assetsdir.h index 0c6e6814ca..798e5395f5 100644 --- a/src/assetsdir.h +++ b/src/assetsdir.h @@ -40,6 +40,9 @@ class CAssetsDir /** @return the label associated to the asset id */ std::string GetLabel(const CAsset& asset) const; + /** @return the label associated to the asset id, or some other identifier */ + std::string GetIdentifier(const CAsset& asset) const; + std::vector GetKnownAssets() const; }; diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 5d9eaea6d0..cfb6447bd1 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -12,7 +12,7 @@ * for both bitcoind and bitcoin-qt, to make it harder for attackers to * target servers or GUI users specifically. */ -const std::string CLIENT_NAME("Satoshi"); +const std::string CLIENT_NAME("Elements Core"); /** * Client version number diff --git a/src/init.cpp b/src/init.cpp index dc7a0d39d0..fd0d02af64 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1873,7 +1873,9 @@ bool AppInitMain() } uiInterface.InitMessage(_("Awaiting mainchain RPC warmup")); if (!MainchainRPCCheck(true)) { //Initial check, fail immediately - return InitError(_("ERROR: elementsd is set to verify pegins but cannot get valid response from the mainchain daemon. Please check debug.log for more information.")); + return InitError(_("ERROR: elementsd is set to verify pegins but cannot get valid response from the mainchain daemon. Please check debug.log for more information.") + + "\n\n" + + strprintf(_("If you haven't setup a %s please get the latest stable version from %s or if you do not need to validate pegins set in your elements configuration %s"), "bitcoind", "https://bitcoincore.org/en/download/", "validatepegin=0")); } uiInterface.InitMessage(_("Done loading")); diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 74c03c1399..af06b8d7a7 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -61,8 +61,14 @@ static WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) EXCLUSIVE_LO WalletTx result; result.tx = wtx.tx; result.txin_is_mine.reserve(wtx.tx->vin.size()); - for (const auto& txin : wtx.tx->vin) { + result.txin_issuance_asset.resize(wtx.tx->vin.size()); + result.txin_issuance_token.resize(wtx.tx->vin.size()); + for (unsigned int i = 0; i < wtx.tx->vin.size(); ++i) { + const auto& txin = wtx.tx->vin[i]; result.txin_is_mine.emplace_back(wallet.IsMine(txin)); + wtx.GetIssuanceAssets(i, &result.txin_issuance_asset[i], &result.txin_issuance_token[i]); + result.txin_issuance_asset_amount.emplace_back(wtx.GetIssuanceAmount(i, false)); + result.txin_issuance_token_amount.emplace_back(wtx.GetIssuanceAmount(i, true)); } result.txout_is_mine.reserve(wtx.tx->vout.size()); result.txout_address.reserve(wtx.tx->vout.size()); @@ -73,6 +79,12 @@ static WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) EXCLUSIVE_LO result.txout_address_is_mine.emplace_back(ExtractDestination(txout.scriptPubKey, result.txout_address.back()) ? IsMine(wallet, result.txout_address.back()) : ISMINE_NO); + result.txout_is_change.push_back(wallet.IsChange(txout)); + } + // ELEMENTS: Retrieve unblinded information about outputs + for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) { + result.txout_amounts.emplace_back(wtx.GetOutputValueOut(i)); + result.txout_assets.emplace_back(wtx.GetOutputAsset(i)); } result.credit = wtx.GetCredit(ISMINE_ALL); result.debit = wtx.GetDebit(ISMINE_ALL); @@ -181,6 +193,10 @@ class WalletImpl : public Wallet return result; } void learnRelatedScripts(const CPubKey& key, OutputType type) override { m_wallet.LearnRelatedScripts(key, type); } + CPubKey getBlindingPubKey(const CScript& script) override + { + return m_wallet.GetBlindingPubKey(script); + } bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override { LOCK(m_wallet.cs_wallet); @@ -220,14 +236,25 @@ class WalletImpl : public Wallet bool sign, int& change_pos, CAmount& fee, + std::vector& out_amounts, std::string& fail_reason) override { LOCK2(cs_main, m_wallet.cs_wallet); auto pending = MakeUnique(m_wallet); + // Pad change keys to cover total possible number of assets + // One already exists(for policyAsset), so one for each destination + std::set assets_seen; + for (const auto& rec : recipients) { + if (assets_seen.insert(rec.asset).second) { + pending->m_keys.emplace_back(new CReserveKey(&m_wallet)); + } + } + BlindDetails blind_details; if (!m_wallet.CreateTransaction(recipients, pending->m_tx, pending->m_keys, fee, change_pos, - fail_reason, coin_control, sign)) { + fail_reason, coin_control, sign, g_con_elementsmode ? &blind_details : nullptr)) { return {}; } + out_amounts = blind_details.o_amounts; return std::move(pending); } bool transactionCanBeAbandoned(const uint256& txid) override { return m_wallet.TransactionCanBeAbandoned(txid); } diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index e9f8d31975..3ad1fc667f 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -111,6 +111,9 @@ class Wallet //! database can detect payments to newer address types. virtual void learnRelatedScripts(const CPubKey& key, OutputType type) = 0; + //! Get blinding pubkey for script + virtual CPubKey getBlindingPubKey(const CScript& script) = 0; + //! Add dest data. virtual bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) = 0; @@ -138,6 +141,7 @@ class Wallet bool sign, int& change_pos, CAmount& fee, + std::vector& out_amounts, std::string& fail_reason) = 0; //! Return whether transaction can be abandoned. @@ -333,8 +337,15 @@ struct WalletTx CTransactionRef tx; std::vector txin_is_mine; std::vector txout_is_mine; + std::vector txout_is_change; std::vector txout_address; std::vector txout_address_is_mine; + std::vector txout_amounts; + std::vector txout_assets; + std::vector txin_issuance_asset_amount; + std::vector txin_issuance_asset; + std::vector txin_issuance_token_amount; + std::vector txin_issuance_token; CAmountMap credit; CAmountMap debit; CAmountMap change; diff --git a/src/qt/Makefile b/src/qt/Makefile index b9dcf0c599..98647296ec 100644 --- a/src/qt/Makefile +++ b/src/qt/Makefile @@ -1,9 +1,9 @@ .PHONY: FORCE all: FORCE - $(MAKE) -C .. bitcoin_qt test_bitcoin_qt + $(MAKE) -C .. elements_qt test_elements_qt clean: FORCE - $(MAKE) -C .. bitcoin_qt_clean test_bitcoin_qt_clean + $(MAKE) -C .. elements_qt_clean test_elements_qt_clean check: FORCE - $(MAKE) -C .. test_bitcoin_qt_check -bitcoin-qt bitcoin-qt.exe: FORCE - $(MAKE) -C .. bitcoin_qt + $(MAKE) -C .. test_elements_qt_check +elements-qt elements-qt.exe: FORCE + $(MAKE) -C .. elements_qt diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 26bdf60d4a..d7c88fbcf8 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -102,12 +102,12 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, switch(tab) { case SendingTab: - ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.")); + ui->labelExplanation->setText(tr("These are your %1 addresses for sending payments. Always check the amount and the receiving address before sending coins.").arg("Liquid")); ui->deleteAddress->setVisible(true); ui->newAddress->setVisible(true); break; case ReceivingTab: - ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.")); + ui->labelExplanation->setText(tr("These are your %1 addresses for receiving payments. It is recommended to use a new receiving address for each transaction.").arg("Liquid")); ui->deleteAddress->setVisible(false); ui->newAddress->setVisible(false); break; diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 2f88e15d21..784cc78ce5 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -380,7 +380,8 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con } } walletModel->wallet().learnRelatedScripts(newKey, address_type); - strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type)); + CPubKey blinding_pubkey = walletModel->wallet().getBlindingPubKey(GetScriptForDestination(GetDestinationForKey(newKey, address_type))); + strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type, blinding_pubkey)); } else { diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index fddc2a5685..1c9c9ba90a 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -1,6 +1,6 @@ - res/icons/bitcoin.png + res/rendered_icons/bitcoin1024.png res/icons/address-book.png res/icons/quit.png res/icons/send.png @@ -42,7 +42,7 @@ res/icons/debugwindow.png res/icons/open.png res/icons/info.png - res/icons/about.png + res/rendered_icons/about.png res/icons/about_qt.png res/icons/verify.png res/icons/warning.png diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index b68f3a439b..2fa32b0910 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -7,6 +7,10 @@ #include #include #include +#include + +#include +#include #include #include @@ -14,6 +18,8 @@ #include #include +Q_DECLARE_METATYPE(CAsset) + /** QSpinBox that uses fixed-point numbers internally and uses our own * formatting/parsing functions. */ @@ -25,8 +31,10 @@ class AmountSpinBox: public QAbstractSpinBox explicit AmountSpinBox(QWidget *parent): QAbstractSpinBox(parent), currentUnit(BitcoinUnits::BTC), - singleStep(100000) // satoshis + singleStep(0) { + current_asset = Params().GetConsensus().pegged_asset; + setAlignment(Qt::AlignRight); connect(lineEdit(), &QLineEdit::textEdited, this, &AmountSpinBox::valueChanged); @@ -48,42 +56,92 @@ class AmountSpinBox: public QAbstractSpinBox CAmount val = parse(input, &valid); if(valid) { - input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways); + input = GUIUtil::formatAssetAmount(current_asset, val, currentUnit, BitcoinUnits::separatorAlways, false); lineEdit()->setText(input); } } - CAmount value(bool *valid_out=0) const + int currentPeggedUnit() const + { + assert(current_asset == Params().GetConsensus().pegged_asset); + return currentUnit; + } + + std::pair value(bool *valid_out=0) const { - return parse(text(), valid_out); + return std::make_pair(current_asset, parse(text(), valid_out)); } - void setValue(const CAmount& value) + void setValue(const CAsset& asset, CAmount value) { - lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways)); + current_asset = asset; + lineEdit()->setText(GUIUtil::formatAssetAmount(asset, value, currentUnit, BitcoinUnits::separatorAlways, false)); Q_EMIT valueChanged(); } + inline void setValue(const std::pair& value) + { + setValue(value.first, value.second); + } + + void stepBy(int steps) { bool valid = false; - CAmount val = value(&valid); - val = val + steps * singleStep; - val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney()); + auto val = value(&valid); + CAmount currentSingleStep = singleStep; + if (!currentSingleStep) { + if (current_asset == Params().GetConsensus().pegged_asset) { + currentSingleStep = 100000; // satoshis + } else { + currentSingleStep = 100000000; // a whole asset + } + } + val.second = val.second + steps * singleStep; + val.second = qMax(val.second, CAmount(0)); + // FIXME: Add this back in when assets can have > MAX_MONEY + // if (val.first == Params().GetConsensus().pegged_asset) + { + val.second = qMin(val.second, BitcoinUnits::maxMoney()); + } setValue(val); } + void setDisplayUnit(const CAsset& asset) + { + if (asset == Params().GetConsensus().pegged_asset) { + setDisplayUnit(currentUnit); + return; + } + + // Only used for bitcoins -> other asset + // Leave the number alone, since the user probably intended it for this asset + + current_asset = asset; + Q_EMIT valueChanged(); + } + void setDisplayUnit(int unit) { bool valid = false; - CAmount val = value(&valid); + std::pair val = value(&valid); + const bool was_pegged = (val.first == Params().GetConsensus().pegged_asset); + current_asset = Params().GetConsensus().pegged_asset; currentUnit = unit; + if (!was_pegged) { + // Leave the text as-is, if it's valid + value(&valid); + if (!valid) { + clear(); + } + } else if(valid) setValue(val); else clear(); + Q_EMIT valueChanged(); } void setSingleStep(const CAmount& step) @@ -125,6 +183,7 @@ class AmountSpinBox: public QAbstractSpinBox } private: + CAsset current_asset; int currentUnit; CAmount singleStep; mutable QSize cachedMinimumSizeHint; @@ -137,11 +196,13 @@ class AmountSpinBox: public QAbstractSpinBox CAmount parse(const QString &text, bool *valid_out=0) const { CAmount val = 0; - bool valid = BitcoinUnits::parse(currentUnit, text, &val); + bool valid = GUIUtil::parseAssetAmount(current_asset, text, currentUnit, &val); if(valid) { - if(val < 0 || val > BitcoinUnits::maxMoney()) + // FIXME: Add this back in when assets can have > MAX_MONEY + if (val < 0 || (val > BitcoinUnits::maxMoney() /*&& current_asset == Params().GetConsensus().pegged_asset*/)) { valid = false; + } } if(valid_out) *valid_out = valid; @@ -173,13 +234,15 @@ class AmountSpinBox: public QAbstractSpinBox StepEnabled rv = 0; bool valid = false; - CAmount val = value(&valid); + const std::pair val = value(&valid); if(valid) { - if(val > 0) + if (val.second > 0) { rv |= StepDownEnabled; - if(val < BitcoinUnits::maxMoney()) + } + if (val.second < BitcoinUnits::maxMoney() || val.first != Params().GetConsensus().pegged_asset) { rv |= StepUpEnabled; + } } return rv; } @@ -190,8 +253,9 @@ class AmountSpinBox: public QAbstractSpinBox #include -BitcoinAmountField::BitcoinAmountField(QWidget *parent) : +BitcoinAmountField::BitcoinAmountField(std::set allowed_assets, QWidget *parent) : QWidget(parent), + m_allowed_assets(allowed_assets), amount(0) { amount = new AmountSpinBox(this); @@ -201,8 +265,11 @@ BitcoinAmountField::BitcoinAmountField(QWidget *parent) : QHBoxLayout *layout = new QHBoxLayout(this); layout->addWidget(amount); - unit = new QValueComboBox(this); - unit->setModel(new BitcoinUnits(this)); + unit = new QComboBox(this); + m_allowed_assets = allowed_assets; + for (const auto& asset : allowed_assets) { + addAssetChoice(asset); + } layout->addWidget(unit); layout->addStretch(1); layout->setContentsMargins(0,0,0,0); @@ -220,6 +287,11 @@ BitcoinAmountField::BitcoinAmountField(QWidget *parent) : unitChanged(unit->currentIndex()); } +BitcoinAmountField::BitcoinAmountField(QWidget *parent) : + BitcoinAmountField(std::set({Params().GetConsensus().pegged_asset}), parent) +{ +} + void BitcoinAmountField::clear() { amount->clear(); @@ -235,7 +307,7 @@ void BitcoinAmountField::setEnabled(bool fEnabled) bool BitcoinAmountField::validate() { bool valid = false; - value(&valid); + fullValue(&valid); setValid(valid); return valid; } @@ -265,14 +337,28 @@ QWidget *BitcoinAmountField::setupTabChain(QWidget *prev) return unit; } -CAmount BitcoinAmountField::value(bool *valid_out) const +std::pair BitcoinAmountField::fullValue(bool *valid_out) const { return amount->value(valid_out); } +void BitcoinAmountField::setFullValue(const CAsset& asset, const CAmount& value) +{ + amount->setValue(asset, value); + setDisplayUnit(asset); +} + +CAmount BitcoinAmountField::value(bool *valid_out) const +{ + std::pair val = amount->value(valid_out); + assert(val.first == Params().GetConsensus().pegged_asset); + return val.second; +} + void BitcoinAmountField::setValue(const CAmount& value) { - amount->setValue(value); + amount->setValue(Params().GetConsensus().pegged_asset, value); + setDisplayUnit(amount->currentPeggedUnit()); } void BitcoinAmountField::setReadOnly(bool fReadOnly) @@ -280,20 +366,105 @@ void BitcoinAmountField::setReadOnly(bool fReadOnly) amount->setReadOnly(fReadOnly); } +bool BitcoinAmountField::hasAssetChoice(const CAsset& asset) const +{ + if (asset == Params().GetConsensus().pegged_asset) { + return -1 != unit->findData(0, Qt::UserRole); + } + return -1 != unit->findData(QVariant::fromValue(asset), Qt::UserRole); +} + +void BitcoinAmountField::addAssetChoice(const CAsset& asset) +{ + if (asset == Params().GetConsensus().pegged_asset) { + // Special handling + for (const auto& pegged_unit : BitcoinUnits::availableUnits()) { + unit->addItem(BitcoinUnits::shortName(pegged_unit), int(pegged_unit)); + } + return; + } + unit->addItem(QString::fromStdString(gAssetsDir.GetIdentifier(asset)), QVariant::fromValue(asset)); +} + +void BitcoinAmountField::removeAssetChoice(const CAsset& asset) +{ + if (asset == Params().GetConsensus().pegged_asset) { + // Special handling + for (const auto& pegged_unit : BitcoinUnits::availableUnits()) { + unit->removeItem(unit->findData(int(pegged_unit), Qt::UserRole)); + } + return; + } + unit->removeItem(unit->findData(QVariant::fromValue(asset), Qt::UserRole)); +} + +void BitcoinAmountField::setAllowedAssets(const std::set& allowed_assets) +{ + std::set assets_to_remove; + for (const auto& asset : m_allowed_assets) { + if (!allowed_assets.count(asset)) { + assets_to_remove.insert(asset); + } + } + m_allowed_assets = allowed_assets; + const QVariant& sel_userdata = unit->itemData(unit->currentIndex(), Qt::UserRole); + const CAsset sel_asset = (sel_userdata.type() == QVariant::UserType) ? sel_userdata.value() : Params().GetConsensus().pegged_asset; + for (const auto& asset : assets_to_remove) { + // Leave it in place for now if it's selected + if (sel_asset == asset) continue; + + removeAssetChoice(asset); + } + for (const auto& asset : allowed_assets) { + if (!hasAssetChoice(asset)) { + addAssetChoice(asset); + } + } +} + void BitcoinAmountField::unitChanged(int idx) { + const CAsset previous_asset = amount->value().first; + // Use description tooltip for current unit for the combobox - unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString()); + const QVariant& userdata = unit->itemData(idx, Qt::UserRole); + if (userdata.type() == QVariant::UserType) { + const CAsset asset = userdata.value(); + unit->setToolTip(tr("Custom asset (%1)").arg(QString::fromStdString(asset.GetHex()))); + + amount->setDisplayUnit(asset); + } else { + // Determine new unit ID + int newUnit = userdata.toInt(); - // Determine new unit ID - int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt(); + unit->setToolTip(BitcoinUnits::description(newUnit)); - amount->setDisplayUnit(newUnit); + amount->setDisplayUnit(newUnit); + } + + if (!(m_allowed_assets.count(previous_asset) || amount->value().first == previous_asset)) { + removeAssetChoice(previous_asset); + } +} + +void BitcoinAmountField::setDisplayUnit(const CAsset& asset) +{ + if (asset == Params().GetConsensus().pegged_asset) { + setDisplayUnit(amount->currentPeggedUnit()); + return; + } + if (!hasAssetChoice(asset)) { + addAssetChoice(asset); + } + unit->setCurrentIndex(unit->findData(QVariant::fromValue(asset), Qt::UserRole)); } void BitcoinAmountField::setDisplayUnit(int newUnit) { - unit->setValue(newUnit); + if (!hasAssetChoice(Params().GetConsensus().pegged_asset)) { + addAssetChoice(Params().GetConsensus().pegged_asset); + } + unit->setCurrentIndex(unit->findData(newUnit, Qt::UserRole)); } void BitcoinAmountField::setSingleStep(const CAmount& step) diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index f93579c492..cb3b3c98cf 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -6,13 +6,15 @@ #define BITCOIN_QT_BITCOINAMOUNTFIELD_H #include +#include +#include #include class AmountSpinBox; QT_BEGIN_NAMESPACE -class QValueComboBox; +class QComboBox; QT_END_NAMESPACE /** Widget for entering bitcoin amounts. @@ -26,8 +28,12 @@ class BitcoinAmountField: public QWidget Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY valueChanged USER true) public: + explicit BitcoinAmountField(std::set allowed_assets, QWidget *parent = 0); explicit BitcoinAmountField(QWidget *parent = 0); + std::pair fullValue(bool *valid=0) const; + void setFullValue(const CAsset& asset, const CAmount& value); + CAmount value(bool *value=0) const; void setValue(const CAmount& value); @@ -42,7 +48,10 @@ class BitcoinAmountField: public QWidget /** Perform input validation, mark field as invalid if entered value is not valid. */ bool validate(); + void setAllowedAssets(const std::set& allowed_assets); + /** Change unit used to display amount. */ + void setDisplayUnit(const CAsset&); void setDisplayUnit(int unit); /** Make field empty and ready for new input. */ @@ -64,8 +73,14 @@ class BitcoinAmountField: public QWidget bool eventFilter(QObject *object, QEvent *event); private: + std::set m_allowed_assets; + CAsset asset; AmountSpinBox *amount; - QValueComboBox *unit; + QComboBox *unit; + + bool hasAssetChoice(const CAsset&) const; + void addAssetChoice(const CAsset&); + void removeAssetChoice(const CAsset&); private Q_SLOTS: void unitChanged(int idx); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 51aff08c42..fc7761af7d 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -242,7 +242,7 @@ void BitcoinGUI::createActions() tabGroup->addAction(overviewAction); sendCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/send"), tr("&Send"), this); - sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address")); + sendCoinsAction->setStatusTip(tr("Send coins to a %1 address").arg("Liquid")); sendCoinsAction->setToolTip(sendCoinsAction->statusTip()); sendCoinsAction->setCheckable(true); sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2)); @@ -253,7 +253,7 @@ void BitcoinGUI::createActions() sendCoinsMenuAction->setToolTip(sendCoinsMenuAction->statusTip()); receiveCoinsAction = new QAction(platformStyle->SingleColorIcon(":/icons/receiving_addresses"), tr("&Receive"), this); - receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and bitcoin: URIs)")); + receiveCoinsAction->setStatusTip(tr("Request payments (generates QR codes and %1 addresses)").arg("Liquid")); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); receiveCoinsAction->setCheckable(true); receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); @@ -313,9 +313,9 @@ void BitcoinGUI::createActions() changePassphraseAction = new QAction(platformStyle->TextColorIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption")); signMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/edit"), tr("Sign &message..."), this); - signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them")); + signMessageAction->setStatusTip(tr("Sign messages with your %1 addresses to prove you own them").arg("Liquid")); verifyMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/verify"), tr("&Verify message..."), this); - verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses")); + verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified %1 addresses").arg("Liquid")); openRPCConsoleAction = new QAction(platformStyle->TextColorIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); @@ -328,11 +328,11 @@ void BitcoinGUI::createActions() usedReceivingAddressesAction->setStatusTip(tr("Show the list of used receiving addresses and labels")); openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this); - openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); + openAction->setStatusTip(tr("Open a payment request")); showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setMenuRole(QAction::NoRole); - showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(tr(PACKAGE_NAME))); + showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible command-line options").arg(tr(PACKAGE_NAME))); connect(quitAction, &QAction::triggered, qApp, QApplication::quit); connect(aboutAction, &QAction::triggered, this, &BitcoinGUI::aboutClicked); @@ -739,7 +739,7 @@ void BitcoinGUI::updateNetworkState() QString tooltip; if (m_node.getNetworkActive()) { - tooltip = tr("%n active connection(s) to Bitcoin network", "", count) + QString(".
") + tr("Click to disable network activity."); + tooltip = tr("%n active connection(s) to %1 network", "", count).arg("Liquid") + QString(".
") + tr("Click to disable network activity."); } else { tooltip = tr("Network activity disabled.") + QString("
") + tr("Click to enable network activity again."); icon = ":/icons/network_disabled"; @@ -894,7 +894,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret) { - QString strTitle = tr("Bitcoin"); // default title + QString strTitle = tr(PACKAGE_NAME); // default title // Default to information icon int nMBoxIcon = QMessageBox::Information; int nNotifyIcon = Notificator::Information; @@ -1008,11 +1008,11 @@ void BitcoinGUI::showEvent(QShowEvent *event) } #ifdef ENABLE_WALLET -void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName) +void BitcoinGUI::incomingTransaction(const QString& date, const QString& assetamount_str, const QString& type, const QString& address, const QString& label, const QString& walletName) { // On new transaction, make an info balloon QString msg = tr("Date: %1\n").arg(date) + - tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)); + tr("Amount: %1\n").arg(assetamount_str); if (m_node.getWallets().size() > 1 && !walletName.isEmpty()) { msg += tr("Wallet: %1\n").arg(walletName); } @@ -1021,7 +1021,7 @@ void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmoun msg += tr("Label: %1\n").arg(label); else if (!address.isEmpty()) msg += tr("Address: %1\n").arg(address); - message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"), + message(assetamount_str.startsWith("-") ? tr("Sent transaction") : tr("Incoming transaction"), msg, CClientUIInterface::MSG_INFORMATION); } #endif // ENABLE_WALLET diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index dcaca10557..dc461173c1 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -221,7 +221,7 @@ public Q_SLOTS: bool handlePaymentRequest(const SendCoinsRecipient& recipient); /** Show incoming transaction notification for new transactions. */ - void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName); + void incomingTransaction(const QString& date, const QString& assetamount_str, const QString& type, const QString& address, const QString& label, const QString& walletName); #endif // ENABLE_WALLET private: diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 8aa1fdba4d..e9af8bbb5d 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -42,10 +42,10 @@ QString BitcoinUnits::longName(int unit) { switch(unit) { - case BTC: return QString("BTC"); - case mBTC: return QString("mBTC"); - case uBTC: return QString::fromUtf8("µBTC (bits)"); - case SAT: return QString("Satoshi (sat)"); + case BTC: return QString("L-BTC"); + case mBTC: return QString("mL-BTC"); + case uBTC: return QString::fromUtf8("μL-BTC"); + case SAT: return QString("Satoshi (L-sat)"); default: return QString("???"); } } @@ -54,8 +54,8 @@ QString BitcoinUnits::shortName(int unit) { switch(unit) { - case uBTC: return QString::fromUtf8("bits"); - case SAT: return QString("sat"); + case uBTC: return QString::fromUtf8("L-bits"); + case SAT: return QString("L-sat"); default: return longName(unit); } } diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp index 0b0b96b30c..01b946c16c 100644 --- a/src/qt/editaddressdialog.cpp +++ b/src/qt/editaddressdialog.cpp @@ -108,7 +108,7 @@ void EditAddressDialog::accept() break; case AddressTableModel::INVALID_ADDRESS: QMessageBox::warning(this, windowTitle(), - tr("The entered address \"%1\" is not a valid Bitcoin address.").arg(ui->addressEdit->text()), + tr("The entered address \"%1\" is not a valid %2 address.").arg(ui->addressEdit->text()).arg("Liquid"), QMessageBox::Ok, QMessageBox::Ok); break; case AddressTableModel::DUPLICATE_ADDRESS: diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui index b5a69c578d..03ccb658e1 100644 --- a/src/qt/forms/modaloverlay.ui +++ b/src/qt/forms/modaloverlay.ui @@ -130,7 +130,7 @@ QLabel { color: rgb(40,40,40); } - Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below. + Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the Liquid network, as detailed below. Qt::RichText @@ -149,7 +149,7 @@ QLabel { color: rgb(40,40,40); } - Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network. + Attempting to spend assets that are affected by not-yet-displayed transactions will not be accepted by the network. Qt::RichText diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 8f34e6bc82..8bde182d4f 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -252,7 +252,7 @@ - Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled. + Automatically open the Liquid client port on the router. This only works when your router supports UPnP and it is enabled. Map port using &UPnP @@ -272,7 +272,7 @@ - Connect to the Bitcoin network through a SOCKS5 proxy. + Connect to the Liquid network through a SOCKS5 proxy. &Connect through SOCKS5 proxy (default proxy): @@ -459,7 +459,7 @@ - Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor hidden services. + Connect to the Liquid network through a separate SOCKS5 proxy for Tor hidden services. Use separate SOCKS&5 proxy to reach peers via Tor hidden services: diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 710801ee96..c2f80ac60c 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -73,7 +73,7 @@ - The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + The displayed information may be out of date. Your wallet automatically synchronizes with the Liquid network after a connection is established, but this process has not completed yet. @@ -220,6 +220,9 @@ Total: + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -265,6 +268,9 @@ Immature: + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -332,6 +338,9 @@ Available: + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -389,6 +398,9 @@ Pending: + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + @@ -459,7 +471,7 @@ - The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet. + The displayed information may be out of date. Your wallet automatically synchronizes with the Liquid network after a connection is established, but this process has not completed yet. diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui index 2f916d0b44..066b932fc5 100644 --- a/src/qt/forms/receivecoinsdialog.ui +++ b/src/qt/forms/receivecoinsdialog.ui @@ -209,7 +209,7 @@ Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don't support them. When unchecked, an address compatible with older wallets will be created instead. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 6b31ddea90..11eb5fbe33 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -880,7 +880,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p - Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. + Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for transactions than the network can process. @@ -893,7 +893,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis p true - Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process. + Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for transactions than the network can process. (read the tooltip) diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 3c699abc6a..9fb9263a39 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -57,7 +57,7 @@ - The Bitcoin address to send the payment to + The Liquid address to send the payment to diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 04b03a5435..a25fa14d2f 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -48,7 +48,7 @@ static const int MAX_URI_LENGTH = 255; #define QAPP_ORG_NAME "Bitcoin" #define QAPP_ORG_DOMAIN "bitcoin.org" -#define QAPP_APP_NAME_DEFAULT "Bitcoin-Qt" -#define QAPP_APP_NAME_TESTNET "Bitcoin-Qt-testnet" +#define QAPP_APP_NAME_DEFAULT "Elements-Qt" +#define QAPP_APP_NAME_TESTNET "Elements-Qt-testnet" #endif // BITCOIN_QT_GUICONSTANTS_H diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 77d99ad307..19d136fe09 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -87,13 +88,15 @@ QFont fixedPitchFont() } // Just some dummy data to generate a convincing random-looking (but consistent) address -static const uint8_t dummydata[] = {0xeb,0x15,0x23,0x1d,0xfc,0xeb,0x60,0x92,0x58,0x86,0xb6,0x7d,0x06,0x52,0x99,0x92,0x59,0x15,0xae,0xb1,0x72,0xc0,0x66,0x47}; +static const uint8_t dummydata[33] = {3}; // Generate a dummy address with invalid CRC, starting with the network prefix. static std::string DummyAddress(const CChainParams ¶ms) { - std::vector sourcedata = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS); - sourcedata.insert(sourcedata.end(), dummydata, dummydata + sizeof(dummydata)); + std::vector sourcedata; + CPubKey dummy_key(&dummydata[0], &dummydata[33]); + ScriptHash script_dest(uint160(), dummy_key); + DecodeBase58(EncodeDestination(script_dest), sourcedata); for(int i=0; i<256; ++i) { // Try every trailing byte std::string s = EncodeBase58(sourcedata.data(), sourcedata.data() + sourcedata.size()); if (!IsValidDestinationString(s)) { @@ -111,7 +114,7 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) widget->setFont(fixedPitchFont()); // We don't want translators to use own addresses in translations // and this is the only place, where this address is supplied. - widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. %1)").arg( + widget->setPlaceholderText(QObject::tr("Enter a Liquid address (e.g. %1)").arg( QString::fromStdString(DummyAddress(Params())))); widget->setValidator(new BitcoinAddressEntryValidator(parent)); widget->setCheckValidator(new BitcoinAddressCheckValidator(parent)); @@ -119,6 +122,8 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent) bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) { + return false; // TODO + // return if URI is not valid or is no bitcoin: URI if(!uri.isValid() || uri.scheme() != QString("bitcoin")) return false; @@ -773,6 +778,61 @@ QString boostPathToQString(const fs::path &path) return QString::fromStdString(path.string(utf8)); } +QString formatAssetAmount(const CAsset& asset, const CAmount& amount, const int bitcoin_unit, BitcoinUnits::SeparatorStyle separators, bool include_asset_name) +{ + if (asset == Params().GetConsensus().pegged_asset) { + if (include_asset_name) { + return BitcoinUnits::formatWithUnit(bitcoin_unit, amount, false, separators); + } else { + return BitcoinUnits::format(bitcoin_unit, amount, false, separators); + } + } + + qlonglong abs = qAbs(amount); + qlonglong whole = abs / 100000000; + qlonglong fraction = abs % 100000000; + QString str = QString("%1").arg(whole); + if (amount < 0) { + str.insert(0, '-'); + } + if (fraction) { + str += QString(".%1").arg(fraction, 8, 10, QLatin1Char('0')); + } + if (include_asset_name) { + str += QString(" ") + QString::fromStdString(gAssetsDir.GetIdentifier(asset)); + } + return str; +} + +QString formatMultiAssetAmount(const CAmountMap& amountmap, const int bitcoin_unit, BitcoinUnits::SeparatorStyle separators, QString line_separator) +{ + QStringList ret; + if (bitcoin_unit >= 0) { + ret << formatAssetAmount(Params().GetConsensus().pegged_asset, amountmap.count(Params().GetConsensus().pegged_asset) ? amountmap.at(Params().GetConsensus().pegged_asset) : 0, bitcoin_unit, separators); + } + for (const auto& assetamount : amountmap) { + if (assetamount.first == Params().GetConsensus().pegged_asset) { + // Already handled first + continue; + } + if (!assetamount.second) { + // Don't include zero-amount assets + continue; + } + ret << formatAssetAmount(assetamount.first, assetamount.second, bitcoin_unit, separators); + } + return ret.join(line_separator); +} + +bool parseAssetAmount(const CAsset& asset, const QString& text, const int bitcoin_unit, CAmount *val_out) +{ + if (asset == Params().GetConsensus().pegged_asset) { + return BitcoinUnits::parse(bitcoin_unit, text, val_out); + } + + return BitcoinUnits::parse(BitcoinUnits::BTC, text, val_out); +} + QString formatDurationStr(int secs) { QStringList strList; diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 011827e134..d812b731c7 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -187,6 +189,15 @@ namespace GUIUtil /* Convert OS specific boost path to QString through UTF-8 */ QString boostPathToQString(const fs::path &path); + /* Format an amount of assets in a user-friendly style */ + QString formatAssetAmount(const CAsset&, const CAmount&, int bitcoin_unit, BitcoinUnits::SeparatorStyle, bool include_asset_name = true); + + /* Format one or more asset+amounts in a user-friendly style */ + QString formatMultiAssetAmount(const CAmountMap&, int bitcoin_unit, BitcoinUnits::SeparatorStyle, QString line_separator); + + /* Parse an amount of a given asset from text */ + bool parseAssetAmount(const CAsset&, const QString& text, int bitcoin_unit, CAmount *val_out); + /* Convert seconds into a QString with days, hours, mins, secs */ QString formatDurationStr(int secs); diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index b19cc17a4d..94885d59da 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -23,9 +23,9 @@ static const uint64_t GB_BYTES = 1000000000LL; /* Minimum free space (in GB) needed for data directory */ -constexpr uint64_t BLOCK_CHAIN_SIZE = 220; +constexpr uint64_t BLOCK_CHAIN_SIZE = 1; /* Minimum free space (in GB) needed for data directory when pruned; Does not include prune target */ -static const uint64_t CHAIN_STATE_SIZE = 3; +static const uint64_t CHAIN_STATE_SIZE = 0; /* Total required space (in GB) depending on user choice (prune, not prune) */ static uint64_t requiredSpace; diff --git a/src/qt/locale/bitcoin_af.ts b/src/qt/locale/bitcoin_af.ts index bff2db1d6a..ff5f311da2 100644 --- a/src/qt/locale/bitcoin_af.ts +++ b/src/qt/locale/bitcoin_af.ts @@ -1144,7 +1144,7 @@ Bedrag - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Voer in 'n Bitcoin adres (bv. %1) diff --git a/src/qt/locale/bitcoin_ar.ts b/src/qt/locale/bitcoin_ar.ts index 481e02c60e..6571c4e0fd 100644 --- a/src/qt/locale/bitcoin_ar.ts +++ b/src/qt/locale/bitcoin_ar.ts @@ -1350,7 +1350,7 @@ مبلغ - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) ادخل عنوان محفطة البتكوين (مثال %1) diff --git a/src/qt/locale/bitcoin_bg.ts b/src/qt/locale/bitcoin_bg.ts index be7fed59a1..fb098da63c 100644 --- a/src/qt/locale/bitcoin_bg.ts +++ b/src/qt/locale/bitcoin_bg.ts @@ -1136,7 +1136,7 @@ Сума - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Въведете Биткойн адрес (например: %1) diff --git a/src/qt/locale/bitcoin_ca.ts b/src/qt/locale/bitcoin_ca.ts index 2926736498..ba918349f1 100644 --- a/src/qt/locale/bitcoin_ca.ts +++ b/src/qt/locale/bitcoin_ca.ts @@ -1450,7 +1450,7 @@ Import - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Introduïu una adreça de Bitcoin (p. ex. %1) @@ -1926,7 +1926,7 @@ Les adreces segwit natives (més conegudes com Bech32 o BIP-173) redueixen les vostres comisions de les transaccions i ofereixen millor protecció contra errades tipogràfiques, però els moneders antics no les suporten. Quan desmarqui la casella, es generarà una adreça compatible amb moneders antics. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Generar una adreça segwit nativa (Bech32) diff --git a/src/qt/locale/bitcoin_ca@valencia.ts b/src/qt/locale/bitcoin_ca@valencia.ts index b5e65bc4bf..a80149abef 100644 --- a/src/qt/locale/bitcoin_ca@valencia.ts +++ b/src/qt/locale/bitcoin_ca@valencia.ts @@ -1148,7 +1148,7 @@ Import - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Introduïu una adreça de Bitcoin (p. ex. %1) diff --git a/src/qt/locale/bitcoin_ca_ES.ts b/src/qt/locale/bitcoin_ca_ES.ts index 03c5dd853e..0b8054bd23 100644 --- a/src/qt/locale/bitcoin_ca_ES.ts +++ b/src/qt/locale/bitcoin_ca_ES.ts @@ -1304,7 +1304,7 @@ Import - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Introduïu una adreça de Bitcoin (p. ex. %1) diff --git a/src/qt/locale/bitcoin_cs.ts b/src/qt/locale/bitcoin_cs.ts index 260d79b766..a470917fb9 100644 --- a/src/qt/locale/bitcoin_cs.ts +++ b/src/qt/locale/bitcoin_cs.ts @@ -1416,7 +1416,7 @@ Částka - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Zadej bitcoinovou adresu (např. %1) diff --git a/src/qt/locale/bitcoin_da.ts b/src/qt/locale/bitcoin_da.ts index c7a2422c8a..49125eaa6a 100644 --- a/src/qt/locale/bitcoin_da.ts +++ b/src/qt/locale/bitcoin_da.ts @@ -1450,7 +1450,7 @@ Beløb - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Indtast en Bitcoin-adresse (fx %1) @@ -1926,7 +1926,7 @@ Rene segwit-adresser (kendt som Bech32 eller BIP-173) reducerer dine transaktionsgebyrer i det lange løb og giver bedre beskyttelse imod tastefejl, men gamle tegnebøger understøtter dem ikke. Hvis dette ikke vælges, vil i stedet en adresse, der fungerer med ældre tegnebøger, oprettes. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Generér rene segwit-adresser (Bech32) diff --git a/src/qt/locale/bitcoin_de.ts b/src/qt/locale/bitcoin_de.ts index 06c1a54d40..70985043b4 100644 --- a/src/qt/locale/bitcoin_de.ts +++ b/src/qt/locale/bitcoin_de.ts @@ -1446,7 +1446,7 @@ Betrag - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Bitcoin-Adresse eingeben (z.B. %1) @@ -1922,7 +1922,7 @@ Ureigene SegWit-Adressen (alias Bech32 oder BIP-173) werden Ihre Transaktionsgebühren senken und bieten besseren Tippfehlerschutz, werden jedoch von alten Brieftaschen nicht unterstützt. Wenn abgewählt, wird eine mit älteren Brieftaschen kompatible Adresse erstellt. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Generiere ureigene SegWit(Bech32)-Adresse diff --git a/src/qt/locale/bitcoin_el_GR.ts b/src/qt/locale/bitcoin_el_GR.ts index ef4ac2d4aa..0df3d78f04 100644 --- a/src/qt/locale/bitcoin_el_GR.ts +++ b/src/qt/locale/bitcoin_el_GR.ts @@ -1096,7 +1096,7 @@ Ποσό - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Εισάγετε μια διεύθυνση Bitcoin (π.χ. %1) diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index fbff2d36a0..b16222dbf9 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1843,7 +1843,7 @@ - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) @@ -2496,7 +2496,7 @@ - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address diff --git a/src/qt/locale/bitcoin_en_GB.ts b/src/qt/locale/bitcoin_en_GB.ts index 7da223f52e..eb79abd7e4 100644 --- a/src/qt/locale/bitcoin_en_GB.ts +++ b/src/qt/locale/bitcoin_en_GB.ts @@ -1418,8 +1418,8 @@ Amount - Enter a Bitcoin address (e.g. %1) - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) + Enter a Liquid address (e.g. %1) %1 d diff --git a/src/qt/locale/bitcoin_es.ts b/src/qt/locale/bitcoin_es.ts index f55a7ce9c4..0c6506f9ac 100644 --- a/src/qt/locale/bitcoin_es.ts +++ b/src/qt/locale/bitcoin_es.ts @@ -1449,7 +1449,7 @@ Cantidad - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Introducir una dirección Bitcoin (p. ej. %1) @@ -1925,7 +1925,7 @@ Las direcciones segwit nativas (también conocidas como Bech32 o BIP-173) reducen las comisiones de transacción más adelante y ofrecen una mejor protección contra errores tipográficos, pero las billeteras antiguas no las admiten. Cuando no está marcada, se creará una dirección compatible con billeteras más antiguas. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Generar dirección segwit nativa (Bech32) diff --git a/src/qt/locale/bitcoin_es_CL.ts b/src/qt/locale/bitcoin_es_CL.ts index f8b13e398f..3a26d5fde2 100644 --- a/src/qt/locale/bitcoin_es_CL.ts +++ b/src/qt/locale/bitcoin_es_CL.ts @@ -1330,7 +1330,7 @@ Cantidad - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Ingresa una dirección de Bitcoin (Ejemplo: %1) diff --git a/src/qt/locale/bitcoin_es_ES.ts b/src/qt/locale/bitcoin_es_ES.ts index 1b196cb13f..00dadf2be8 100644 --- a/src/qt/locale/bitcoin_es_ES.ts +++ b/src/qt/locale/bitcoin_es_ES.ts @@ -1324,7 +1324,7 @@ Cantidad - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Introducir una dirección Bitcoin (p. ej. %1) diff --git a/src/qt/locale/bitcoin_fa.ts b/src/qt/locale/bitcoin_fa.ts index 1fa0d9fb44..6594dc0b87 100644 --- a/src/qt/locale/bitcoin_fa.ts +++ b/src/qt/locale/bitcoin_fa.ts @@ -1012,7 +1012,7 @@ مبلغ - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) یک آدرس بیت‌کوین وارد کنید (مثلاً %1) diff --git a/src/qt/locale/bitcoin_fi.ts b/src/qt/locale/bitcoin_fi.ts index 8df4871025..b11d2758b4 100644 --- a/src/qt/locale/bitcoin_fi.ts +++ b/src/qt/locale/bitcoin_fi.ts @@ -1404,7 +1404,7 @@ Määrä - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Syötä Bitcoin-osoite (esim. %1) diff --git a/src/qt/locale/bitcoin_fr.ts b/src/qt/locale/bitcoin_fr.ts index 5faba54d5b..aeaf0c31e9 100644 --- a/src/qt/locale/bitcoin_fr.ts +++ b/src/qt/locale/bitcoin_fr.ts @@ -1450,7 +1450,7 @@ Montant - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Saisir une adresse Bitcoin (p. ex. %1) @@ -1926,7 +1926,7 @@ Les adresses SegWit natives (aussi appelées Bech32 ou BIP-173) réduisent vos frais de transaction ultérieurs et offrent une meilleure protection contre les erreurs de frappe, mais les anciens porte-monnaie ne les prennent pas en charge. Si cette option n’est pas cochée, une adresse compatible avec les anciens porte-monnaie sera plutôt créée. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Générer une adresse SegWit native (Bech32) diff --git a/src/qt/locale/bitcoin_fr_FR.ts b/src/qt/locale/bitcoin_fr_FR.ts index 10582127c4..610421da31 100644 --- a/src/qt/locale/bitcoin_fr_FR.ts +++ b/src/qt/locale/bitcoin_fr_FR.ts @@ -1112,7 +1112,7 @@ Montant - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Entrer une adresse Bitcoin (e.g. %1) diff --git a/src/qt/locale/bitcoin_he.ts b/src/qt/locale/bitcoin_he.ts index cf884f0fc7..ae57bae72b 100644 --- a/src/qt/locale/bitcoin_he.ts +++ b/src/qt/locale/bitcoin_he.ts @@ -1426,7 +1426,7 @@ כמות - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) נא להזין כתובת ביטקוין (למשל: %1) @@ -1890,7 +1890,7 @@ כתובות segwit טבעיות (כלומר Bech32 או BIP-173) מפחיתות את עמלת העסקה שלכם בהמשך ומציעות הגנה נגד שגיאות כתיב, אך ארנקים ישנים לא תומכים בהן. אם לא סומן, כתובת תאימה לארנקים ישנים תיווצר במקום. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address הפקת כתובת segwit טבעית (Bech32) diff --git a/src/qt/locale/bitcoin_hu.ts b/src/qt/locale/bitcoin_hu.ts index 3a3990c265..60ebc60d69 100644 --- a/src/qt/locale/bitcoin_hu.ts +++ b/src/qt/locale/bitcoin_hu.ts @@ -1377,7 +1377,7 @@ Kérem a kulcsmondatban használjon <b> tíz vagy több véletlenszerű ka Összeg - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Ad meg egy Bitcoin címet (pl: %1) @@ -1817,7 +1817,7 @@ Kérem a kulcsmondatban használjon <b> tíz vagy több véletlenszerű ka Segwit címek (Bech32 vagy BIP-173) csökkentik a tranzakciók díját és jobb védelmet biztosítanak gépelési hibával szemben, de a régi pénztárcák nem támogatják. Ha nincs aktiválva, egy régi pénztárcával is kompatibilis cím lesz létrehozva. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Segwit cím (Bech32) létrehozása diff --git a/src/qt/locale/bitcoin_id_ID.ts b/src/qt/locale/bitcoin_id_ID.ts index 3c79d54e94..98daafc0ad 100644 --- a/src/qt/locale/bitcoin_id_ID.ts +++ b/src/qt/locale/bitcoin_id_ID.ts @@ -1212,7 +1212,7 @@ Nilai - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Masukkan alamat Bitcoin (contoh %1) diff --git a/src/qt/locale/bitcoin_it.ts b/src/qt/locale/bitcoin_it.ts index 5b24fcdf46..734f120c68 100644 --- a/src/qt/locale/bitcoin_it.ts +++ b/src/qt/locale/bitcoin_it.ts @@ -1443,7 +1443,7 @@ Per specificare più URL separarli con una barra verticale "|". Importo - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Inserisci un indirizzo Bitcoin (ad es. %1) @@ -1907,7 +1907,7 @@ Per specificare più URL separarli con una barra verticale "|". Gli indirizzi nativi segwit (noti anche come Bech32 o BIP-173) riducono le spese di transazione e offrono una migliore protezione dagli errori di battitura, ma i vecchi portafogli non li supportano. Se deselezionata, verrà creato un indirizzo compatibile con i portafogli meno recenti. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Genera indirizzo nativo segwit (Bech32) diff --git a/src/qt/locale/bitcoin_ja.ts b/src/qt/locale/bitcoin_ja.ts index 284bdb39b5..16c9062e0f 100644 --- a/src/qt/locale/bitcoin_ja.ts +++ b/src/qt/locale/bitcoin_ja.ts @@ -1450,7 +1450,7 @@ 総額 - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Bitcoinアドレスを入力してください (例 %1) @@ -1926,7 +1926,7 @@ Segwitアドレス(Bech32もしくはBIP-173アドレス)を利用すると手数料が安くなり、また誤入力防止機能も強化されますが、Segwitアドレスをサポートしない古いウォレットとの互換性は失われます。チェックを外すと、古いウォレットとの互換性を保った古いアドレスが代わりに生成されます。 - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Segwitアドレス(Bech32アドレス)を生成する diff --git a/src/qt/locale/bitcoin_ko_KR.ts b/src/qt/locale/bitcoin_ko_KR.ts index 9912cc76e2..41be7cb22b 100644 --- a/src/qt/locale/bitcoin_ko_KR.ts +++ b/src/qt/locale/bitcoin_ko_KR.ts @@ -1450,7 +1450,7 @@ 거래액 - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) 비트코인 주소를 입력하기 (예. %1) @@ -1926,7 +1926,7 @@ Bech32 주소 (BIP-173)는 더 적은 수수료와 오입금으로부터 방지해 줍니다. Bech32가 비활성화 되어있으면 P2SH 기반의 세그윗 주소가 대신 생성됩니다. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Bech32 세그윗 주소 생성 diff --git a/src/qt/locale/bitcoin_nb.ts b/src/qt/locale/bitcoin_nb.ts index 89c8e4174b..73adc5342d 100644 --- a/src/qt/locale/bitcoin_nb.ts +++ b/src/qt/locale/bitcoin_nb.ts @@ -1404,7 +1404,7 @@ Beløp - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Oppgi en Bitcoin-adresse (f.eks. %1) diff --git a/src/qt/locale/bitcoin_ne.ts b/src/qt/locale/bitcoin_ne.ts index 4da7d64cee..aaf5ac5829 100644 --- a/src/qt/locale/bitcoin_ne.ts +++ b/src/qt/locale/bitcoin_ne.ts @@ -308,7 +308,7 @@ रकम - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) कृपया बिटकोइन ठेगाना प्रवेश गर्नुहोस् (उदाहरण %1) diff --git a/src/qt/locale/bitcoin_nl.ts b/src/qt/locale/bitcoin_nl.ts index 747a62510f..b731103544 100644 --- a/src/qt/locale/bitcoin_nl.ts +++ b/src/qt/locale/bitcoin_nl.ts @@ -1450,7 +1450,7 @@ Bedrag - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Voer een Bitcoinadres in (bijv. %1) @@ -1926,7 +1926,7 @@ Native segwit-adressen (Bech32 of BIP-173) reduceren later je transactiekosten en bieden een betere bescherming tegen typefouten, maar oude portemonnees ondersteunen deze niet. Een adres dat is compatibel met oudere portemonnees zal worden gecreëerd indien dit niet is aangevinkt. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Genereer native segwit-adres (Bech32) diff --git a/src/qt/locale/bitcoin_pl.ts b/src/qt/locale/bitcoin_pl.ts index a1437b8808..5700ed634f 100644 --- a/src/qt/locale/bitcoin_pl.ts +++ b/src/qt/locale/bitcoin_pl.ts @@ -1450,7 +1450,7 @@ Kwota - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Wprowadź adres bitcoinowy (np. %1) @@ -1926,7 +1926,7 @@ Natywne adresy segwit (aka Bech32 lub BIP-173) zmniejszają później twoje opłaty transakcyjne i dają lepsze zabezpieczenie przed literówkami, ale stare portfele ich nie obsługują. Jeżeli odznaczone, stworzony zostanie adres kompatybilny ze starszymi portfelami. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Wygeneruj natywny adres segwit (Bech32) diff --git a/src/qt/locale/bitcoin_pt_BR.ts b/src/qt/locale/bitcoin_pt_BR.ts index e964838d9f..acda653429 100644 --- a/src/qt/locale/bitcoin_pt_BR.ts +++ b/src/qt/locale/bitcoin_pt_BR.ts @@ -1446,7 +1446,7 @@ Quantidade - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Informe um endereço Bitcoin (ex: %1) @@ -1922,7 +1922,7 @@ Endereços segwit nativos (também conhecidos como Bench32 ou BIP-173) reduzem suas taxas de transação mais adiante e oferecem melhor proteção contra erros de digitação, porém carteiras antigas não têm suporte a eles. Quando não estiver rubricado, um endereço compatível com cateiras antigas será criado como alternativa. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Gere um endereço segwit (Bench32) nativo diff --git a/src/qt/locale/bitcoin_pt_PT.ts b/src/qt/locale/bitcoin_pt_PT.ts index 48068409be..46c6d4b4c8 100644 --- a/src/qt/locale/bitcoin_pt_PT.ts +++ b/src/qt/locale/bitcoin_pt_PT.ts @@ -1427,7 +1427,7 @@ Quantia - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Entre um endereço Bitcoin (ex. %1) @@ -1899,7 +1899,7 @@ Endereços nativos SegWit (também conhecidos como Bech32 ou BIP-173) reduzem as taxas da sua transação mais tarde e oferecem melhor protecção contra erros, mas carteiras antigas não os suportam. Quando não selecionado, um endereço compatível com carteiras antigas irá ser criado em vez. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Gerar endereço nativo SegWit (Bech32) diff --git a/src/qt/locale/bitcoin_ro_RO.ts b/src/qt/locale/bitcoin_ro_RO.ts index 503c15259b..293ad3d815 100644 --- a/src/qt/locale/bitcoin_ro_RO.ts +++ b/src/qt/locale/bitcoin_ro_RO.ts @@ -1426,7 +1426,7 @@ Cantitate - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Introduceţi o adresă Bitcoin (de exemplu %1) @@ -1878,7 +1878,7 @@ Adresele native segwit (aka Bech32 sau BIP-173) vor reduce mai tarziu comisioanele de tranzactionare si vor oferi o mai buna protectie impotriva introducerii gresite, dar portofelele vechi nu sunt compatibile. Daca optiunea nu e bifata, se va crea o adresa compatibila cu portofelele vechi. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Genereaza adresa nativa segwit (Bech32) diff --git a/src/qt/locale/bitcoin_ru_RU.ts b/src/qt/locale/bitcoin_ru_RU.ts index ea30f39969..ae99fef2f9 100644 --- a/src/qt/locale/bitcoin_ru_RU.ts +++ b/src/qt/locale/bitcoin_ru_RU.ts @@ -1126,7 +1126,7 @@ Количество - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Введите биткоин-адрес (напр. %1) diff --git a/src/qt/locale/bitcoin_sk.ts b/src/qt/locale/bitcoin_sk.ts index 6a69bfe63c..8d61e1d376 100644 --- a/src/qt/locale/bitcoin_sk.ts +++ b/src/qt/locale/bitcoin_sk.ts @@ -1430,7 +1430,7 @@ Suma - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Zadajte bitcoin adresu (napr. %1) @@ -1891,7 +1891,7 @@ Natívne segwit adresy (Bech32 or BIP-173) znižujú Vaše budúce transakčné poplatky and ponúkajú lepšiu ochranu pred preklepmi, avšak staré peňaženky ich nepodporujú. Ak je toto pole nezaškrtnuté, bude vytvorená adresa kompatibilná so staršími peňaženkami. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Generovať natívnu segwit adresu (Bech32) diff --git a/src/qt/locale/bitcoin_sl_SI.ts b/src/qt/locale/bitcoin_sl_SI.ts index 91080a774a..671eb7a250 100644 --- a/src/qt/locale/bitcoin_sl_SI.ts +++ b/src/qt/locale/bitcoin_sl_SI.ts @@ -1044,7 +1044,7 @@ Znesek - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Vnesite naslov Bitcoin (npr. %1): diff --git a/src/qt/locale/bitcoin_sv.ts b/src/qt/locale/bitcoin_sv.ts index d0fcef9297..1bf0cf8ff4 100644 --- a/src/qt/locale/bitcoin_sv.ts +++ b/src/qt/locale/bitcoin_sv.ts @@ -1401,7 +1401,7 @@ Var vänlig och försök igen. Mängd - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Ange en Bitcoin-adress (t.ex. %1) diff --git a/src/qt/locale/bitcoin_tr.ts b/src/qt/locale/bitcoin_tr.ts index b092ee060e..910b3bd472 100644 --- a/src/qt/locale/bitcoin_tr.ts +++ b/src/qt/locale/bitcoin_tr.ts @@ -1388,7 +1388,7 @@ Tutar - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Bir Bitcoin adresi giriniz (mesela %1) diff --git a/src/qt/locale/bitcoin_tr_TR.ts b/src/qt/locale/bitcoin_tr_TR.ts index cf119c65c2..dd29b95f7c 100644 --- a/src/qt/locale/bitcoin_tr_TR.ts +++ b/src/qt/locale/bitcoin_tr_TR.ts @@ -709,7 +709,7 @@ QObject - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Bitcoin adresinizi girin (örneğin %1) diff --git a/src/qt/locale/bitcoin_uk.ts b/src/qt/locale/bitcoin_uk.ts index 1865a84834..60e5f6a5b5 100644 --- a/src/qt/locale/bitcoin_uk.ts +++ b/src/qt/locale/bitcoin_uk.ts @@ -1436,7 +1436,7 @@ Кількість - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Введіть адресу Bitcoin (наприклад %1) @@ -1912,7 +1912,7 @@ Чиста сегвіт адреса (segwit, Bech32, BIP-173) знижує комісію та пропонує кращий захист від помилок, але старі гаманці її не підтримують. Якщо позначка знята, буде створено адресу, сумісну зі старими гаманцями. - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address Згенерувати чисту SegWit (Bech32) адресу diff --git a/src/qt/locale/bitcoin_uz@Cyrl.ts b/src/qt/locale/bitcoin_uz@Cyrl.ts index d369d4f16a..fe44bea1f7 100644 --- a/src/qt/locale/bitcoin_uz@Cyrl.ts +++ b/src/qt/locale/bitcoin_uz@Cyrl.ts @@ -674,7 +674,7 @@ Миқдори - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Bitcoin манзилини киритинг (масалан. %1) diff --git a/src/qt/locale/bitcoin_vi.ts b/src/qt/locale/bitcoin_vi.ts index 563d047ff7..a0f4a9d704 100644 --- a/src/qt/locale/bitcoin_vi.ts +++ b/src/qt/locale/bitcoin_vi.ts @@ -1372,7 +1372,7 @@ Số lượng - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) Nhập một Bitcoin address (e.g. %1) diff --git a/src/qt/locale/bitcoin_zh_CN.ts b/src/qt/locale/bitcoin_zh_CN.ts index 6678641ad3..3916583814 100644 --- a/src/qt/locale/bitcoin_zh_CN.ts +++ b/src/qt/locale/bitcoin_zh_CN.ts @@ -1381,7 +1381,7 @@ 金额 - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) 请输入一个比特币地址 (例如 %1) @@ -1797,7 +1797,7 @@ 清除 - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address 生成本地分离见证 (Bech32)地址 diff --git a/src/qt/locale/bitcoin_zh_HK.ts b/src/qt/locale/bitcoin_zh_HK.ts index df77762c6c..80b0611282 100644 --- a/src/qt/locale/bitcoin_zh_HK.ts +++ b/src/qt/locale/bitcoin_zh_HK.ts @@ -468,7 +468,7 @@ QObject - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) 輸入一個 Bitcoin 位址 (例如 %1) diff --git a/src/qt/locale/bitcoin_zh_TW.ts b/src/qt/locale/bitcoin_zh_TW.ts index 0aa7964e39..76a97c1d0d 100644 --- a/src/qt/locale/bitcoin_zh_TW.ts +++ b/src/qt/locale/bitcoin_zh_TW.ts @@ -1450,7 +1450,7 @@ 金額 - Enter a Bitcoin address (e.g. %1) + Enter a Liquid address (e.g. %1) 輸入 Bitcoin 位址 (比如說 %1) @@ -1926,7 +1926,7 @@ 使用 segwit 原生位址(也叫做 Bech32 或 BIP-173)可以減少日後的交易手續費,也比較不容易打錯字,不過會跟舊版的錢包軟體不相容。如果沒有勾選的話,會改產生與舊版錢包軟體相容的位址。 - Generate native segwit (Bech32) address + Generate blinded native segwit (Blech32) address 產生 segwit 原生位址(Bech32) diff --git a/src/qt/macnotificationhandler.mm b/src/qt/macnotificationhandler.mm index 0e04d50baa..e0906a1c58 100644 --- a/src/qt/macnotificationhandler.mm +++ b/src/qt/macnotificationhandler.mm @@ -13,7 +13,7 @@ @implementation NSBundle(returnCorrectIdentifier) - (NSString *)__bundleIdentifier { if (self == [NSBundle mainBundle]) { - return @"org.bitcoinfoundation.Bitcoin-Qt"; + return @"org.elementsproject.Elements-Qt"; } else { return [self __bundleIdentifier]; } diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 25dec23c6e..45c67900db 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -19,6 +19,7 @@ static const struct { } network_styles[] = { {"main", QAPP_APP_NAME_DEFAULT, 0, 0}, {"test", QAPP_APP_NAME_TESTNET, 70, 30}, + {"liquidv1", "Liquid-Qt-liquidv1", 0, 0}, {"regtest", QAPP_APP_NAME_TESTNET, 160, 30} }; static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles); @@ -79,7 +80,7 @@ NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const NetworkStyle* NetworkStyle::instantiate(const std::string& networkId) { - std::string titleAddText = networkId == CBaseChainParams::MAIN ? "" : strprintf("[%s]", networkId); + std::string titleAddText = networkId == "liquidv1" ? "" : strprintf("[%s]", networkId); for (unsigned x=0; xsetupUi(this); + ui->coinControlFeatures->setEnabled(false); + /* Main elements init */ ui->databaseCache->setMinimum(nMinDbCache); ui->databaseCache->setMaximum(nMaxDbCache); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index d04a2cf862..10ddf91b51 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -77,7 +77,7 @@ void OptionsModel::Init(bool resetSettings) if (!settings.contains("fCoinControlFeatures")) settings.setValue("fCoinControlFeatures", false); - fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); + fCoinControlFeatures = false; // These are shared with the core or have a command-line parameter // and we want command-line parameters to overwrite the GUI settings. diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 465086e342..1983c7ae18 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -88,11 +88,7 @@ class TxViewDelegate : public QAbstractItemDelegate foreground = option.palette.color(QPalette::Text); } painter->setPen(foreground); - QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true, BitcoinUnits::separatorAlways); - if(!confirmed) - { - amountText = QString("[") + amountText + QString("]"); - } + QString amountText = index.sibling(index.row(), TransactionTableModel::Amount).data(Qt::DisplayRole).toString(); painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); painter->setPen(option.palette.color(QPalette::Text)); @@ -123,6 +119,11 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) m_balances.balance[::policyAsset] = -1; + // Move the "Recent Transactions" view below "Balances" + ui->verticalLayout_3->removeWidget(ui->frame_2); + ui->verticalLayout_2->addWidget(ui->frame_2); + ui->horizontalLayout->removeItem(ui->verticalLayout_3); + // use a SingleColorIcon for the "out of sync warning" icon QIcon icon = platformStyle->SingleColorIcon(":/icons/warning"); icon.addPixmap(icon.pixmap(QSize(64,64), QIcon::Normal), QIcon::Disabled); // also set the disabled icon because we are using a disabled QPushButton to work around missing HiDPI support of QLabel (https://bugreports.qt.io/browse/QTBUG-42503) @@ -163,19 +164,19 @@ void OverviewPage::setBalance(const interfaces::WalletBalances& balances) { int unit = walletModel->getOptionsModel()->getDisplayUnit(); m_balances = balances; - ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.unconfirmed_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.immature_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelTotal->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.balance, ::policyAsset) + valueFor(balances.unconfirmed_balance, ::policyAsset) + valueFor(balances.immature_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelWatchAvailable->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.watch_only_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelWatchPending->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.unconfirmed_watch_only_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelWatchImmature->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.immature_watch_only_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); - ui->labelWatchTotal->setText(BitcoinUnits::formatWithUnit(unit, valueFor(balances.watch_only_balance, ::policyAsset) + valueFor(balances.unconfirmed_watch_only_balance, ::policyAsset) + valueFor(balances.immature_watch_only_balance, ::policyAsset), false, BitcoinUnits::separatorAlways)); + ui->labelBalance->setText(GUIUtil::formatMultiAssetAmount(balances.balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelUnconfirmed->setText(GUIUtil::formatMultiAssetAmount(balances.unconfirmed_balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelImmature->setText(GUIUtil::formatMultiAssetAmount(balances.immature_balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelTotal->setText(GUIUtil::formatMultiAssetAmount(balances.balance + balances.unconfirmed_balance + balances.immature_balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelWatchAvailable->setText(GUIUtil::formatMultiAssetAmount(balances.watch_only_balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelWatchPending->setText(GUIUtil::formatMultiAssetAmount(balances.unconfirmed_watch_only_balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelWatchImmature->setText(GUIUtil::formatMultiAssetAmount(balances.immature_watch_only_balance, unit, BitcoinUnits::separatorAlways, "\n")); + ui->labelWatchTotal->setText(GUIUtil::formatMultiAssetAmount(balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, unit, BitcoinUnits::separatorAlways, "\n")); // only show immature (newly mined) balance if it's non-zero, so as not to complicate things // for the non-mining users - bool showImmature = valueFor(balances.immature_balance, ::policyAsset) != 0; - bool showWatchOnlyImmature = valueFor(balances.immature_watch_only_balance, ::policyAsset) != 0; + bool showImmature = !!balances.immature_balance; + bool showWatchOnlyImmature = !!balances.immature_watch_only_balance; // for symmetry reasons also show immature label when the watch-only one is shown ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature); diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 43fc614871..87f0fa527b 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -605,7 +605,7 @@ void PaymentServer::fetchRequest(const QUrl& url) netManager->get(netRequest); } -void PaymentServer::fetchPaymentACK(WalletModel* walletModel, const SendCoinsRecipient& recipient, QByteArray transaction) +void PaymentServer::fetchPaymentACK(WalletModel* walletModel, const SendAssetsRecipient& recipient, QByteArray transaction) { const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); if (!details.has_payment_url()) diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index d335db9c85..464f02364f 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -111,7 +111,7 @@ public Q_SLOTS: void uiReady(); // Submit Payment message to a merchant, get back PaymentACK: - void fetchPaymentACK(WalletModel* walletModel, const SendCoinsRecipient& recipient, QByteArray transaction); + void fetchPaymentACK(WalletModel* walletModel, const SendAssetsRecipient& recipient, QByteArray transaction); // Handle an incoming URI, URI with local file scheme or file void handleURIOrFile(const QString& s); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index a7cc5da19e..01be25dac5 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -31,6 +31,11 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid { ui->setupUi(this); + // Hide URI-specific fields, since we don't support URIs + ui->label_5->hide(); + ui->label->hide(); ui->reqAmount->hide(); + ui->label_3->hide(); ui->reqMessage->hide(); + if (!_platformStyle->getImagesOnButtons()) { ui->clearButton->setIcon(QIcon()); ui->receiveButton->setIcon(QIcon()); @@ -44,7 +49,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid } // context menu actions - QAction *copyURIAction = new QAction(tr("Copy URI"), this); + QAction *copyURIAction = new QAction(tr("Copy address"), this); QAction *copyLabelAction = new QAction(tr("Copy label"), this); QAction *copyMessageAction = new QAction(tr("Copy message"), this); QAction *copyAmountAction = new QAction(tr("Copy amount"), this); @@ -85,15 +90,19 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model) tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->setSelectionMode(QAbstractItemView::ContiguousSelection); tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH); + tableView->horizontalHeader()->setStretchLastSection(true); +#if 0 tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH); tableView->setColumnWidth(RecentRequestsTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); +#endif connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ReceiveCoinsDialog::recentRequestsView_selectionChanged); +#if 0 // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); - +#endif if (model->wallet().getDefaultAddressType() == OutputType::BECH32) { ui->useBech32->setCheckState(Qt::Checked); } else { @@ -213,7 +222,6 @@ void ReceiveCoinsDialog::on_removeRequestButton_clicked() void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); - columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message); } void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event) @@ -272,7 +280,7 @@ void ReceiveCoinsDialog::copyURI() } const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel(); - const QString uri = GUIUtil::formatBitcoinURI(submodel->entry(sel.row()).recipient); + const QString uri = submodel->entry(sel.row()).recipient.address; GUIUtil::setClipboard(uri); } diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index c561d948be..8813bf4dd4 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -92,6 +92,8 @@ ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) : { ui->setupUi(this); + ui->btnCopyURI->setVisible(false); + #ifndef USE_QRCODE ui->btnSaveAs->setVisible(false); ui->lblQRCode->setVisible(false); @@ -131,13 +133,11 @@ void ReceiveRequestDialog::update() target = info.address; setWindowTitle(tr("Request payment to %1").arg(target)); - QString uri = GUIUtil::formatBitcoinURI(info); + QString uri = info.address; ui->btnSaveAs->setEnabled(false); QString html; html += ""; html += ""+tr("Payment information")+"
"; - html += ""+tr("URI")+": "; - html += "" + GUIUtil::HtmlEscape(uri) + "
"; html += ""+tr("Address")+": " + GUIUtil::HtmlEscape(info.address) + "
"; if(info.amount) html += ""+tr("Amount")+": " + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), info.amount) + "
"; @@ -178,20 +178,29 @@ void ReceiveRequestDialog::update() } QRcode_free(code); - QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE+20, QImage::Format_RGB32); + QFont font = GUIUtil::fixedPitchFont(); + font.setPixelSize(12); + QFontMetrics fm(font); + const int lines = (fm.width(info.address) / QR_IMAGE_SIZE) + 1; + QString split_address = info.address; + const int chars_per_line = (info.address.length() + lines - 1) / lines; + for (int i = 0; i < lines; ++i) { + split_address.insert((chars_per_line * i) + i, '\n'); + } + + QImage qrAddrImage = QImage(QR_IMAGE_SIZE, QR_IMAGE_SIZE + 16 + fm.height(), QImage::Format_RGB32); qrAddrImage.fill(0xffffff); QPainter painter(&qrAddrImage); painter.drawImage(0, 0, qrImage.scaled(QR_IMAGE_SIZE, QR_IMAGE_SIZE)); - QFont font = GUIUtil::fixedPitchFont(); QRect paddedRect = qrAddrImage.rect(); + paddedRect.setHeight(QR_IMAGE_SIZE + 8 + fm.height()); + painter.drawText(paddedRect, Qt::AlignBottom | Qt::AlignCenter | Qt::TextWordWrap, split_address); // calculate ideal font size qreal font_size = GUIUtil::calculateIdealFontSize(paddedRect.width() - 20, info.address, font); font.setPointSizeF(font_size); painter.setFont(font); - paddedRect.setHeight(QR_IMAGE_SIZE+12); - painter.drawText(paddedRect, Qt::AlignBottom|Qt::AlignCenter, info.address); painter.end(); ui->lblQRCode->setPixmap(QPixmap::fromImage(qrAddrImage)); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 82ab48ac20..ba680fc278 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -24,7 +24,7 @@ RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) : addNewRequest(request); /* These columns must match the indices in the ColumnIndex enumeration */ - columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle(); + columns << tr("Date") << tr("Label"); connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &RecentRequestsTableModel::updateDisplayUnit); } @@ -115,8 +115,6 @@ QVariant RecentRequestsTableModel::headerData(int section, Qt::Orientation orien /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ void RecentRequestsTableModel::updateAmountColumnTitle() { - columns[Amount] = getAmountTitle(); - Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount); } /** Gets title for amount column including current display unit if optionsModel reference available. */ diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 94ae256477..d4fb4aca28 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -1,5 +1,5 @@ -IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" -IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" +IDI_ICON1 ICON DISCARDABLE "rendered_icons/bitcoin.ico" +IDI_ICON2 ICON DISCARDABLE "rendered_icons/bitcoin_testnet.ico" #include // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information @@ -20,12 +20,12 @@ BEGIN BLOCK "040904E4" // U.S. English - multilingual (hex) BEGIN VALUE "CompanyName", "Bitcoin" - VALUE "FileDescription", PACKAGE_NAME " (GUI node for Bitcoin)" + VALUE "FileDescription", PACKAGE_NAME VALUE "FileVersion", VER_FILEVERSION_STR - VALUE "InternalName", "bitcoin-qt" + VALUE "InternalName", "elements-qt" VALUE "LegalCopyright", COPYRIGHT_STR VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." - VALUE "OriginalFilename", "bitcoin-qt.exe" + VALUE "OriginalFilename", "elements-qt.exe" VALUE "ProductName", PACKAGE_NAME VALUE "ProductVersion", VER_PRODUCTVERSION_STR END diff --git a/src/qt/res/src/bitcoin.svg b/src/qt/res/src/bitcoin.svg index 14cf0c5e11..7727885ddb 100644 --- a/src/qt/res/src/bitcoin.svg +++ b/src/qt/res/src/bitcoin.svg @@ -1,58 +1,15 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 0a268f7898..a57d732184 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -217,7 +217,7 @@ void SendCoinsDialog::on_sendButton_clicked() if(!model || !model->getOptionsModel()) return; - QList recipients; + QList recipients; bool valid = true; for(int i = 0; i < ui->entries->count(); ++i) @@ -275,11 +275,12 @@ void SendCoinsDialog::on_sendButton_clicked() CAmount txFee = currentTransaction.getTransactionFee(); // Format confirmation message + int bitcoin_unit = model->getOptionsModel()->getDisplayUnit(); QStringList formatted; - for (const SendCoinsRecipient &rcp : currentTransaction.getRecipients()) + for (const SendAssetsRecipient &rcp : currentTransaction.getRecipients()) { // generate bold amount string with wallet name in case of multiwallet - QString amount = "" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); + QString amount = "" + GUIUtil::formatAssetAmount(rcp.asset, rcp.asset_amount, bitcoin_unit, BitcoinUnits::separatorStandard, true); if (model->isMultiwallet()) { amount.append(" "+tr("from wallet %1").arg(GUIUtil::HtmlEscape(model->getWalletName()))+" "); } @@ -347,17 +348,22 @@ void SendCoinsDialog::on_sendButton_clicked() // add total amount in all subdivision units questionString.append("
"); - CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; + CAmountMap totalAmount = currentTransaction.getTotalTransactionAmount(); + totalAmount[Params().GetConsensus().pegged_asset] += txFee; QStringList alternativeUnits; for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) { if(u != model->getOptionsModel()->getDisplayUnit()) - alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); + alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount[Params().GetConsensus().pegged_asset])); } questionString.append(QString("%1: %2").arg(tr("Total Amount")) - .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))); + .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount[Params().GetConsensus().pegged_asset]))); questionString.append(QString("
(=%1)") .arg(alternativeUnits.join(" " + tr("or") + " "))); + totalAmount.erase(Params().GetConsensus().pegged_asset); + if (!!totalAmount) { + questionString.append(" " + tr("and") + "
" + GUIUtil::formatMultiAssetAmount(totalAmount, -1 /*bitcoin unit, hide*/, BitcoinUnits::separatorStandard, ";
")); + } SendConfirmationDialog confirmationDialog(tr("Confirm send coins"), questionString.arg(formatted.join("
")), SEND_CONFIRM_DELAY, this); @@ -511,7 +517,7 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv) entry = addEntry(); } - entry->setValue(rv); + entry->setValue(SendAssetsRecipient(rv)); updateTabsAndLabels(); } @@ -623,7 +629,7 @@ void SendCoinsDialog::useAvailableBalance(SendCoinsEntry* entry) for (int i = 0; i < ui->entries->count(); ++i) { SendCoinsEntry* e = qobject_cast(ui->entries->itemAt(i)->widget()); if (e && !e->isHidden() && e != entry) { - amount -= e->getValue().amount; + amount -= e->getValue().asset_amount; } } @@ -871,8 +877,10 @@ void SendCoinsDialog::coinControlUpdateLabels() SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); if(entry && !entry->isHidden()) { - SendCoinsRecipient rcp = entry->getValue(); - CoinControlDialog::payAmounts.append(rcp.amount); + SendAssetsRecipient rcp = entry->getValue(); + if (rcp.asset == Params().GetConsensus().pegged_asset) { + CoinControlDialog::payAmounts.append(rcp.asset_amount); + } if (rcp.fSubtractFeeFromAmount) CoinControlDialog::fSubtractFeeFromAmount = true; } diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index b394ff3150..21975743ac 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -14,6 +14,9 @@ #include #include +#include +#include + SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *parent) : QStackedWidget(parent), ui(new Ui::SendCoinsEntry), @@ -42,6 +45,7 @@ SendCoinsEntry::SendCoinsEntry(const PlatformStyle *_platformStyle, QWidget *par // Connect signals connect(ui->payAmount, &BitcoinAmountField::valueChanged, this, &SendCoinsEntry::payAmountChanged); connect(ui->checkboxSubtractFeeFromAmount, &QCheckBox::toggled, this, &SendCoinsEntry::subtractFeeFromAmountChanged); + connect(ui->payAmount, &BitcoinAmountField::valueChanged, this, &SendCoinsEntry::payAmountChangedInternal); connect(ui->deleteButton, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked); connect(ui->deleteButton_is, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked); connect(ui->deleteButton_s, &QPushButton::clicked, this, &SendCoinsEntry::deleteClicked); @@ -81,8 +85,10 @@ void SendCoinsEntry::setModel(WalletModel *_model) { this->model = _model; - if (_model && _model->getOptionsModel()) + if (_model && _model->getOptionsModel()) { connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &SendCoinsEntry::updateDisplayUnit); + connect(_model, &WalletModel::assetTypesChanged, this, &SendCoinsEntry::updateAssetTypes); + } clear(); } @@ -107,9 +113,21 @@ void SendCoinsEntry::clear() ui->payAmount_s->clear(); // update the display unit, to not use the default ("BTC") + updateAssetTypes(); updateDisplayUnit(); } +void SendCoinsEntry::payAmountChangedInternal() +{ + const auto send_assets = ui->payAmount->fullValue(); + if (send_assets.first == Params().GetConsensus().pegged_asset) { + ui->checkboxSubtractFeeFromAmount->setEnabled(true); + } else { + ui->checkboxSubtractFeeFromAmount->setCheckState(Qt::Unchecked); + ui->checkboxSubtractFeeFromAmount->setEnabled(false); + } +} + void SendCoinsEntry::checkSubtractFeeFromAmount() { ui->checkboxSubtractFeeFromAmount->setChecked(true); @@ -149,14 +167,15 @@ bool SendCoinsEntry::validate(interfaces::Node& node) } // Sending a zero amount is invalid - if (ui->payAmount->value(0) <= 0) + const auto send_assets = ui->payAmount->fullValue(); + if (send_assets.second <= 0) { ui->payAmount->setValid(false); retval = false; } // Reject dust outputs: - if (retval && GUIUtil::isDust(node, ui->payTo->text(), ui->payAmount->value())) { + if (retval && send_assets.first == ::policyAsset && GUIUtil::isDust(node, ui->payTo->text(), ui->payAmount->value())) { ui->payAmount->setValid(false); retval = false; } @@ -164,7 +183,7 @@ bool SendCoinsEntry::validate(interfaces::Node& node) return retval; } -SendCoinsRecipient SendCoinsEntry::getValue() +SendAssetsRecipient SendCoinsEntry::getValue() { // Payment request if (recipient.paymentRequest.IsInitialized()) @@ -173,7 +192,7 @@ SendCoinsRecipient SendCoinsEntry::getValue() // Normal payment recipient.address = ui->payTo->text(); recipient.label = ui->addAsLabel->text(); - recipient.amount = ui->payAmount->value(); + std::tie(recipient.asset, recipient.asset_amount) = ui->payAmount->fullValue(); recipient.message = ui->messageTextLabel->text(); recipient.fSubtractFeeFromAmount = (ui->checkboxSubtractFeeFromAmount->checkState() == Qt::Checked); @@ -192,7 +211,7 @@ QWidget *SendCoinsEntry::setupTabChain(QWidget *prev) return ui->deleteButton; } -void SendCoinsEntry::setValue(const SendCoinsRecipient &value) +void SendCoinsEntry::setValue(const SendAssetsRecipient &value) { recipient = value; @@ -202,7 +221,7 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value) { ui->payTo_is->setText(recipient.address); ui->memoTextLabel_is->setText(recipient.message); - ui->payAmount_is->setValue(recipient.amount); + ui->payAmount_is->setFullValue(recipient.asset, recipient.asset_amount); ui->payAmount_is->setReadOnly(true); setCurrentWidget(ui->SendCoins_UnauthenticatedPaymentRequest); } @@ -210,7 +229,7 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value) { ui->payTo_s->setText(recipient.authenticatedMerchant); ui->memoTextLabel_s->setText(recipient.message); - ui->payAmount_s->setValue(recipient.amount); + ui->payAmount_s->setFullValue(recipient.asset, recipient.asset_amount); ui->payAmount_s->setReadOnly(true); setCurrentWidget(ui->SendCoins_AuthenticatedPaymentRequest); } @@ -226,7 +245,7 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value) ui->payTo->setText(recipient.address); // this may set a label from addressbook if (!recipient.label.isEmpty()) // if a label had been set from the addressbook, don't overwrite with an empty label ui->addAsLabel->setText(recipient.label); - ui->payAmount->setValue(recipient.amount); + ui->payAmount->setFullValue(recipient.asset, recipient.asset_amount); } } @@ -251,6 +270,13 @@ void SendCoinsEntry::setFocus() ui->payTo->setFocus(); } +void SendCoinsEntry::updateAssetTypes() +{ + if (model) { + ui->payAmount->setAllowedAssets(model->getAssetTypes()); + } +} + void SendCoinsEntry::updateDisplayUnit() { if(model && model->getOptionsModel()) diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 48ecd598d6..581b3095d9 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -31,12 +31,12 @@ class SendCoinsEntry : public QStackedWidget void setModel(WalletModel *model); bool validate(interfaces::Node& node); - SendCoinsRecipient getValue(); + SendAssetsRecipient getValue(); /** Return whether the entry is still empty and unedited */ bool isClear(); - void setValue(const SendCoinsRecipient &value); + void setValue(const SendAssetsRecipient &value); void setAddress(const QString &address); void setAmount(const CAmount &amount); @@ -58,15 +58,17 @@ public Q_SLOTS: void subtractFeeFromAmountChanged(); private Q_SLOTS: + void payAmountChangedInternal(); void deleteClicked(); void useAvailableBalanceClicked(); void on_payTo_textChanged(const QString &address); void on_addressBookButton_clicked(); void on_pasteButton_clicked(); void updateDisplayUnit(); + void updateAssetTypes(); private: - SendCoinsRecipient recipient; + SendAssetsRecipient recipient; Ui::SendCoinsEntry *ui; WalletModel *model; const PlatformStyle *platformStyle; diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index 1eff4f6b65..eddd10e0df 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -69,7 +69,8 @@ SplashScreen::SplashScreen(interfaces::Node& node, Qt::WindowFlags f, const Netw pixPaint.fillRect(rGradient, gradient); // draw the bitcoin icon, expected size of PNG: 1024x1024 - QRect rectIcon(QPoint(-150,-122), QSize(430,430)); + int _32 = 32 / devicePixelRatio; + QRect rectIcon(QPoint(_32,-_32/2), QSize(pixmap.size().height()/devicePixelRatio+_32*2,pixmap.size().height()/devicePixelRatio+_32*2)); const QSize requiredSize(1024,1024); QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize)); diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index df65a85fb5..82f3118f01 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) // Don't remove this, it's needed to access // QApplication:: and QCoreApplication:: in the tests QApplication app(argc, argv); - app.setApplicationName("Bitcoin-Qt-test"); + app.setApplicationName("Elements-Qt-test"); SSL_library_init(); diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp index b87d3b21ca..88b767e1d8 100644 --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -11,6 +11,7 @@ void URITests::uriTests() { + /* Elements doesn't use URI SendCoinsRecipient rv; QUrl uri; uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-dontexist=")); @@ -63,4 +64,5 @@ void URITests::uriTests() uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000.0&label=Wikipedia Example")); QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + */ } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 701295ac5d..eab58cdaf9 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -208,6 +208,8 @@ void TestGUI() requestPaymentButton->click(); for (QWidget* widget : QApplication::topLevelWidgets()) { if (widget->inherits("ReceiveRequestDialog")) { + + /* URI are disabled for Elements-QT ReceiveRequestDialog* receiveRequestDialog = qobject_cast(widget); QTextEdit* rlist = receiveRequestDialog->QObject::findChild("outUri"); QString paymentText = rlist->toPlainText(); @@ -218,6 +220,7 @@ void TestGUI() QCOMPARE(paymentTextList.at(3), QString("Amount: 0.00000001 ") + QString::fromStdString(CURRENCY_UNIT)); QCOMPARE(paymentTextList.at(4), QString("Label: TEST_LABEL_1")); QCOMPARE(paymentTextList.at(5), QString("Message: TEST_MESSAGE_1")); + */ } } diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 00ba85dcbd..99fa20f66b 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -213,7 +213,7 @@ QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wall strHTML += "" + tr("Total credit") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "
"; } - CAmount nTxFee = nDebit - valueFor(wtx.tx->GetValueOutMap(), ::policyAsset); + CAmount nTxFee = GetFeeMap(*wtx.tx)[::policyAsset]; if (nTxFee > 0) strHTML += "" + tr("Transaction fee") + ": " + BitcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "
"; } diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 5dd1f91902..e20899c89b 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -36,124 +36,168 @@ QList TransactionRecord::decomposeTransaction(const interface uint256 hash = wtx.tx->GetHash(); std::map mapValue = wtx.value_map; - if (nNet > 0 || wtx.is_coinbase) + bool involvesWatchAddress = false; + isminetype fAllFromMe = ISMINE_SPENDABLE; + bool any_from_me = false; + std::set assets_issued_to_me_only; + if (wtx.is_coinbase) { + fAllFromMe = ISMINE_NO; + } + else { - // - // Credit - // + CAmountMap assets_received_by_me_only; + for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) + { + if (wtx.tx->vout[i].IsFee()) { + continue; + } + const CAsset& asset = wtx.txout_assets[i]; + if (assets_received_by_me_only.count(asset) && assets_received_by_me_only.at(asset) < 0) { + // Already known to be received by not-me + continue; + } + isminetype mine = wtx.txout_address_is_mine[i]; + if (!mine) { + assets_received_by_me_only[asset] = -1; + } else { + assets_received_by_me_only[asset] += wtx.txout_amounts[i]; + } + } + + any_from_me = false; + for (size_t i = 0; i < wtx.tx->vin.size(); ++i) + { + /* Issuance detection */ + isminetype mine = wtx.txin_is_mine[i]; + if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; + if(fAllFromMe > mine) fAllFromMe = mine; + if (mine) any_from_me = true; + CAmountMap assets; + assets[wtx.txin_issuance_asset[i]] = wtx.txin_issuance_asset_amount[i]; + assets[wtx.txin_issuance_token[i]] = wtx.txin_issuance_token_amount[i]; + for (const auto& asset : assets) { + if (!asset.first.IsNull()) { + if (assets_received_by_me_only.count(asset.first) == 0) { + continue; + } + if (asset.second == assets_received_by_me_only.at(asset.first)) { + // Special case: collapse the chain of issue, send, receive to just an issue + assets_issued_to_me_only.insert(asset.first); + continue; + } else { + TransactionRecord sub(hash, nTime); + sub.involvesWatchAddress = involvesWatchAddress; + sub.asset = asset.first; + sub.amount = asset.second; + sub.type = TransactionRecord::IssuedAsset; + parts.append(sub); + } + } + } + } + } + + if (fAllFromMe || !any_from_me) { for(unsigned int i = 0; i < wtx.tx->vout.size(); i++) { const CTxOut& txout = wtx.tx->vout[i]; + const CAsset& asset = wtx.txout_assets[i]; + if (txout.IsFee()) { + // explicit fee; ignore + continue; + } + + if (fAllFromMe && assets_issued_to_me_only.count(asset) == 0) { + // Change is only really possible if we're the sender + // Otherwise, someone just sent bitcoins to a change address, which should be shown + + if (wtx.txout_is_change[i]) { + continue; + } + + // + // Debit + // + TransactionRecord sub(hash, nTime); + sub.idx = i; + sub.involvesWatchAddress = involvesWatchAddress; + sub.amount = -wtx.txout_amounts[i]; + sub.asset = asset; + + if (!boost::get(&wtx.txout_address[i])) + { + // Sent to Bitcoin Address + sub.type = TransactionRecord::SendToAddress; + sub.address = EncodeDestination(wtx.txout_address[i]); + } + else + { + // Sent to IP, or other non-address transaction like OP_EVAL + sub.type = TransactionRecord::SendToOther; + sub.address = mapValue["to"]; + } + parts.append(sub); + } + isminetype mine = wtx.txout_is_mine[i]; if(mine) { + // + // Credit + // + TransactionRecord sub(hash, nTime); CTxDestination address; sub.idx = i; // vout index - sub.credit = txout.nValue.GetAmount(); + sub.amount = wtx.txout_amounts[i]; sub.involvesWatchAddress = mine & ISMINE_WATCH_ONLY; if (wtx.txout_address_is_mine[i]) { // Received by Bitcoin Address sub.type = TransactionRecord::RecvWithAddress; sub.address = EncodeDestination(wtx.txout_address[i]); + sub.asset = asset; } else { // Received by IP connection (deprecated features), or a multisignature or other non-simple transaction sub.type = TransactionRecord::RecvFromOther; sub.address = mapValue["from"]; + sub.asset = wtx.txout_assets[i]; } if (wtx.is_coinbase) { // Generated sub.type = TransactionRecord::Generated; + sub.asset = wtx.txout_assets[i]; + } + if (assets_issued_to_me_only.count(wtx.txout_assets[i])) { + sub.type = TransactionRecord::IssuedAsset; } parts.append(sub); } } - } - else - { - bool involvesWatchAddress = false; - isminetype fAllFromMe = ISMINE_SPENDABLE; - for (const isminetype mine : wtx.txin_is_mine) - { - if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; - if(fAllFromMe > mine) fAllFromMe = mine; - } - - isminetype fAllToMe = ISMINE_SPENDABLE; - for (const isminetype mine : wtx.txout_is_mine) - { - if(mine & ISMINE_WATCH_ONLY) involvesWatchAddress = true; - if(fAllToMe > mine) fAllToMe = mine; - } - - if (fAllFromMe && fAllToMe) - { - // Payment to self - CAmount nChange = valueFor(wtx.change, ::policyAsset); - parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", - -(nDebit - nChange), nCredit - nChange)); - parts.last().involvesWatchAddress = involvesWatchAddress; // maybe pass to TransactionRecord as constructor argument - } - else if (fAllFromMe) - { - // - // Debit - // - CAmount nTxFee = nDebit - wtx.tx->GetValueOutMap()[::policyAsset]; + if (fAllFromMe) { + for (const auto& tx_fee : GetFeeMap(*wtx.tx)) { + if (!tx_fee.second) continue; - for (unsigned int nOut = 0; nOut < wtx.tx->vout.size(); nOut++) - { - const CTxOut& txout = wtx.tx->vout[nOut]; TransactionRecord sub(hash, nTime); - sub.idx = nOut; - sub.involvesWatchAddress = involvesWatchAddress; - - if(wtx.txout_is_mine[nOut]) - { - // Ignore parts sent to self, as this is usually the change - // from a transaction sent back to our own address. - continue; - } - - if (!boost::get(&wtx.txout_address[nOut])) - { - // Sent to Bitcoin Address - sub.type = TransactionRecord::SendToAddress; - sub.address = EncodeDestination(wtx.txout_address[nOut]); - } - else - { - // Sent to IP, or other non-address transaction like OP_EVAL - sub.type = TransactionRecord::SendToOther; - sub.address = mapValue["to"]; - } - - CAmount nValue = txout.nValue.GetAmount(); - /* Add fee to first output */ - if (nTxFee > 0) - { - nValue += nTxFee; - nTxFee = 0; - } - sub.debit = -nValue; - + sub.type = TransactionRecord::Fee; + sub.asset = tx_fee.first; + sub.amount = -tx_fee.second; parts.append(sub); } } - else - { - // - // Mixed debit transaction, can't break down payees - // - parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0)); - parts.last().involvesWatchAddress = involvesWatchAddress; - } + } + else + { + // + // Mixed debit transaction, can't break down payees + // + parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, CAsset())); + parts.last().involvesWatchAddress = involvesWatchAddress; } return parts; @@ -164,11 +208,32 @@ void TransactionRecord::updateStatus(const interfaces::WalletTxStatus& wtx, int // Determine transaction status // Sort order, unrecorded transactions sort to the top - status.sortKey = strprintf("%010d-%01d-%010u-%03d", + int typesort; + switch (type) { + case Fee: + typesort = 0; + break; + case IssuedAsset: + typesort = 1; + break; + case SendToAddress: + case SendToOther: + case SendToSelf: + typesort = 2; + break; + case RecvWithAddress: + case RecvFromOther: + typesort = 3; + break; + default: + typesort = 10; + } + status.sortKey = strprintf("%010d-%01d-%010u-%03d-%d", wtx.block_height, wtx.is_coinbase ? 1 : 0, wtx.time_received, - idx); + idx, + typesort); status.countsForBalance = wtx.is_trusted && !(wtx.blocks_to_maturity > 0); status.depth = wtx.depth_in_main_chain; status.cur_num_blocks = numBlocks; diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index e187309d3f..6661705e51 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -6,6 +6,7 @@ #define BITCOIN_QT_TRANSACTIONRECORD_H #include +#include #include #include @@ -81,27 +82,30 @@ class TransactionRecord SendToOther, RecvWithAddress, RecvFromOther, - SendToSelf + SendToSelf, + Fee, + IssuedAsset, }; /** Number of confirmation recommended for accepting a transaction */ - static const int RecommendedNumConfirmations = 6; + static const int RecommendedNumConfirmations = 2; TransactionRecord(): - hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0) + hash(), time(0), type(Other), address(""), amount(0), idx(0) { } TransactionRecord(uint256 _hash, qint64 _time): - hash(_hash), time(_time), type(Other), address(""), debit(0), - credit(0), idx(0) + hash(_hash), time(_time), type(Other), address(""), amount(0), + idx(0) { } TransactionRecord(uint256 _hash, qint64 _time, Type _type, const std::string &_address, - const CAmount& _debit, const CAmount& _credit): - hash(_hash), time(_time), type(_type), address(_address), debit(_debit), credit(_credit), + const CAmount& _amount, const CAsset& _asset): + hash(_hash), time(_time), type(_type), address(_address), + amount(_amount), asset(_asset), idx(0) { } @@ -117,8 +121,8 @@ class TransactionRecord qint64 time; Type type; std::string address; - CAmount debit; - CAmount credit; + CAmount amount; + CAsset asset; /**@}*/ /** Subtransaction index, for sort key */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index b4be068904..72818ca67a 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include @@ -225,7 +227,7 @@ TransactionTableModel::TransactionTableModel(const PlatformStyle *_platformStyle fProcessingQueuedTransactions(false), platformStyle(_platformStyle) { - columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); + columns << QString() << QString() << tr("Date") << tr("Type") << tr("Label") << tr("Amount"); priv->refreshWallet(walletModel->wallet()); connect(walletModel->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &TransactionTableModel::updateDisplayUnit); @@ -239,12 +241,6 @@ TransactionTableModel::~TransactionTableModel() delete priv; } -/** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ -void TransactionTableModel::updateAmountColumnTitle() -{ - columns[Amount] = BitcoinUnits::getAmountColumnTitle(walletModel->getOptionsModel()->getDisplayUnit()); - Q_EMIT headerDataChanged(Qt::Horizontal,Amount,Amount); -} void TransactionTableModel::updateTransaction(const QString &hash, int status, bool showTransaction) { @@ -356,6 +352,10 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const return tr("Payment to yourself"); case TransactionRecord::Generated: return tr("Mined"); + case TransactionRecord::Fee: + return tr("Fee"); + case TransactionRecord::IssuedAsset: + return tr("Issuance"); default: return QString(); } @@ -366,12 +366,14 @@ QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx switch(wtx->type) { case TransactionRecord::Generated: + case TransactionRecord::IssuedAsset: return QIcon(":/icons/tx_mined"); case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvFromOther: return QIcon(":/icons/tx_input"); case TransactionRecord::SendToAddress: case TransactionRecord::SendToOther: + case TransactionRecord::Fee: return QIcon(":/icons/tx_output"); default: return QIcon(":/icons/tx_inout"); @@ -393,6 +395,7 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b case TransactionRecord::RecvWithAddress: case TransactionRecord::SendToAddress: case TransactionRecord::Generated: + case TransactionRecord::IssuedAsset: return lookupAddress(wtx->address, tooltip) + watchAddress; case TransactionRecord::SendToOther: return QString::fromStdString(wtx->address) + watchAddress; @@ -410,6 +413,7 @@ QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const case TransactionRecord::RecvWithAddress: case TransactionRecord::SendToAddress: case TransactionRecord::Generated: + case TransactionRecord::IssuedAsset: { QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); if(label.isEmpty()) @@ -425,7 +429,7 @@ QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool showUnconfirmed, BitcoinUnits::SeparatorStyle separators) const { - QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit, false, separators); + QString str = GUIUtil::formatAssetAmount(wtx->asset, wtx->amount, walletModel->getOptionsModel()->getDisplayUnit(), separators); if(showUnconfirmed) { if(!wtx->status.countsForBalance) @@ -535,7 +539,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case Status: return QString::fromStdString(rec->status.sortKey); case Date: - return rec->time; + return QString::fromStdString(strprintf("%020-%s", rec->time, rec->status.sortKey)); case Type: return formatTxType(rec); case Watchonly: @@ -543,7 +547,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case ToAddress: return formatTxToAddress(rec, true); case Amount: - return qint64(rec->credit + rec->debit); + return qint64(rec->amount); } break; case Qt::ToolTipRole: @@ -561,7 +565,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const { return COLOR_UNCONFIRMED; } - if(index.column() == Amount && (rec->credit+rec->debit) < 0) + if (index.column() == Amount && rec->amount < 0) { return COLOR_NEGATIVE; } @@ -585,7 +589,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case LabelRole: return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); case AmountRole: - return qint64(rec->credit + rec->debit); + return qint64(rec->amount); case TxHashRole: return rec->getTxHash(); case TxHexRole: @@ -676,7 +680,6 @@ QModelIndex TransactionTableModel::index(int row, int column, const QModelIndex void TransactionTableModel::updateDisplayUnit() { // emit dataChanged to update Amount column with the current unit - updateAmountColumnTitle(); Q_EMIT dataChanged(index(0, Amount), index(priv->size()-1, Amount)); } diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 8be3a7ab2e..d846627a23 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -112,8 +112,6 @@ public Q_SLOTS: void updateTransaction(const QString &hash, int status, bool showTransaction); void updateConfirmations(); void updateDisplayUnit(); - /** Updates the column title to "Amount (DisplayUnit)" and emits headerDataChanged() signal for table headers to react. */ - void updateAmountColumnTitle(); /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */ void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; } diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 6d08a3b0fb..d70a0eea4f 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -37,6 +39,37 @@ #include #include +class TransactionRecordDelegate : public QItemDelegate +{ + QSortFilterProxyModel* m_proxy; + + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const + { + bool alternate = false; + QVariant previous_hash; + + for (int row = 0; row <= index.row(); ++row) { + QModelIndex sibling = m_proxy->mapToSource(index.sibling(row, 0)); + QVariant hash = sibling.data(TransactionTableModel::TxHashRole); + if (row == 0) { + previous_hash = hash; + } else if (hash != previous_hash) { + alternate = !alternate; + previous_hash = hash; + } + } + + if (alternate) { + painter->fillRect(option.rect, option.palette.alternateBase()); + } + + QItemDelegate::paint(painter, option, index); + } + +public: + TransactionRecordDelegate(QSortFilterProxyModel* proxy) : m_proxy(proxy) {} +}; + TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), transactionView(0), abandonAction(0), bumpFeeAction(0), columnResizingFixer(0) @@ -89,8 +122,9 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther)); typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) | TransactionFilterProxy::TYPE(TransactionRecord::SendToOther)); - typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf)); typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated)); + typeWidget->addItem(tr("Fee"), TransactionFilterProxy::TYPE(TransactionRecord::Fee)); + typeWidget->addItem(tr("Issuance"), TransactionFilterProxy::TYPE(TransactionRecord::IssuedAsset)); typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other)); hlayout->addWidget(typeWidget); @@ -167,7 +201,6 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa contextMenu->addAction(copyTxIDAction); contextMenu->addAction(copyTxHexAction); contextMenu->addAction(copyTxPlainText); - contextMenu->addAction(showDetailsAction); contextMenu->addSeparator(); contextMenu->addAction(bumpFeeAction); contextMenu->addAction(abandonAction); @@ -222,7 +255,7 @@ void TransactionView::setModel(WalletModel *_model) transactionView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); transactionView->setModel(transactionProxyModel); - transactionView->setAlternatingRowColors(true); + transactionView->setItemDelegate(new TransactionRecordDelegate(transactionProxyModel)); transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); transactionView->setSortingEnabled(true); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 7d903b3b1c..9cef3e703a 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -70,7 +70,7 @@ HelpMessageDialog::HelpMessageDialog(interfaces::Node& node, QWidget *parent, bo ui->helpMessage->setVisible(false); } else { setWindowTitle(tr("Command-line options")); - QString header = "Usage: bitcoin-qt [command-line options] \n"; + QString header = "Usage: elements-qt [command-line options] \n"; QTextCursor cursor(ui->helpMessage->document()); cursor.insertText(version); cursor.insertBlock(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 5a6e650aba..6123cf7941 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -20,6 +20,7 @@ #include // for GetBoolArg #include #include +#include #include @@ -28,6 +29,19 @@ #include #include +SendAssetsRecipient::SendAssetsRecipient(SendCoinsRecipient r) : + address(r.address), + label(r.label), + asset(Params().GetConsensus().pegged_asset), + asset_amount(r.amount), + message(r.message), + paymentRequest(r.paymentRequest), + authenticatedMerchant(r.authenticatedMerchant), + fSubtractFeeFromAmount(r.fSubtractFeeFromAmount) +{ +} + +#define SendCoinsRecipient SendAssetsRecipient WalletModel::WalletModel(std::unique_ptr wallet, interfaces::Node& node, const PlatformStyle *platformStyle, OptionsModel *_optionsModel, QObject *parent) : QObject(parent), m_wallet(std::move(wallet)), m_node(node), optionsModel(_optionsModel), addressTableModel(0), @@ -56,6 +70,11 @@ WalletModel::~WalletModel() unsubscribeFromCoreSignals(); } +std::set WalletModel::getAssetTypes() const +{ + return cached_asset_types; +} + void WalletModel::updateStatus() { EncryptionStatus newEncryptionStatus = getEncryptionStatus(); @@ -95,6 +114,16 @@ void WalletModel::checkBalanceChanged(const interfaces::WalletBalances& new_bala if(new_balances.balanceChanged(m_cached_balances)) { m_cached_balances = new_balances; Q_EMIT balanceChanged(new_balances); + + std::set new_asset_types; + for (const auto& assetamount : new_balances.balance + new_balances.unconfirmed_balance) { + if (!assetamount.second) continue; + new_asset_types.insert(assetamount.first); + } + if (new_asset_types != cached_asset_types) { + cached_asset_types = new_asset_types; + Q_EMIT assetTypesChanged(); + } } } @@ -124,7 +153,7 @@ bool WalletModel::validateAddress(const QString &address) WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl& coinControl) { - CAmount total = 0; + CAmountMap total; bool fSubtractFeeFromAmount = false; QList recipients = transaction.getRecipients(); std::vector vecSend; @@ -162,7 +191,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { return InvalidAmount; } - total += subtotal; + total[Params().GetConsensus().pegged_asset] += subtotal; } else { // User-entered bitcoin address / amount: @@ -170,18 +199,20 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { return InvalidAddress; } - if(rcp.amount <= 0) + if(rcp.asset_amount <= 0) { return InvalidAmount; } setAddress.insert(rcp.address); ++nAddresses; - CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString())); - CRecipient recipient = {scriptPubKey, rcp.amount, ::policyAsset, CPubKey(), rcp.fSubtractFeeFromAmount}; + CTxDestination dest = DecodeDestination(rcp.address.toStdString()); + CScript scriptPubKey = GetScriptForDestination(dest); + CPubKey confidentiality_pubkey = GetDestinationBlindingKey(dest); + CRecipient recipient = {scriptPubKey, rcp.asset_amount, rcp.asset, confidentiality_pubkey, rcp.fSubtractFeeFromAmount}; vecSend.push_back(recipient); - total += rcp.amount; + total[rcp.asset] += rcp.asset_amount; } } if(setAddress.size() != nAddresses) @@ -189,7 +220,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return DuplicateAddress; } - CAmount nBalance = m_wallet->getAvailableBalance(coinControl)[::policyAsset]; + CAmountMap nBalance = m_wallet->getAvailableBalance(coinControl); if(total > nBalance) { @@ -202,14 +233,17 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact std::string strFailReason; auto& newTx = transaction.getWtx(); - newTx = m_wallet->createTransaction(vecSend, coinControl, true /* sign */, nChangePosRet, nFeeRequired, strFailReason); + std::vector out_amounts; + newTx = m_wallet->createTransaction(vecSend, coinControl, true /* sign */, nChangePosRet, nFeeRequired, out_amounts, strFailReason); transaction.setTransactionFee(nFeeRequired); if (fSubtractFeeFromAmount && newTx) - transaction.reassignAmounts(nChangePosRet); + assert(out_amounts.size() == newTx->get().vout.size()); + transaction.reassignAmounts(out_amounts, nChangePosRet); if(!newTx) { - if(!fSubtractFeeFromAmount && (total + nFeeRequired) > nBalance) + total[Params().GetConsensus().pegged_asset] += nFeeRequired; + if(!fSubtractFeeFromAmount && total > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance); } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index b22728c69b..a16b374b3e 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -105,6 +105,24 @@ class SendCoinsRecipient } }; +class SendAssetsRecipient +{ +public: + explicit SendAssetsRecipient() : fSubtractFeeFromAmount(false) { } + explicit SendAssetsRecipient(SendCoinsRecipient r); +public: + QString address; + QString label; + CAsset asset; + CAmount asset_amount; + QString message; + + PaymentRequestPlus paymentRequest; + QString authenticatedMerchant; + + bool fSubtractFeeFromAmount; // memory only +}; + /** Interface to Bitcoin wallet from Qt view code. */ class WalletModel : public QObject { @@ -140,6 +158,7 @@ class WalletModel : public QObject TransactionTableModel *getTransactionTableModel(); RecentRequestsTableModel *getRecentRequestsTableModel(); + std::set getAssetTypes() const; EncryptionStatus getEncryptionStatus() const; // Check address for validity @@ -230,6 +249,7 @@ class WalletModel : public QObject // Cache some values to be able to detect changes interfaces::WalletBalances m_cached_balances; + std::set cached_asset_types; EncryptionStatus cachedEncryptionStatus; int cachedNumBlocks; @@ -243,6 +263,9 @@ class WalletModel : public QObject // Signal that balance in wallet changed void balanceChanged(const interfaces::WalletBalances& balances); + // Signal that the set of possessed asset types changed + void assetTypesChanged(); + // Encryption status of wallet changed void encryptionStatusChanged(); @@ -255,7 +278,7 @@ class WalletModel : public QObject void message(const QString &title, const QString &message, unsigned int style); // Coins sent: from wallet, to recipient, in (serialized) transaction: - void coinsSent(WalletModel* wallet, SendCoinsRecipient recipient, QByteArray transaction); + void coinsSent(WalletModel* wallet, SendAssetsRecipient recipient, QByteArray transaction); // Show progress dialog e.g. for rescan void showProgress(const QString &title, int nProgress); diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 821b158a4f..a7085d2e4f 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -7,6 +7,8 @@ #include #include +#define SendCoinsRecipient SendAssetsRecipient + WalletModelTransaction::WalletModelTransaction(const QList &_recipients) : recipients(_recipients), fee(0) @@ -38,13 +40,13 @@ void WalletModelTransaction::setTransactionFee(const CAmount& newFee) fee = newFee; } -void WalletModelTransaction::reassignAmounts(int nChangePosRet) +void WalletModelTransaction::reassignAmounts(const std::vector& outAmounts, int nChangePosRet) { const CTransaction* walletTransaction = &wtx->get(); int i = 0; - for (QList::iterator it = recipients.begin(); it != recipients.end(); ++it) + for (auto it = recipients.begin(); it != recipients.end(); ++it) { - SendCoinsRecipient& rcp = (*it); + auto& rcp = (*it); if (rcp.paymentRequest.IsInitialized()) { @@ -56,27 +58,27 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet) if (out.amount() <= 0) continue; if (i == nChangePosRet) i++; - subtotal += walletTransaction->vout[i].nValue.GetAmount(); + subtotal += g_con_elementsmode ? outAmounts[i] : walletTransaction->vout[i].nValue.GetAmount(); i++; } - rcp.amount = subtotal; + rcp.asset_amount = subtotal; } else // normal recipient (no payment request) { if (i == nChangePosRet) i++; - rcp.amount = walletTransaction->vout[i].nValue.GetAmount(); + rcp.asset_amount = g_con_elementsmode ? outAmounts[i] : walletTransaction->vout[i].nValue.GetAmount(); i++; } } } -CAmount WalletModelTransaction::getTotalTransactionAmount() const +CAmountMap WalletModelTransaction::getTotalTransactionAmount() const { - CAmount totalTransactionAmount = 0; - for (const SendCoinsRecipient &rcp : recipients) + CAmountMap totalTransactionAmount; + for (const auto &rcp : recipients) { - totalTransactionAmount += rcp.amount; + totalTransactionAmount[rcp.asset] += rcp.asset_amount; } return totalTransactionAmount; } diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 75ede2e2a1..0a83f70c4b 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -11,7 +11,7 @@ #include -class SendCoinsRecipient; +class SendAssetsRecipient; namespace interfaces { class Node; @@ -22,9 +22,9 @@ class PendingWalletTx; class WalletModelTransaction { public: - explicit WalletModelTransaction(const QList &recipients); + explicit WalletModelTransaction(const QList &recipients); - QList getRecipients() const; + QList getRecipients() const; std::unique_ptr& getWtx(); unsigned int getTransactionSize(); @@ -32,12 +32,12 @@ class WalletModelTransaction void setTransactionFee(const CAmount& newFee); CAmount getTransactionFee() const; - CAmount getTotalTransactionAmount() const; + CAmountMap getTotalTransactionAmount() const; - void reassignAmounts(int nChangePosRet); // needed for the subtract-fee-from-amount feature + void reassignAmounts(const std::vector& out_amounts, int nChangePosRet); // needed for the subtract-fee-from-amount feature private: - QList recipients; + QList recipients; std::unique_ptr wtx; CAmount fee; }; diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 053e951921..afce24339c 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -72,7 +72,6 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent): // Highlight transaction after send connect(sendCoinsPage, &SendCoinsDialog::coinsSent, transactionView, static_cast(&TransactionView::focusTransaction)); - // Clicking on "Export" allows to export the transaction list connect(exportButton, &QPushButton::clicked, transactionView, &TransactionView::exportClicked); @@ -166,13 +165,13 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int return; QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString(); - qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong(); + QString assetamount_str = ttm->index(start, TransactionTableModel::Amount, parent).data().toString(); QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString(); QModelIndex index = ttm->index(start, 0, parent); QString address = ttm->data(index, TransactionTableModel::AddressRole).toString(); QString label = ttm->data(index, TransactionTableModel::LabelRole).toString(); - Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label, walletModel->getWalletName()); + Q_EMIT incomingTransaction(date, assetamount_str, type, address, label, walletModel->getWalletName()); } void WalletView::gotoOverviewPage() diff --git a/src/qt/walletview.h b/src/qt/walletview.h index e29c4c52f5..4c55efd1e8 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -124,7 +124,7 @@ public Q_SLOTS: /** HD-Enabled status of wallet changed (only possible during startup) */ void hdEnabledStatusChanged(); /** Notify that a new transaction appeared */ - void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName); + void incomingTransaction(const QString& date, const QString& assetamount_str, const QString& type, const QString& address, const QString& label, const QString& walletName); /** Notify that the out of sync warning icon has been pressed */ void outOfSyncWarningClicked(); }; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 697c726a9e..f1fdedcd37 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2024,6 +2024,19 @@ bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const return CTransaction(tx1) == CTransaction(tx2); } +CAmountMap CWalletTx::GetIssuanceAssets(unsigned int input_index) const { + CAmountMap ret; + CAsset asset, token; + GetIssuanceAssets(input_index, &asset, &token); + if (!asset.IsNull()) { + ret[asset] = GetIssuanceAmount(input_index, false); + } + if (!token.IsNull()) { + ret[token] = GetIssuanceAmount(input_index, true); + } + return ret; +} + std::vector CWallet::ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman) { std::vector result; @@ -5196,32 +5209,52 @@ CPubKey CWalletTx::GetOutputBlindingPubKey(unsigned int output_index) const { return ret; } -uint256 CWalletTx::GetIssuanceBlindingFactor(unsigned int input_index, bool reissuance_token) const { +void CWalletTx::GetIssuanceAssets(unsigned int input_index, CAsset* out_asset, CAsset* out_reissuance_token) const { assert(input_index < tx->vin.size()); - CAsset asset; const CAssetIssuance& issuance = tx->vin[input_index].assetIssuance; - const CTxWitness& wit = tx->witness; - if ((issuance.nAmount.IsNull() && !reissuance_token) || (issuance.nInflationKeys.IsNull() && reissuance_token)) { - return uint256(); + + if (out_asset && issuance.nAmount.IsNull()) { + out_asset->SetNull(); + out_asset = nullptr; } - const std::vector& rangeproof = wit.vtxinwit.size() <= input_index ? std::vector() : (reissuance_token ? wit.vtxinwit[input_index].vchInflationKeysRangeproof : wit.vtxinwit[input_index].vchIssuanceAmountRangeproof); - unsigned int mapValueInd = GetPseudoInputOffset(input_index, reissuance_token)+tx->vout.size(); - if (issuance.assetBlindingNonce.IsNull()) { + if (out_reissuance_token && issuance.nInflationKeys.IsNull()) { + out_reissuance_token->SetNull(); + out_reissuance_token = nullptr; + } + if (!(out_asset || out_reissuance_token)) return; + + if (issuance.assetBlindingNonce.IsNull()) { uint256 entropy; GenerateAssetEntropy(entropy, tx->vin[input_index].prevout, issuance.assetEntropy); - if (reissuance_token) { - CalculateReissuanceToken(asset, entropy, issuance.nInflationKeys.IsCommitment()); - } else { - CalculateAsset(asset, entropy); + if (out_reissuance_token) { + CalculateReissuanceToken(*out_reissuance_token, entropy, issuance.nAmount.IsCommitment()); } - } + if (out_asset) { + CalculateAsset(*out_asset, entropy); + } + } else { - if (reissuance_token) { + if (out_reissuance_token) { // Re-issuances don't emit issuance tokens - return uint256(); + out_reissuance_token->SetNull(); + } + if (out_asset) { + CalculateAsset(*out_asset, issuance.assetEntropy); } - CalculateAsset(asset, issuance.assetEntropy); } +} + +uint256 CWalletTx::GetIssuanceBlindingFactor(unsigned int input_index, bool reissuance_token) const { + assert(input_index < tx->vin.size()); + CAsset asset; + const CAssetIssuance& issuance = tx->vin[input_index].assetIssuance; + const CTxWitness& wit = tx->witness; + GetIssuanceAssets(input_index, reissuance_token ? nullptr : &asset, reissuance_token ? &asset : nullptr); + if (asset.IsNull()) { + return uint256(); + } + const std::vector& rangeproof = wit.vtxinwit.size() <= input_index ? std::vector() : (reissuance_token ? wit.vtxinwit[input_index].vchInflationKeysRangeproof : wit.vtxinwit[input_index].vchIssuanceAmountRangeproof); + unsigned int mapValueInd = GetPseudoInputOffset(input_index, reissuance_token)+tx->vout.size(); uint256 ret; CScript blindingScript(CScript() << OP_RETURN << std::vector(tx->vin[input_index].prevout.hash.begin(), tx->vin[input_index].prevout.hash.end()) << tx->vin[input_index].prevout.n); @@ -5232,31 +5265,18 @@ uint256 CWalletTx::GetIssuanceBlindingFactor(unsigned int input_index, bool reis CAmount CWalletTx::GetIssuanceAmount(unsigned int input_index, bool reissuance_token) const { assert(input_index < tx->vin.size()); CAsset asset; - CAsset token; const CAssetIssuance& issuance = tx->vin[input_index].assetIssuance; const CTxWitness& wit = tx->witness; - if ((issuance.nAmount.IsNull() && !reissuance_token) || (issuance.nInflationKeys.IsNull() && reissuance_token)) { - return 0; + GetIssuanceAssets(input_index, reissuance_token ? nullptr : &asset, reissuance_token ? &asset : nullptr); + if (asset.IsNull()) { + return -1; } unsigned int mapValueInd = GetPseudoInputOffset(input_index, reissuance_token)+tx->vout.size(); const std::vector& rangeproof = wit.vtxinwit.size() <= input_index ? std::vector() : (reissuance_token ? wit.vtxinwit[input_index].vchInflationKeysRangeproof : wit.vtxinwit[input_index].vchIssuanceAmountRangeproof); - if (issuance.assetBlindingNonce.IsNull()) { - uint256 entropy; - GenerateAssetEntropy(entropy, tx->vin[input_index].prevout, issuance.assetEntropy); - CalculateReissuanceToken(token, entropy, issuance.nAmount.IsCommitment()); - CalculateAsset(asset, entropy); - } - else { - if (reissuance_token) { - // Re-issuances don't emit issuance tokens - return -1; - } - CalculateAsset(asset, issuance.assetEntropy); - } CAmount ret; CScript blindingScript(CScript() << OP_RETURN << std::vector(tx->vin[input_index].prevout.hash.begin(), tx->vin[input_index].prevout.hash.end()) << tx->vin[input_index].prevout.n); - GetBlindingData(mapValueInd, rangeproof, reissuance_token ? issuance.nInflationKeys : issuance.nAmount, CConfidentialAsset((reissuance_token ? token : asset)), CConfidentialNonce(), blindingScript, nullptr, &ret, nullptr, nullptr, nullptr); + GetBlindingData(mapValueInd, rangeproof, reissuance_token ? issuance.nInflationKeys : issuance.nAmount, CConfidentialAsset(asset), CConfidentialNonce(), blindingScript, nullptr, &ret, nullptr, nullptr, nullptr); return ret; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 71524f3dde..87d22bc346 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -533,6 +533,10 @@ class CWalletTx : public CMerkleTx uint256 GetOutputAssetBlindingFactor(unsigned int output_index) const; //! Returns the underlying asset type, or 0 if unknown CAsset GetOutputAsset(unsigned int output_index) const; + //! Get the issuance CAssets for both the asset itself and the issuing tokens + void GetIssuanceAssets(unsigned int vinIndex, CAsset* out_asset, CAsset* out_reissuance_token) const; + // ! Return map of issued assets at input_index + CAmountMap GetIssuanceAssets(unsigned int input_index) const; // ! Returns receiver's blinding pubkey CPubKey GetOutputBlindingPubKey(unsigned int output_index) const; //! Get the issuance blinder for either the asset itself or the issuing tokens