diff --git a/.gitignore b/.gitignore index 0c9cc5e5..266878fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.class build/** +**/target/* # Mobile Tools for Java (J2ME) .mtj.tmp/ @@ -8,3 +9,15 @@ build/** # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +*exe +.idea/* +.iml +*.iml + +.vscode +.classpath +.settings +installer/.project +installer/bin +zencash-wallet-swing/.project +zencash-wallet-swing/bin diff --git a/.project b/.project index 1353b675..34f90cb4 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - ZENCashOfficialSwingWalletUI + HorizenSwingWalletUI diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index d17b6724..a698e596 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,12 +1,12 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..d15b24c8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,47 @@ +os: linux +language: shell + +env: + - ZEND_VERSION=4.1.0 JDK=16 + +install: + - source ./scripts/install.sh + - source ./scripts/setup-env.sh + +script: ./scripts/build.sh + +before_deploy: + - git config --local user.name $GITHUB_USERNAME + - git config --local user.email $GITHUB_EMAIL + - if [[ -z $TRAVIS_TAG ]]; then export TRAVIS_TAG=$TRAVIS_BRANCH; fi + +deploy: + edge: true + provider: releases + token: $GITHUB_AUTH + file_glob: true + file: "./releases/*" + cleanup: false + overwrite: true + draft: true + release_notes: $READABLE_NAME + on: + all_branches: true + +jobs: + include: + - stage: "Builds and Deploy" + os: osx + osx_image: xcode9.4 + language: shell + - + os: linux + dist: bionic + language: shell + - + os: windows + language: shell + before_install: + - powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine + - powershell Install-WindowsFeature Net-Framework-Core + - cinst -y wixtoolset diff --git a/LICENSE b/LICENSE index 14790f71..6fb3087a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License -Copyright (c) 2016-2017 Ivan Vaklinov +Copyright (c) 2023 The Horizen Foundation +Copyright (c) 2016-2021 Zen Blockchain Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 3b3acaa3..83cc967a 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,89 @@ -# [ZENCash](https://zensystem.io/) Desktop GUI Wallet +# [Horizen](https://horizen.io/) Desktop GUI Wallet -## Graphical user interface wrapper for the [ZENCash](https://zensystem.io/) command line tools +

-### IMPORTANT: Please read the [security notice](docs/KnownSecurityIssues.md) about watch-only addresses before using the wallet! +## Deprecation notice -This program provides a Graphical User Interface (GUI) for the ZENCash client tools that acts as a wrapper and +Horizen Desktop GUI Wallet is no longer actively maintained. + +[Sphere by Horizen](https://github.com/HorizenOfficial/Sphere_by_Horizen) is its successor and ongoing development will be focused on Sphere by Horizen, to migrate to Sphere by Horizen please see our [wiki]( https://horizenofficial.atlassian.net/wiki/spaces/ZEN/pages/729776153). + +If you still wish to use Horizen Desktop GUI Wallet, you can manually update the bundled binaries of [Zen](https://github.com/HorizenOfficial/zen) by following these steps: + +1. Access the **[Releases](https://github.com/HorizenOfficial/zen/releases)** section of the Zen repository to download the last zend binaries for your operating system. +2. Once you have downloaded the necessary binaries (make sure you have `zen-cli`, `zen-tx`, `zend`), you need to update them in the installation path of your app, which varies depending on your operating system. Make sure Horizen Desktop GUI Wallet is closed before proceeding. + +- **Windows**: + - Replace the binaries in the `/app` folder where you installed the wallet. The default path for this is `C:\Program Files\HorizenDesktopGUIWallet\app`. +- **macOS**: + - Inspect the app by right-clicking and selecting "Show Package Contents." + - Navigate to the `/Contents/app` directory within the package. + - Replace the existing binaries with the new ones. + +Once you have updated the binaries, you can open the wallet again and it will be running the latest version of Zen. + +**Note**: The Linux version of Swing doesn't include Zend binaries by default; instead, it relies on the presence of the Zen Debian package being installed. Therefore, there's no Linux-specific installation instructions in the repository since Zend is updated and installed separately as part of an external process. + +--- + +**Running Horizen Desktop GUI Wallet on macOS Catalina**: Horizen Desktop GUI Wallet is not going to be notarized and as such won't start on macOS Catalina without going through some extra steps, if you want to run it on MacOS Catalina or later please read and follow https://support.apple.com/en-us/HT202491 `How to open an app that hasn’t been notarized or is from an unidentified developer`. + +## Graphical user interface wrapper for the [Horizen](https://horizen.io/) command line tools + +This program provides a Graphical User Interface (GUI) for the Horizen client tools that acts as a wrapper and presents the information in a user-friendly manner. -![Screenshot](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/raw/master/docs/ZENCashWallet.png "Main Window") +![Screenshot](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/raw/master/docs/ZENCashWallet.png "Main Window") + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** -#### New/Experimental: [ZENCash Desktop GUI Wallet packages for Debian/Ubuntu Linux](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/blob/master/docs/ReleaseUbuntuRepository.md) are available +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** -#### New/Experimental: [ZENCash Desktop GUI Wallet for Mac OS](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/blob/master/docs/Release_0.75.9.md) is available +#### New/Experimental: [Horizen Desktop GUI Wallet packages for Debian/Ubuntu Linux](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/ReleaseUbuntuRepository.md) are available -#### New/Experimental: [ZENCash Desktop GUI Wallet for Windows](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/blob/master/docs/Release_0.75.8.md) is available +#### New/Experimental: [Horizen Desktop GUI Wallet for Windows/macOS](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/Release_1.0.12.md) is available #### Information on diagnosing some common problems may be found in this [troubleshooting guide](docs/TroubleshootingGuide.md). ## Building, installing and running the Wallet GUI -Before installing the Desktop GUI Wallet you need to have ZENCash up and running. The following -[guide](https://github.com/ZencashOfficial/zen/blob/master/README.md) -explains how to set up [ZENCash](https://zensystem.io/). +Before installing the Desktop GUI Wallet you need to have Horizen up and running. The following +[guide](https://github.com/HorizenOfficial/zen/blob/master/README.md) +explains how to set up [Horizen](https://horizen.io/). **For security reasons it is recommended to always build the GUI wallet program from GitHub** -**[source](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/archive/master.zip).** +**[source](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/archive/master.zip).** The details of how to build it are described below (easy to follow). 1. Operating system and tools - As of June 2017 (ZENCash v1.0.9) this program is mostly tested on Linux and Mac OS X - (same limitation as [ZENCash](https://zensystem.io/)) with experimental support for Windows. - The Linux tools you need to build and run the Wallet GUI are Git, Java (JDK7 or later) and - Ant. If using Ubuntu Linux, they may be installed via command: - ``` - user@ubuntu:~/build-dir$ sudo apt-get install git default-jdk ant - ``` - For RedHat/CentOS/Fedora-type Linux systems the command is (like): + As of January 2019 (Horizen v2.0.16) this program supports Linux, macOS Sierra/High Sierra and Windows. + The Linux tools you need to build and run the Wallet GUI are Git, Java (JDK12) and Ant. + To install OpenJDK to meet the Java dependency, please follow the instructions on these links: + [Windows](https://adoptopenjdk.net/installation.html?variant=openjdk12&jvmVariant=hotspot#windows-msi) + [Linux](https://adoptopenjdk.net/installation.html?variant=openjdk12&jvmVariant=hotspot#linux-pkg) + [MacOS](https://adoptopenjdk.net/installation.html?variant=openjdk12&jvmVariant=hotspot#macos-pkg) + + For RedHat/CentOS/Fedora-type, you should be able to install git and ant running the following command: ``` - user@centos:~/build-dir$ sudo yum install java-1.8.0-openjdk git ant + user@centos:~/build-dir$ sudo yum install git ant ``` - The name of the JDK package (`java-1.8.0-openjdk`) may vary depending on the Linux system, so you need to - check it, if name `java-1.8.0-openjdk` is not accepted. - If you have some other Linux distribution, please check your relevant documentation on installing Git, + If you have some Linux distribution that those instructions do not apply to, please check your relevant documentation on installing Git, JDK and Ant. The commands `git`, `java`, `javac` and `ant` need to be startable from command line before proceeding with build. @@ -51,7 +91,7 @@ The details of how to build it are described below (easy to follow). As a start you need to clone the zencash-swing-wallet-ui Git repository: ``` - user@ubuntu:~/build-dir$ git clone https://github.com/ZencashOfficial/zencash-swing-wallet-ui.git + user@ubuntu:~/build-dir$ git clone https://github.com/HorizenOfficial/zencash-swing-wallet-ui.git ``` Change the current directory: ``` @@ -70,28 +110,28 @@ The details of how to build it are described below (easy to follow). file `./build/jars/ZENCashSwingWalletUI.jar`. In addition the JAR file `bitcoinj-core-0.14.5.jar` is also necessary to run the wallet. -3. Installing the built ZENCash GUI wallet +3. Installing the built Horizen GUI wallet - 3.1. If you have built ZENCash from source code: + 3.1. If you have built Horizen from source code: - Assuming you have already built from source code [ZENCash](https://zensystem.io/) in directory `/home/user/zen/src` (for example - this is the typical build dir. for ZENCash v1.0.9) which contains the command line tools `zen-cli` and `zend` you need to take the created JAR files and copy them to directory `/home/user/zen/src` (the same dir. that contains `zen-cli` and `zend`). Example copy command: + Assuming you have already built from source code [Horizen](https://github.com/HorizenOfficial/zen) in directory `/home/user/zen/src` (for example - this is the typical build dir. for Horizen v2.0.16) which contains the command line tools `zen-cli` and `zend` you need to take the created JAR files and copy them to directory `/home/user/zen/src` (the same dir. that contains `zen-cli` and `zend`). Example copy command: ``` user@ubuntu:~/build-dir/zencash-swing-wallet-ui$ cp -R -v ./build/jars/* /home/user/zen/src ``` -4. Running the installed ZENCash GUI wallet +4. Running the installed Horizen GUI wallet It may be run from command line or started from another GUI tool (e.g. file manager). - Assuming you have already installed [ZENCash](https://zensystem.io/) and the GUI Wallet `ZENCashSwingWalletUI.jar` in + Assuming you have already installed [Horizen](https://horizen.io/) and the GUI Wallet `ZENCashSwingWalletUI.jar` in directory `/home/user/zen/src` one way to run it from command line is: ``` user@ubuntu:~/build-dir/zencash-swing-wallet-ui$ java -jar /home/user/zen/src/ZENCashSwingWalletUI.jar ``` If you are using Ubuntu (or similar ;) Linux you may instead just use the file manager and right-click on the `ZENCashSwingWalletUI.jar` file and choose the option "Open with OpenJDK 8 Runtime". - This will start the ZENCash GUI wallet. + This will start the Horizen GUI wallet. - **Important:** the ZENCash configuration file `~/.zen/zen.conf` needs to be correctly set up for the GUI + **Important:** the Horizen configuration file `~/.zen/zen.conf` needs to be correctly set up for the GUI wallet to work. Specifically the RPC user and password need to be set in it like: ``` rpcuser=username @@ -101,7 +141,7 @@ The details of how to build it are described below (easy to follow). ### License -This program is distributed under an [MIT License](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/raw/master/LICENSE). +This program is distributed under an [MIT License](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/raw/master/LICENSE). ### Disclaimer @@ -115,14 +155,14 @@ SOFTWARE. ### Known issues and limitations -1. Issue: The ZENCash Desktop GUI Wallet is not compatible with applications that modify the ZEN `wallet.dat` file. The wallet should not be used +1. Issue: The Horizen Desktop GUI Wallet is not compatible with applications that modify the ZEN `wallet.dat` file. The wallet should not be used with such applications on the same PC. For instance some distributed exchange applications are known to create watch-only addresses in the `wallet.dat` file that cause the GUI wallet to display a wrong balance and/or display addresses that do not belong to the wallet. 1. Limitation: if two users exchange text messages via the messaging UI TAB and one of them has a system clock, substantially running slow or fast by more than 1 minute, it is possible that this user will see text messages appearing out of order. 1. Limitation: if a messaging identity has been created (happens on first click on the messaging UI tab), then replacing the `wallet.dat` or changing the node configuration between mainnet and testnet will make the identity invalid. This will result in a wallet update error. To remove the error the directory `~/.ZENCashSwingWalletUI/messaging` may be manually renamed or deleted (when the wallet is stopped). **CAUTION: all messaging history will be lost in this case!** -1. Limitation: Wallet encryption has been temporarily disabled in ZENCash due to stability problems. A corresponding issue +1. Limitation: Wallet encryption has been temporarily disabled in Horizen due to stability problems. A corresponding issue [#1552](https://github.com/zcash/zcash/issues/1552) has been opened by the ZCash developers. Correspondingly -wallet encryption has been temporarily disabled in the ZENCash Desktop GUI Wallet. +wallet encryption has been temporarily disabled in the Horizen Desktop GUI Wallet. The latter needs to be disabled. 1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address transactions). A corresponding issue [#1438](https://github.com/zcash/zcash/issues/1438) has been opened @@ -136,6 +176,3 @@ Windows you need to right-click on `ZENCashSwingWalletUI.exe` and choose option: ``` Properties >> Compatibility >> Override High DPI scaling behavior >> Scaling Performed by (Application) ``` -Example: - -![DPI Scaling](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/raw/master/docs/EXEScalingSettings.png "DPI Scaling") diff --git a/docs/IV_Github_GPG_public.key b/docs/IV_Github_GPG_public.key deleted file mode 100644 index 17f426cd..00000000 Binary files a/docs/IV_Github_GPG_public.key and /dev/null differ diff --git a/docs/IV_Github_GPG_public_key.txt b/docs/IV_Github_GPG_public_key.txt deleted file mode 100644 index 84265e69..00000000 --- a/docs/IV_Github_GPG_public_key.txt +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 - -mQINBFhVAR8BEACjWyvHZ22nLblUfNZqmhPFkVGmPEEG91LoLrqNUU9hEBhRKjDY -HtKGdedCKU8qb+G/9EF5f6k4jtC/tFIaNC1oDiOgu5Ti029nUa4tsKdYPeH6pfTk -4r/aakH2jTF51raG5uG549fte5bqgiflkcQG+47lddYxOlExnBk8FhmJiHvJtheq -AwZHpnOrB40dmtAC5xBu4OF7ugR5C49YmQ+2Ob96DF+Cwd3eIcZm4JPdaFuPlp7a -0wIUHbYR+RIAPRhv6uhwnAC1F4zp1XR69y+I0qK3mrE/sXcshjWZo3vA8851ZpAE -N6lTHbDwXrEjPPHNY7xZ0nb007BYDbDuzsdBBg9YD8FOgoPqWsbKAImcJ+D9kkNo -NvsWGyjLd96S5jbnv02VENh+tPpZyp7Em+Uo21yIW0y75qj0hBAerzs9703Ac7kF -0kcsE+fmJaaeatZNmJ1eoWAf4fJr0lNvSynrUebHI9z9sZ2kg6tEB/AneoKv3g9V -BSaY0X3XV/u2Byk0W7VZEgLO3CLhVo8r5tVH9vyEQVMWzG+B5Iox5S16Sh0PDEUP -3NmVSWBcZunUfIk9vKNLso2yNgZU08qHh7C1KsyemXasiGOgPdVmrh0QyHp4rgKK -I2+SUQxxk6efDDMtCs5PnswToLKM/WNJsWBaAlbLoJqOpAFRNj0Q+rmJzQARAQAB -tC9JdmFuIFZha2xpbm92IChHaXRIdWIgRGV2LikgPGl2YW5AdmFrbGlub3YuY29t -PokCOAQTAQIAIgUCWFUBHwIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ -TG9dNsFDSKAnfhAAhkjifHRq7BT/BL5ezBljZ2/oXL4Wc/bsFciRbt/xrNKlMd7y -X8uRqrdqwpRqNtmbDZt5YEy1khUK2ML9doNsUCjRKpNkuMxes0bC+QHEPlTLKrJ6 -X8NJWm/GL34ZzNv3dvIY6y1k7HRSztkByj6U+xoEkg20o5Oag8sljcItEgIgYerG -Xuj7P7cTUPOy7EtiRV9cyVqKCeVXOFDQgVTLVMl3N+V19LWGo5UzAexmxGr7k74t -zSaOiZt15MhOoBY5fG9bEaF6mI7x6t2Oiy5A0Za3jP4Ss6LekwSLDjz2JIuSlY0w -XjaG6Sy8ss/7EkWxHSoh7BoAP3BxL+0t1s2orxIguB2WMqmb4NO1jRZQaHvs3xcW -CbSbP+hGeuSn5adL+BHicB2kDzkk98NowcguBzR82htzQxaZxgMNCzp7mGqeALMr -RKyBi6QYsbhKsCWIU2INhzg/91P/FmzT8UuMqD7QnZzC78Mq90RiiNN4tgko6473 -Ho2kDYOpXc3nhqmpoiuXXu2JglpAJm2PA8V6cBrNdOizhV93c2Lx/ex4E3D+JWn8 -9/GhQSUHr5MkiUoZCMqhUKJi3Jx5yBYGxOPqtAupKwMumsIbXXyIWOwIc51mgjvv -8Zyj3AiDDGAoQX5dS+bRcQD5wrwN43dKhtWrOWGsb5bSBOrcVSLOdN1LKxy5Ag0E -WFUBHwEQAL1bSfrV6xZLSz/mXM/J19KrQh2Z9sZhX2DUpL1XzbqSW1TvrWmplnsa -ThnN/zAYsdWxTuQqlyq8gRwAdfr0+UDD3euEPHXdN9i6Oxrsq5qbsaPWohxBx6M5 -knMW6I2f9j4cMzOLU07i35ekVt8wYSnvi4+U/ZDBZgRvvkqqR8P3+6XSCxTnWXGE -r3vuqtN/hD8aL6Kogd3gWMGk8NfCAv/UK4nQVcn7Pnb9ZfkMJGh8u6ZhjUMTp64o -TRl6OBDCnGxM2RpqijK74wqsJQztdnuQNFqptXOpw9gSzc4rFjxre3tmhn3njHDI -Wn16LppdXnhUiTd/SmJHlfHgX8COjVZu8ZnpjMwaBIo3hf3aaUiz6yoeultJKwYi -qXimSXOEEm1oPwSPNX2uOuWLimHQ9J/SCBV4w38YqCiHootAGHmTDkthmbYFxOmn -bwyjHAgOtCAf298SxghZ9PNucL+66gLf7Q946hpwbpHURy2zkjxxcOZYEkA8zC2P -7EuklIhMWCC6a9V0mHQLu53NugkzkJxxtlGC6PYrzdg7+8H9rL6d8bTW94NktO9i -P6Lwo5i8WjY8e+HfhpBSsVcDJ3DJW1wWhLr5yjLqv7xezosSvRiT46iIkhA607eg -FLnGJvw2f2V5l6RbIX06a5MeQq2VGzKxuIvuQ32kfyjRx0/6HKrRABEBAAGJAh8E -GAECAAkFAlhVAR8CGwwACgkQTG9dNsFDSKAk/g//S8ZOY0G8t+sewYHttewGx+R/ -NcOlZsBTfaB2mm66z6cnYpK1fC4K8T55p37aecGQYgVYFn/6kQ+H2Nif26vLc+nV -3f7WC6JBBQJGF8r997yCPkASapro3wQRszWDQZGMkDsSezu3rKV/PtNfup7Lk7Xp -s7ZLl+KSBMH6hU4E8EXvdkYXnzYRW4N4kNJu2aZZVrYMZq4KkRa3c49y69lLbfmz -f+8Q/HW+cTUOVf/caeI4o1P5wPLJs0iw/kX/vZRaAnHbCXRSVUtCqJsMMYXuWdiL -IGCvpWEE2AbF/2vyjeD9yexlI/ZF1bOa0fYaK90+GvtaGUjBISYrsNHtxEBG3CyO -IJaZn0LdCe6NXr9IU2UwttjFKx3C1l+VUpqqupUOmwuTOCBx2pgzd3h4JmGGwz50 -G97c8fUVRvFR9PJcuIQyInYRM3V2FcPzCVsv1TaUHR8XMv6I4jIiO6dj223yWL4W -6kIjQW8/Js+7HN8eBh+PpqpgxgwAUtX1b5keX29xPzhbaxcwrtYzPD5t+kSuAKVn -wXZa5fUV6PRUAVGfoE78gmkAcZ+EnfRNjC08WUEZ6XXn4vVjtE+tTH0GhReQxi5R -1VnTiJXdftMoAe8XmB72gWhwmuBwayBu1W3E1F6nJLfFtU/+m+68SKCAptcZgwaY -Q6Ilae5JbbhJZn0mj0A= -=lK3H ------END PGP PUBLIC KEY BLOCK----- diff --git a/docs/ReleaseUbuntuRepository.md b/docs/ReleaseUbuntuRepository.md index 3f375ccd..7e4b7497 100644 --- a/docs/ReleaseUbuntuRepository.md +++ b/docs/ReleaseUbuntuRepository.md @@ -1,20 +1,32 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet APT repository for Debian/Ubuntu Linux +## [Horizen](https://horizen.io/) Desktop GUI Wallet APT repository for Debian/Ubuntu Linux -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet made available through a package repository +This is a [Horizen](https://horizen.io/) Desktop GUI Wallet made available through a package repository for Debian/Ubuntu (and similar) Linux systems. -### IMPORTANT: Please read the [security notice](KnownSecurityIssues.md) about watch-only addresses before using the wallet! - ![Screenshot](ZENCashWalletUbuntu.png "Main Window") -### Installing the ZENCash Desktop GUI Wallet on Linux +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +### Installing the Horizen Desktop GUI Wallet on Linux To setup the APT repository and install packages, using a terminal run the following commands ``` sudo apt-get update sudo apt-get install apt-transport-https lsb-release -echo 'deb https://zencashofficial.github.io/repo/ '$(lsb_release -cs)' main' | sudo tee --append /etc/apt/sources.list.d/zen.list +echo 'deb https://HorizenOfficial.github.io/repo/ '$(lsb_release -cs)' main' | sudo tee --append /etc/apt/sources.list.d/zen.list gpg --keyserver ha.pool.sks-keyservers.net --recv 219F55740BBF7A1CE368BA45FB7053CE4991B669 gpg --export 219F55740BBF7A1CE368BA45FB7053CE4991B669 | sudo apt-key add - @@ -33,9 +45,9 @@ Finally you need to download the Z cryptographic keys (takes a while): zen-fetch-params ``` -### Running the ZENCash Desktop GUI Wallet on Linux +### Running the Horizen Desktop GUI Wallet on Linux -To launch the ZENCash Desktop GUI Wallet you can just search and click on it in the Ubuntu unity menu: +To launch the Horizen Desktop GUI Wallet you can just search and click on it in the Ubuntu unity menu: ![UnityLauncher](ZENUnityLauncher.png "ZENCash Wallet launcher") ...or alternatively, run the command `zencash-desktop-gui-wallet` from a terminal: @@ -56,9 +68,9 @@ SOFTWARE. ### Known issues and limitations 1. Limitation: if two users exchange text messages via the messaging UI TAB and one of them has a system clock, substantially running slow or fast by more than 1 minute, it is possible that this user will see text messages appearing out of order. 1. Limitation: if a messaging identity has been created (happens on first click on the messaging UI tab), then replacing the `wallet.dat` or changing the node configuration between mainnet and testnet will make the identity invalid. This will result in a wallet update error. To remove the error the directory `~/.ZENCashSwingWalletUI/messaging` may be manually renamed or deleted (when the wallet is stopped). **CAUTION: all messaging history will be lost in this case!** -1. Limitation: Wallet encryption has been temporarily disabled in ZENCash due to stability problems. A corresponding issue +1. Limitation: Wallet encryption has been temporarily disabled in Horizen due to stability problems. A corresponding issue [#1552](https://github.com/zcash/zcash/issues/1552) has been opened by the ZCash developers. Correspondingly -wallet encryption has been temporarily disabled in the ZENCash Desktop GUI Wallet. +wallet encryption has been temporarily disabled in the Horizen Desktop GUI Wallet. 1. Issue: GUI data tables (transactions/addresses etc.) allow copying of data via double click but also allow editing. The latter needs to be disabled. 1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address diff --git a/docs/Release_0.71.4.md b/docs/Release_0.71.4.md deleted file mode 100644 index 67668f55..00000000 --- a/docs/Release_0.71.4.md +++ /dev/null @@ -1,50 +0,0 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.71.4a for Mac OS - -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.71.4a for Mac OS. -It includes [ZENCash 2.0.9-4 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.9-4) -by [@cronicc](https://github.com/cronicc). - -**This release contains the ZenCash [Mandatory Software Upgrade](https://blog.zensystem.io/zencash-hard-fork-at-block-139200-on-friday-july-21th-1400-edt/) at Block 139,200 on Friday July 21th 14:00 EDT** - -![Screenshot](ZENCashWalletMac.png "Main Window") - -### Installing the ZENCash Desktop GUI Wallet on Mac OS - -1. Download the Wallet image file -[ZENCashWallet-0.71.4a.dmg](https://github.com/vaklinov/zencash-swing-wallet-ui/releases/download/0.71.4/ZENCashWallet-0.71.4a.dmg). - -2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool -such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The -result should be: -``` -32cab9e88d1f96fe6eca21693a302d613651370d4636e7a7aa093ad9dda6e983 ZENCashWallet-0.71.4a.dmg -``` -**If the resulting checksum is not `32cab9e88d1f96fe6eca21693a302d613651370d4636e7a7aa093ad9dda6e983` then** -**something is wrong and you should discard the downloaded wallet!** - -3. You need to (at least temporarily) allow the installation of "apps downloaded from anywhere" on your Mac. -[This article](http://osxdaily.com/2016/09/27/allow-apps-from-anywhere-macos-gatekeeper/) is a good description -of how to do this. This step will not be necessary in future releases. - -4. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.71.4a.dmg` -and copy the ZENCashWallet application to the Applications folder. You can then discard the disk image. - -### Running the ZENCash Desktop GUI Wallet on Mac OS - -Simply click on ZENCashWallet in the Mac OS application launchpad. - -### Disclaimer - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -### Known issues and limitations -1. Issue: GUI data tables (transactions/addresses etc.) allow copying of data via double click but also allow editing. -The latter needs to be disabled. -1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address -transactions). diff --git a/docs/Release_0.73.1.md b/docs/Release_0.73.1.md deleted file mode 100644 index e46b30ae..00000000 --- a/docs/Release_0.73.1.md +++ /dev/null @@ -1,49 +0,0 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.73.1 for Windows - -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.73.1 for Windows. -It requires a 64-bit Windows 7 or later version to run. It also includes [ZENCash 2.0.9-4 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.9-4) by [@cronicc](https://github.com/cronicc). - -This release includes an initial/early version of the one-to-one ZEN messaging functionality. The messaging -UI TAB allows users to securely exchange text messages. This release does not yet include features such as -group messaging or IPFS integration (will be developed in future releases). - -![Screenshot](ZENChat.png "Main Window") - -### Installing the ZENCash Desktop GUI Wallet on Windows - -1. Download the Wallet ZIP file -[ZENCashSwingWalletUI_0.73.1.zip](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/releases/download/0.73.1/ZENCashSwingWalletUI_0.73.1.zip). - -2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool -such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The -result should be: -``` -1ec2c45e86295031fdd663850ad55a4e4a7b876ec6a3e62dd0c9db115dae9223 ZENCashSwingWalletUI_0.73.1.zip -``` -**If the resulting checksum is not `1ec2c45e86295031fdd663850ad55a4e4a7b876ec6a3e62dd0c9db115dae9223` then** -**something is wrong and you should discard the downloaded wallet!** - -3. Unzip the Wallet ZIP file `ZENCashSwingWalletUI_0.73.1.zip` in some directory that it will run from. - -### Running the ZENCash Desktop GUI Wallet on Windows - -Double click on `ZENCashSwingWalletUI.exe`. On first run (only) the wallet will download the cryptographic keys -(900MB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. - - -### Disclaimer - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -### Known issues and limitations -1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. -As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. -This problem will be fixed in future versions. -1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address -transactions). diff --git a/docs/Release_0.73.4.md b/docs/Release_0.73.4.md deleted file mode 100644 index e25aa255..00000000 --- a/docs/Release_0.73.4.md +++ /dev/null @@ -1,47 +0,0 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.73.4 for Mac OS - -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.73.4 for Mac OS. -It includes [ZENCash 2.0.10 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.10) -One notable new feature is the ability to send encrypted text messages between users on the ZEN blockchain. - -![Screenshot](ZENCashWalletMac_0.73.4.png "Main Window") - -### Installing the ZENCash Desktop GUI Wallet on Mac OS - -1. Download the Wallet image file -[ZENCashWallet-0.73.4.dmg](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/releases/download/0.73.4/ZENCashWallet-0.73.4.dmg). - -2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool -such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The -result should be: -``` -148152571ca14fa054742918dfae0be76875cf74658221b00fe23cf712db1ae4 ZENCashWallet-0.73.4.dmg -``` -**If the resulting checksum is not `148152571ca14fa054742918dfae0be76875cf74658221b00fe23cf712db1ae4` then** -**something is wrong and you should discard the downloaded wallet!** - -3. You need to (at least temporarily) allow the installation of "apps downloaded from anywhere" on your Mac. -[This article](http://osxdaily.com/2016/09/27/allow-apps-from-anywhere-macos-gatekeeper/) is a good description -of how to do this. This step will not be necessary in future releases. - -4. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.73.4.dmg` -and copy the ZENCashWallet application to the Applications folder. You can then discard the disk image. - -### Running the ZENCash Desktop GUI Wallet on Mac OS - -Simply click on ZENCashWallet in the Mac OS application launchpad. - -### Disclaimer - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -### Known issues and limitations -1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address -transactions). -2. Anonymous text messaging does not work reliably in both directions (works reliably in one direction only). diff --git a/docs/Release_0.74.2.md b/docs/Release_0.74.2.md deleted file mode 100644 index f7bd5b32..00000000 --- a/docs/Release_0.74.2.md +++ /dev/null @@ -1,47 +0,0 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.74.2 for Windows - -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.74.2 for Windows. -It requires a 64-bit Windows 7 or later version to run. It includes [ZENCash 2.0.10 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.10) - -Notable new features include messaging interface improvements for group messaging and ignoring/filtering contacts. - -![Screenshot](ZENCashWalletWindows_0.74.2.png "Main Window") - -### Installing the ZENCash Desktop GUI Wallet on Windows - -1. Download the Wallet ZIP file -[ZENCashDesktopGUIWallet_0.74.2.zip](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/releases/download/0.74.2/ZENCashDesktopGUIWallet_0.74.2.zip). - -2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool -such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The -result should be: -``` -f64af29a8cb242056be0dcdf29cf6630991ea29242a0a4c284d71595f9e00e10 ZENCashSwingWalletUI_0.74.2.zip -``` -**If the resulting checksum is not `f64af29a8cb242056be0dcdf29cf6630991ea29242a0a4c284d71595f9e00e10` then** -**something is wrong and you should discard the downloaded wallet!** - -3. Unzip the Wallet ZIP file `ZENCashDesktopGUIWallet_0.74.2.zip` in some directory that it will run from. - -### Running the ZENCash Desktop GUI Wallet on Windows - -Double click on `ZENCashDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys -(900MB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. - - -### Disclaimer - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -### Known issues and limitations -1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. -As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. -This problem will be fixed in future versions. -1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address -transactions). diff --git a/docs/Release_0.75.8.md b/docs/Release_0.75.8.md index a07308dc..8ad3335d 100644 --- a/docs/Release_0.75.8.md +++ b/docs/Release_0.75.8.md @@ -1,25 +1,27 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.8 for Windows +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.8a for Windows This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.8 for Windows. -It requires a 64-bit Windows 7 or later version to run. It includes [ZENCash 2.0.10-1 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.10-1) +It requires a 64-bit Windows 7 or later version to run. It includes [ZENCash 2.0.11 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.11). Originally the release was created with ZENCash 2.0.10-1 binaries but was upgraded to 2.0.11 due to +stability issues. + ### IMPORTANT: Please read the [security notice](KnownSecurityIssues.md) about watch-only addresses before using the wallet! ### Installing the ZENCash Desktop GUI Wallet on Windows 1. Download the Wallet ZIP file -[ZENCashDesktopGUIWallet_0.75.8.zip](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/releases/download/0.75.8/ZENCashDesktopGUIWallet_0.75.8.zip). +[ZENCashDesktopGUIWallet_0.75.8a.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.75.8/ZENCashDesktopGUIWallet_0.75.8a.zip). 2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The result should be: ``` -7d4ef3973aba20ad0d7961e0eef61c2e80b85c4049cec75b8171b5e26338b27b ZENCashDesktopGUIWallet_0.75.8.zip +2f8eee60181aed5475b1c82051c7b8abae31cd418384eceb866ef09389b8e3ad ZENCashDesktopGUIWallet_0.75.8a.zip ``` -**If the resulting checksum is not `7d4ef3973aba20ad0d7961e0eef61c2e80b85c4049cec75b8171b5e26338b27b` then** +**If the resulting checksum is not `2f8eee60181aed5475b1c82051c7b8abae31cd418384eceb866ef09389b8e3ad` then** **something is wrong and you should discard the downloaded wallet!** -3. Unzip the Wallet ZIP file `ZENCashDesktopGUIWallet_0.75.8.zip` in some directory that it will run from. +3. Unzip the Wallet ZIP file `ZENCashDesktopGUIWallet_0.75.8a.zip` in some directory that it will run from. ### Running the ZENCash Desktop GUI Wallet on Windows diff --git a/docs/Release_0.75.9.md b/docs/Release_0.75.9.md index c51d478f..1d9c34ba 100644 --- a/docs/Release_0.75.9.md +++ b/docs/Release_0.75.9.md @@ -1,7 +1,10 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.9 for Mac OS +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.9a for Mac OS + +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.9a for Mac OS. +It includes [ZENCash 2.0.11 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.11). +Originally the release was created with ZENCash 2.0.10-1 binaries but was upgraded to 2.0.11 due to +stability issues. -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.75.9 for Mac OS. -It includes [ZENCash 2.0.10-1 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.10-1) One notable new feature is the ability to send encrypted text messages in group conversations on the ZEN blockchain. It is also possible to block/ignore other users if they are spamming the conversation. ### IMPORTANT: Please read the [security notice](KnownSecurityIssues.md) about watch-only addresses before using the wallet! @@ -9,22 +12,22 @@ One notable new feature is the ability to send encrypted text messages in group ### Installing the ZENCash Desktop GUI Wallet on Mac OS 1. Download the Wallet image file -[ZENCashWallet-0.75.9.dmg](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/releases/download/0.75.9/ZENCashWallet-0.75.9.dmg). +[ZENCashWallet-0.75.9a.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.75.9/ZENCashWallet-0.75.9a.dmg). 2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The result should be: ``` -056dd920b740ccc087204c003886074005ad2187f68aa2ae9f6201e6e07a83c6 ZENCashWallet-0.75.9.dmg +10c68899f23055eaa036f83f8a0f1799ee057103080585ce3dc12779df760ffc ZENCashWallet-0.75.9a.dmg ``` -**If the resulting checksum is not `056dd920b740ccc087204c003886074005ad2187f68aa2ae9f6201e6e07a83c6` then** +**If the resulting checksum is not `10c68899f23055eaa036f83f8a0f1799ee057103080585ce3dc12779df760ffc` then** **something is wrong and you should discard the downloaded wallet!** 3. You need to (at least temporarily) allow the installation of "apps downloaded from anywhere" on your Mac. [This article](http://osxdaily.com/2016/09/27/allow-apps-from-anywhere-macos-gatekeeper/) is a good description of how to do this. This step will not be necessary in future releases. -4. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.75.9.dmg` +4. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.75.9a.dmg` and copy the ZENCashWallet application to the Applications folder. You can then discard the disk image. ### Running the ZENCash Desktop GUI Wallet on Mac OS diff --git a/docs/Release_0.80.5.md b/docs/Release_0.80.5.md new file mode 100644 index 00000000..c331f8bc --- /dev/null +++ b/docs/Release_0.80.5.md @@ -0,0 +1,61 @@ +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.80.5 for Windows + +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.80.5 for Windows. +It requires a 64-bit Windows 7 or later version to run. It includes [ZENCash 2.0.11 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.11). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for ZENCash. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 18 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the ZENCash Desktop GUI Wallet on Windows + +1. Download the Wallet ZIP file +[ZENCashDesktopGUIWallet_0.80.5.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.80.5/ZENCashDesktopGUIWallet_0.80.5.zip). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +3edf98620b458bb9eef70f9e317cbf56c0ef190e6d6983769a76015ff07ebd36 *ZENCashDesktopGUIWallet_0.80.5.zip +``` +**If the resulting checksum is not `3edf98620b458bb9eef70f9e317cbf56c0ef190e6d6983769a76015ff07ebd36` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Unzip the Wallet ZIP file `ZENCashDesktopGUIWallet_0.80.5.zip` in some directory that it will run from. + +### Running the ZENCash Desktop GUI Wallet on Windows + +Double click on `ZENCashDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys +(900MB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.74.7.md b/docs/Release_0.81.0.md similarity index 53% rename from docs/Release_0.74.7.md rename to docs/Release_0.81.0.md index 211793d5..3f122c04 100644 --- a/docs/Release_0.74.7.md +++ b/docs/Release_0.81.0.md @@ -1,30 +1,45 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.74.7 for Mac OS +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.81.0 for Mac OS -This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.74.7 for Mac OS. -It includes [ZENCash 2.0.10 binaries](https://github.com/ZencashOfficial/zen/releases/tag/v2.0.10) -One notable new feature is the ability to send encrypted text messages in group conversations on the ZEN blockchain. It is also possible to block/ignore other users if they are spamming the conversation. +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.81.0 for Mac OS. +It includes [ZENCash 2.0.11 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.11). -![Screenshot](ZENCashWalletMac_0.74.7.png "Main Window") +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for ZENCash. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 18 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** ### Installing the ZENCash Desktop GUI Wallet on Mac OS 1. Download the Wallet image file -[ZENCashWallet-0.74.7.dmg](https://github.com/ZencashOfficial/zencash-swing-wallet-ui/releases/download/0.74.7/ZENCashWallet-0.74.7.dmg). +[ZENCashWallet-0.81.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.81.0/ZENCashWallet-0.81.0.dmg). 2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The result should be: ``` -b7ff9e45909ec2fd17cb3629a5212b902e06f3f8a41a9f2ea427d2025356b82e ZENCashWallet-0.74.7.dmg +8d681460480787b7fbd9a05ca8faa5af9b1a995f56cd68e4a7109ae813abd7e7 ZENCashWallet-0.81.0.dmg ``` -**If the resulting checksum is not `b7ff9e45909ec2fd17cb3629a5212b902e06f3f8a41a9f2ea427d2025356b82e` then** +**If the resulting checksum is not `8d681460480787b7fbd9a05ca8faa5af9b1a995f56cd68e4a7109ae813abd7e7` then** **something is wrong and you should discard the downloaded wallet!** 3. You need to (at least temporarily) allow the installation of "apps downloaded from anywhere" on your Mac. [This article](http://osxdaily.com/2016/09/27/allow-apps-from-anywhere-macos-gatekeeper/) is a good description of how to do this. This step will not be necessary in future releases. -4. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.74.7.dmg` +4. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.81.0.dmg` and copy the ZENCashWallet application to the Applications folder. You can then discard the disk image. ### Running the ZENCash Desktop GUI Wallet on Mac OS @@ -41,7 +56,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -### Known issues and limitations +### Some known issues and limitations 1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address transactions). 1. Limitation: if two users exchange text messages via the messaging UI TAB and one of them has a system clock, substantially running slow or fast by more than 1 minute, it is possible that this user will see text messages appearing out of order. diff --git a/docs/Release_0.83.0.md b/docs/Release_0.83.0.md new file mode 100644 index 00000000..6db5a0e1 --- /dev/null +++ b/docs/Release_0.83.0.md @@ -0,0 +1,61 @@ +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.83.0 for Windows + +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.83.0 for Windows. +It requires a 64-bit Windows 7 or later version to run. It includes [ZENCash 2.0.14 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.14). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for ZENCash. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the ZENCash Desktop GUI Wallet on Windows + +1. Download the Wallet ZIP file +[ZENCashDesktopGUIWallet_0.83.0.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.83.0/ZENCashDesktopGUIWallet_0.83.0.zip). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +fba2adcc7ded9a9de345243214d78556a3061d91d4bb165be916654ea3393fd4 *ZENCashDesktopGUIWallet_0.83.0.zip +``` +**If the resulting checksum is not `fba2adcc7ded9a9de345243214d78556a3061d91d4bb165be916654ea3393fd4` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Unzip the Wallet ZIP file `ZENCashDesktopGUIWallet_0.83.0.zip` in some directory that it will run from. + +### Running the ZENCash Desktop GUI Wallet on Windows + +Double click on `ZENCashDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys +(900MB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.83.1.md b/docs/Release_0.83.1.md new file mode 100644 index 00000000..4ba3339c --- /dev/null +++ b/docs/Release_0.83.1.md @@ -0,0 +1,62 @@ +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.83.1 for Mac OS Sierra/High Sierra + +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.83.1 for Mac OS. +It includes [ZENCash 2.0.14 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.14). + +**This release does not support OS X 10.11 El Capitan anymore which is end of life,** +**to migrate to a different wallet follow this [GUIDE](https://documentation.zencash.com/x/tAJP).** + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for ZENCash. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the ZENCash Desktop GUI Wallet on Mac OS + +1. Download the Wallet image file +[ZENCashWallet-0.83.1.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.83.1/ZENCashWallet-0.83.1.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +10f69731236e6ce6029168ffba24dcf4e74d3940549d8e84928080a7997b4873 ZENCashWallet-0.83.1.dmg +``` +**If the resulting checksum is not `10f69731236e6ce6029168ffba24dcf4e74d3940549d8e84928080a7997b4873` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.83.1.dmg` +and copy the ZENCashWallet application to the Applications folder. You can then discard the disk image. + +### Running the ZENCash Desktop GUI Wallet on Mac OS + +Simply click on ZENCashWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). +1. Limitation: if two users exchange text messages via the messaging UI TAB and one of them has a system clock, substantially running slow or fast by more than 1 minute, it is possible that this user will see text messages appearing out of order. +1. Limitation: if a messaging identity has been created (happens on first click on the messaging UI tab), then replacing the `wallet.dat` or changing the node configuration between mainnet and testnet will make the identity invalid. This will result in a wallet update error. To remove the error the directory `~/.ZENCashSwingWalletUI/messaging` may be manually renamed or deleted (when the wallet is stopped). **CAUTION: all messaging history will be lost in this case!** diff --git a/docs/Release_0.84.0.md b/docs/Release_0.84.0.md new file mode 100644 index 00000000..924815e7 --- /dev/null +++ b/docs/Release_0.84.0.md @@ -0,0 +1,61 @@ +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.84.0 for Windows + +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.84.0 for Windows. +It requires a 64-bit Windows 7 or later version to run. It includes [ZENCash 2.0.15 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.15). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for ZENCash. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the ZENCash Desktop GUI Wallet on Windows + +1. Download the Wallet ZIP file +[ZENCashDesktopGUIWallet_0.84.0.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.84.0/ZENCashDesktopGUIWallet_0.84.0.zip). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +c33797f675a946fb5cc23a1347c64733d86399425f7b389c289f78878646efc0 ZENCashDesktopGUIWallet_0.84.0.zip +``` +**If the resulting checksum is not `c33797f675a946fb5cc23a1347c64733d86399425f7b389c289f78878646efc0` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Unzip the Wallet ZIP file `ZENCashDesktopGUIWallet_0.84.0.zip` in some directory that it will run from. + +### Running the ZENCash Desktop GUI Wallet on Windows + +Double click on `ZENCashDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys +(900MB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.84.1.md b/docs/Release_0.84.1.md new file mode 100644 index 00000000..c1640e3e --- /dev/null +++ b/docs/Release_0.84.1.md @@ -0,0 +1,62 @@ +## [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.84.1 for Mac OS Sierra/High Sierra + +This is a [ZENCash](https://zensystem.io/) Desktop GUI Wallet binary release 0.84.1 for Mac OS. +It includes [ZENCash 2.0.15 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.15). + +**This release does not support OS X 10.11 El Capitan anymore which is end of life,** +**to migrate to a different wallet follow this [GUIDE](https://documentation.zencash.com/x/tAJP).** + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for ZENCash. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the ZENCash Desktop GUI Wallet on Mac OS + +1. Download the Wallet image file +[ZENCashWallet-0.84.1.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.84.1/ZENCashWallet-0.84.1.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +19f9ab03e2b0f019b7472bc6dfeb46a6a76ba8ab736214698c1802c302827858 ZENCashWallet-0.84.1.dmg +``` +**If the resulting checksum is not `19f9ab03e2b0f019b7472bc6dfeb46a6a76ba8ab736214698c1802c302827858` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `ZENCashWallet-0.84.1.dmg` +and copy the ZENCashWallet application to the Applications folder. You can then discard the disk image. + +### Running the ZENCash Desktop GUI Wallet on Mac OS + +Simply click on ZENCashWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). +1. Limitation: if two users exchange text messages via the messaging UI TAB and one of them has a system clock, substantially running slow or fast by more than 1 minute, it is possible that this user will see text messages appearing out of order. +1. Limitation: if a messaging identity has been created (happens on first click on the messaging UI tab), then replacing the `wallet.dat` or changing the node configuration between mainnet and testnet will make the identity invalid. This will result in a wallet update error. To remove the error the directory `~/.ZENCashSwingWalletUI/messaging` may be manually renamed or deleted (when the wallet is stopped). **CAUTION: all messaging history will be lost in this case!** diff --git a/docs/Release_0.85.0.md b/docs/Release_0.85.0.md new file mode 100644 index 00000000..047a4163 --- /dev/null +++ b/docs/Release_0.85.0.md @@ -0,0 +1,61 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.85.0 for Windows + +This is a [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.85.0 for Windows. +It requires a 64-bit Windows 7 or later version to run. It includes [Horizen 2.0.16 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.16). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +1. Download the Wallet ZIP file +[HorizenDesktopGUIWallet_0.85.0.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.85.0/HorizenDesktopGUIWallet_0.85.0.zip). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +facef7a71047851199689606a563fbe9b12c4dcfbdb369340dc388ae239af3c1 HorizenDesktopGUIWallet_0.85.0.zip +``` +**If the resulting checksum is not `facef7a71047851199689606a563fbe9b12c4dcfbdb369340dc388ae239af3c1` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Unzip the Wallet ZIP file `HorizenDesktopGUIWallet_0.85.0.zip` in some directory that it will run from. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys +(1.6GB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.85.1.md b/docs/Release_0.85.1.md new file mode 100644 index 00000000..f1631aea --- /dev/null +++ b/docs/Release_0.85.1.md @@ -0,0 +1,62 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.85.1 for Mac OS Sierra/High Sierra/Mojave + +This is a [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.85.1 for Mac OS. +It includes [Horizen 2.0.16 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.16). + +**This release does not support OS X 10.11 El Capitan anymore which is end of life,** +**to migrate to a different wallet follow this [GUIDE](https://horizenofficial.atlassian.net/wiki/x/X4AoC).** + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +1. Download the Wallet image file +[HorizenWallet-0.85.1.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.85.1/HorizenWallet-0.85.1.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +ae1f0df047695bd7f6150331f70f431bda9a1394d3da394aa6513bc14bc63a7a HorizenWallet-0.85.1.dmg +``` +**If the resulting checksum is not `ae1f0df047695bd7f6150331f70f431bda9a1394d3da394aa6513bc14bc63a7a` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.85.1.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). +1. Limitation: if two users exchange text messages via the messaging UI TAB and one of them has a system clock, substantially running slow or fast by more than 1 minute, it is possible that this user will see text messages appearing out of order. +1. Limitation: if a messaging identity has been created (happens on first click on the messaging UI tab), then replacing the `wallet.dat` or changing the node configuration between mainnet and testnet will make the identity invalid. This will result in a wallet update error. To remove the error the directory `~/.HorizenSwingWalletUI/messaging` may be manually renamed or deleted (when the wallet is stopped). **CAUTION: all messaging history will be lost in this case!** diff --git a/docs/Release_0.86.0.md b/docs/Release_0.86.0.md new file mode 100644 index 00000000..f9bee088 --- /dev/null +++ b/docs/Release_0.86.0.md @@ -0,0 +1,84 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.86.0 + +It includes [Horizen 2.0.17 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.17). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet ZIP file +[HorizenDesktopGUIWallet_0.86.0.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.86.0/HorizenDesktopGUIWallet_0.86.0.zip). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +c21676bd909bcb10589f4a6f3409830f346f4d32fa448b12668630dc3cf8e50b HorizenDesktopGUIWallet_0.86.0.zip +``` +**If the resulting checksum is not `c21676bd909bcb10589f4a6f3409830f346f4d32fa448b12668630dc3cf8e50b` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Unzip the Wallet ZIP file `HorizenDesktopGUIWallet_0.86.0.zip` in some directory that it will run from. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys +(1.6GB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.86.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.86.0/HorizenDesktopGUIWallet-0.86.0.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +e32ebd283364fbb3d4fab5984aefd400e9377c87c891661af32ac01b58888d16 HorizenWallet-0.86.0.dmg +``` +**If the resulting checksum is not `e32ebd283364fbb3d4fab5984aefd400e9377c87c891661af32ac01b58888d16` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.86.0.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.87.0.md b/docs/Release_0.87.0.md new file mode 100644 index 00000000..7c7a9ebc --- /dev/null +++ b/docs/Release_0.87.0.md @@ -0,0 +1,84 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.87.0 + +It includes [Horizen 2.0.18 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.18). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet ZIP file +[HorizenDesktopGUIWallet_0.87.0.zip](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.87.0/HorizenDesktopGUIWallet-0.87.0.zip). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +2caa932df847211abde12bc4fdb7b831769746f05c7776848ee6e00785ce4e6f HorizenDesktopGUIWallet-0.87.0.zip +``` +**If the resulting checksum is not `2caa932df847211abde12bc4fdb7b831769746f05c7776848ee6e00785ce4e6f` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Unzip the Wallet ZIP file `HorizenDesktopGUIWallet_0.87.0.zip` in some directory that it will run from. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe`. On first run (only) the wallet will download the cryptographic keys +(1.6GB or so). In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.87.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.87.0/HorizenDesktopGUIWallet-0.87.0.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +701d6279bbc0420723d162b9b2b4f7bc24f3ead20b581e3a240eb8cce096f303 HorizenDesktopGUIWallet-0.87.0.dmg +``` +**If the resulting checksum is not `701d6279bbc0420723d162b9b2b4f7bc24f3ead20b581e3a240eb8cce096f303` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.87.0.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.88.0.md b/docs/Release_0.88.0.md new file mode 100644 index 00000000..c79e9af8 --- /dev/null +++ b/docs/Release_0.88.0.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.88.0 + +It includes [Horizen 2.0.19 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.19). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-0.88.0.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.88.0/HorizenDesktopGUIWallet-0.88.0.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +58ce0261f80d49dacd3e5542c1282e44fba377c4f8ab7fa51d29c61e06e04df9 HorizenDesktopGUIWallet-0.88.0.exe +``` +**If the resulting checksum is not `58ce0261f80d49dacd3e5542c1282e44fba377c4f8ab7fa51d29c61e06e04df9` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-0.88.0.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.88.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.88.0/HorizenDesktopGUIWallet-0.88.0.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +7f7956ed954591826b50999898b9b6ada8dc0839595e09f4eedc2feff4526e50 HorizenDesktopGUIWallet-0.88.0.dmg +``` +**If the resulting checksum is not `7f7956ed954591826b50999898b9b6ada8dc0839595e09f4eedc2feff4526e50` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.88.0.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.89.0.md b/docs/Release_0.89.0.md new file mode 100644 index 00000000..bc412be9 --- /dev/null +++ b/docs/Release_0.89.0.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.898.0 + +It includes [Horizen 2.0.20 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.20). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-0.89.0.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.89.0/HorizenDesktopGUIWallet-0.89.0.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +8dbde4f9ededc6fd604165f153f627e4286e0808502bf7d713ec5f2f449e3838 HorizenDesktopGUIWallet-0.89.0.exe +``` +**If the resulting checksum is not `8dbde4f9ededc6fd604165f153f627e4286e0808502bf7d713ec5f2f449e3838` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-0.89.0.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.89.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.89.0/HorizenDesktopGUIWallet-0.89.0.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +8b00132254d36e969c95bb138e40a7ceeedb45b7c635c0347dbe7132299bda1c HorizenDesktopGUIWallet-0.89.0.dmg +``` +**If the resulting checksum is not `8b00132254d36e969c95bb138e40a7ceeedb45b7c635c0347dbe7132299bda1c` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.89.0.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.90.0.md b/docs/Release_0.90.0.md new file mode 100644 index 00000000..9499009b --- /dev/null +++ b/docs/Release_0.90.0.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.90.0 + +It includes [Horizen 2.0.21 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.21). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-0.90.0.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.90.0/HorizenDesktopGUIWallet-0.90.0.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +5ab70e2ed6983b363f0cf8c28824eb3d3eb333d1938a52155de7a7be2c4e95c1 HorizenDesktopGUIWallet-0.90.0.exe +``` +**If the resulting checksum is not `5ab70e2ed6983b363f0cf8c28824eb3d3eb333d1938a52155de7a7be2c4e95c1` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-0.90.0.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.90.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.90.0/HorizenDesktopGUIWallet-0.90.0.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +03d541b81af102cc446c9489020fd4502aac3bb26807002267f08b16650cfc69 HorizenDesktopGUIWallet-0.90.0.dmg +``` +**If the resulting checksum is not `03d541b81af102cc446c9489020fd4502aac3bb26807002267f08b16650cfc69` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.90.0.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.90.1.md b/docs/Release_0.90.1.md new file mode 100644 index 00000000..5a5e13d4 --- /dev/null +++ b/docs/Release_0.90.1.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.90.1 + +It includes [Horizen 2.0.21 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.21). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-0.90.1.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.90.1/HorizenDesktopGUIWallet-0.90.1.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +494bda4af6c92f530bb16ff1fd867aebc531282e326bec5cda13f79bb510f3fe HorizenDesktopGUIWallet-0.90.1.exe +``` +**If the resulting checksum is not `494bda4af6c92f530bb16ff1fd867aebc531282e326bec5cda13f79bb510f3fe` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-0.90.1.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.90.1.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.90.1/HorizenDesktopGUIWallet-0.90.1.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +5ed571add32f7117f946d24f1a7beb19a29f6bccb0b1ddc344be026ea6953c65 HorizenDesktopGUIWallet-0.90.1.dmg +``` +**If the resulting checksum is not `5ed571add32f7117f946d24f1a7beb19a29f6bccb0b1ddc344be026ea6953c65` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.90.1.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_0.90.2.md b/docs/Release_0.90.2.md new file mode 100644 index 00000000..cf5b9575 --- /dev/null +++ b/docs/Release_0.90.2.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 0.90.2 + +It includes [Horizen 2.0.22 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.22). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-0.90.2.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.90.2/HorizenDesktopGUIWallet-0.90.2.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +11c9d6d47ad3f82e287f3290a60c6bcf1ec9e4615e16e3a14106c635e06aab73 HorizenDesktopGUIWallet-0.90.2.exe +``` +**If the resulting checksum is not `11c9d6d47ad3f82e287f3290a60c6bcf1ec9e4615e16e3a14106c635e06aab73` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-0.90.2.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-0.90.2.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/0.90.2/HorizenDesktopGUIWallet-0.90.2.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +93f86e8cfb1888a4710506ac8f05d0fd736ac2a5042f06224df7f27579969555 HorizenDesktopGUIWallet-0.90.2.dmg +``` +**If the resulting checksum is not `93f86e8cfb1888a4710506ac8f05d0fd736ac2a5042f06224df7f27579969555` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-0.90.2.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.0.md b/docs/Release_1.0.0.md new file mode 100644 index 00000000..0ac568de --- /dev/null +++ b/docs/Release_1.0.0.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.0 + +It includes [Horizen 2.0.23 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.23). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.0.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.0/HorizenDesktopGUIWallet-1.0.0.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +150e51a76d8179e145319cc7200f220017eea24ebb1b0ffffdd9de776155f700 HorizenDesktopGUIWallet-1.0.0.exe +``` +**If the resulting checksum is not `150e51a76d8179e145319cc7200f220017eea24ebb1b0ffffdd9de776155f700` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.0.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.0.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.0/HorizenDesktopGUIWallet-1.0.0.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +7bc60e003f7e1f2d6d7cde9cde42660adc0e86f9de83d0fe70b65e0355001dcb HorizenDesktopGUIWallet-1.0.0.dmg +``` +**If the resulting checksum is not `7bc60e003f7e1f2d6d7cde9cde42660adc0e86f9de83d0fe70b65e0355001dcb` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.0.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.1.md b/docs/Release_1.0.1.md new file mode 100644 index 00000000..3127dd39 --- /dev/null +++ b/docs/Release_1.0.1.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.1 + +It includes [Horizen 2.0.24 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v2.0.24). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.1.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.1/HorizenDesktopGUIWallet-1.0.1.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +25497a1d445ee8c6600782fe0ea4e50fb2c0ca252a299147bedd04064da330cc HorizenDesktopGUIWallet-1.0.1.exe +``` +**If the resulting checksum is not `25497a1d445ee8c6600782fe0ea4e50fb2c0ca252a299147bedd04064da330cc` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.1.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.1.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.1/HorizenDesktopGUIWallet-1.0.1.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +fac5abd2a34c822c76df575c4d6e5efd7c2d659f23ed2edc572f1a7eb81b46d6 HorizenDesktopGUIWallet-1.0.1.dmg +``` +**If the resulting checksum is not `fac5abd2a34c822c76df575c4d6e5efd7c2d659f23ed2edc572f1a7eb81b46d6` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.1.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.10.md b/docs/Release_1.0.10.md new file mode 100644 index 00000000..96c2220e --- /dev/null +++ b/docs/Release_1.0.10.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.10 + +It includes [Horizen 3.3.1 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.3.1). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.10.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.10/HorizenDesktopGUIWallet-1.0.10.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +e4de2fb3dc68888dad45dffdefb34213f27ddab9aa23a54c57ace6e38cd52de7 HorizenDesktopGUIWallet-1.0.10.exe +``` +**If the resulting checksum is not `e4de2fb3dc68888dad45dffdefb34213f27ddab9aa23a54c57ace6e38cd52de7` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.10.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.10.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.10/HorizenDesktopGUIWallet-1.0.10.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +de46776da659fb4639ad46002da30bfafee93e8bb1c180a9e1c8740815ab24e4 HorizenDesktopGUIWallet-1.0.10.dmg +``` +**If the resulting checksum is not `de46776da659fb4639ad46002da30bfafee93e8bb1c180a9e1c8740815ab24e4` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.10.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.11.md b/docs/Release_1.0.11.md new file mode 100644 index 00000000..dbdab652 --- /dev/null +++ b/docs/Release_1.0.11.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.11 + +It includes [Horizen 4.0.0 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v4.0.0). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.11.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.11/HorizenDesktopGUIWallet-1.0.11.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +667bf7321cc2681e4fb84cae4dcfb5af83bb32c6a359e1462c0356e1b56d23c2 HorizenDesktopGUIWallet-1.0.11.exe +``` +**If the resulting checksum is not `667bf7321cc2681e4fb84cae4dcfb5af83bb32c6a359e1462c0356e1b56d23c2` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.11.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.11.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.11/HorizenDesktopGUIWallet-1.0.11.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +eb581627d35f25ff23a675febdaee81afbe099ab6b20768b73ebb9468b864435 HorizenDesktopGUIWallet-1.0.11.dmg +``` +**If the resulting checksum is not `eb581627d35f25ff23a675febdaee81afbe099ab6b20768b73ebb9468b864435` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.11.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.12.md b/docs/Release_1.0.12.md new file mode 100644 index 00000000..63c0da15 --- /dev/null +++ b/docs/Release_1.0.12.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.12 + +It includes [Horizen 4.1.0 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v4.1.0). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.12.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.12/HorizenDesktopGUIWallet-1.0.12.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +a642d33bd87efbb82bb9f09c024342e9c1c8d212ca982beb5a72bb27a592539c HorizenDesktopGUIWallet-1.0.12.exe +``` +**If the resulting checksum is not `a642d33bd87efbb82bb9f09c024342e9c1c8d212ca982beb5a72bb27a592539c` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.12.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.12.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.12/HorizenDesktopGUIWallet-1.0.12.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +eefeceffc3a48a53e57dc24696b33fda58b7863eae8406e1b326001212c62f4c HorizenDesktopGUIWallet-1.0.12.dmg +``` +**If the resulting checksum is not `eefeceffc3a48a53e57dc24696b33fda58b7863eae8406e1b326001212c62f4c` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.12.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.2.md b/docs/Release_1.0.2.md new file mode 100644 index 00000000..4dbb2c41 --- /dev/null +++ b/docs/Release_1.0.2.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.2 + +It includes [Horizen 3.0.0 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.0.0). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.2.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.2/HorizenDesktopGUIWallet-1.0.2.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +cc6cbffc7c8d4b9dca75a2f7c89113392d9e0f4c6017246ce375304709f37b5a HorizenDesktopGUIWallet-1.0.2.exe +``` +**If the resulting checksum is not `cc6cbffc7c8d4b9dca75a2f7c89113392d9e0f4c6017246ce375304709f37b5a` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.2.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.2.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.2/HorizenDesktopGUIWallet-1.0.2.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +c162b43e82153e33e84a75a34ccec42ad196db815a5e845fcca5b857ae3aaf54 HorizenDesktopGUIWallet-1.0.2.dmg +``` +**If the resulting checksum is not `c162b43e82153e33e84a75a34ccec42ad196db815a5e845fcca5b857ae3aaf54` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.2.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.3.md b/docs/Release_1.0.3.md new file mode 100644 index 00000000..678bc857 --- /dev/null +++ b/docs/Release_1.0.3.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.3 + +It includes [Horizen 3.0.1 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.0.1). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.3.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.3/HorizenDesktopGUIWallet-1.0.3.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +bb18201fc755773cec53d513752be0561b17016c2e405fd71cd3a4af2ba2d012 HorizenDesktopGUIWallet-1.0.3.exe +``` +**If the resulting checksum is not `bb18201fc755773cec53d513752be0561b17016c2e405fd71cd3a4af2ba2d012` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.3.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.3.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.3/HorizenDesktopGUIWallet-1.0.3.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +082980648853fb5135fc3ef1261c09de96e308ae777e634ef626840d59858ea6 HorizenDesktopGUIWallet-1.0.3.dmg +``` +**If the resulting checksum is not `082980648853fb5135fc3ef1261c09de96e308ae777e634ef626840d59858ea6` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.3.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.4.md b/docs/Release_1.0.4.md new file mode 100644 index 00000000..1b861694 --- /dev/null +++ b/docs/Release_1.0.4.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.4 + +It includes [Horizen 3.0.2 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.0.2). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.4.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.4/HorizenDesktopGUIWallet-1.0.4.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +b2d08fd3f3a93d0a72cb9a0f39a6be3da336ed9e37f728bb1ba7058173c05ba7 HorizenDesktopGUIWallet-1.0.4.exe +``` +**If the resulting checksum is not `b2d08fd3f3a93d0a72cb9a0f39a6be3da336ed9e37f728bb1ba7058173c05ba7` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.4.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.4.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.4/HorizenDesktopGUIWallet-1.0.4.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +50d494888c3268745ec8c5809907d135437a19699860eeb554a2ded458b1c834 HorizenDesktopGUIWallet-1.0.4.dmg +``` +**If the resulting checksum is not `50d494888c3268745ec8c5809907d135437a19699860eeb554a2ded458b1c834` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.4.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.5.md b/docs/Release_1.0.5.md new file mode 100644 index 00000000..bfc297b7 --- /dev/null +++ b/docs/Release_1.0.5.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.5 + +It includes [Horizen 3.0.3 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.0.3). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.5.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.5/HorizenDesktopGUIWallet-1.0.5.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +46db36769de40adf57c55def3275d94b2ab177e7b53e1422eda569a15751ade8 HorizenDesktopGUIWallet-1.0.5.exe +``` +**If the resulting checksum is not `46db36769de40adf57c55def3275d94b2ab177e7b53e1422eda569a15751ade8` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.5.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.5.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.5/HorizenDesktopGUIWallet-1.0.5.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +b97f2478dd0afeff9f3fbddbeb6b50e03349b22eb48122a546cb9d8061ce6fa1 HorizenDesktopGUIWallet-1.0.5.dmg +``` +**If the resulting checksum is not `b97f2478dd0afeff9f3fbddbeb6b50e03349b22eb48122a546cb9d8061ce6fa1` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.5.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.6.md b/docs/Release_1.0.6.md new file mode 100644 index 00000000..e81a4a51 --- /dev/null +++ b/docs/Release_1.0.6.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.6 + +It includes [Horizen 3.1.0 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.1.0). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.6.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.6/HorizenDesktopGUIWallet-1.0.6.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +3383f41a478eb6e596aa80e2cb6c2ab12bdfbe77a973af089aae20a6e6849277 HorizenDesktopGUIWallet-1.0.6.exe +``` +**If the resulting checksum is not `3383f41a478eb6e596aa80e2cb6c2ab12bdfbe77a973af089aae20a6e6849277` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.6.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.6.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.6/HorizenDesktopGUIWallet-1.0.6.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +c99163d464677c0837080dd85dc80ef03d641059d4c7fdf4bab316df40be95bd HorizenDesktopGUIWallet-1.0.6.dmg +``` +**If the resulting checksum is not `c99163d464677c0837080dd85dc80ef03d641059d4c7fdf4bab316df40be95bd` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.6.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.7.md b/docs/Release_1.0.7.md new file mode 100644 index 00000000..6d74f744 --- /dev/null +++ b/docs/Release_1.0.7.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.7 + +It includes [Horizen 3.2.0 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.2.0). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.7.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.7/HorizenDesktopGUIWallet-1.0.7.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +dfcd5bbef381759c4634d94eec93968d8843b80ccd1b6583495facb11b3ee5cf HorizenDesktopGUIWallet-1.0.7.exe +``` +**If the resulting checksum is not `dfcd5bbef381759c4634d94eec93968d8843b80ccd1b6583495facb11b3ee5cf` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.7.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.7.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.7/HorizenDesktopGUIWallet-1.0.7.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +f4af3348113fc1289766f81f6a869db57c0a0f331172cd1c6566ba4bc41ad73e HorizenDesktopGUIWallet-1.0.7.dmg +``` +**If the resulting checksum is not `f4af3348113fc1289766f81f6a869db57c0a0f331172cd1c6566ba4bc41ad73e` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.7.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.8.md b/docs/Release_1.0.8.md new file mode 100644 index 00000000..3b25a4b2 --- /dev/null +++ b/docs/Release_1.0.8.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.8 + +It includes [Horizen 3.2.1 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.2.1). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.8.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.8/HorizenDesktopGUIWallet-1.0.8.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +4fc4d45df0fd731c787bba18ebac96d97d99cfa56751a0130219276a4bab484d HorizenDesktopGUIWallet-1.0.8.exe +``` +**If the resulting checksum is not `4fc4d45df0fd731c787bba18ebac96d97d99cfa56751a0130219276a4bab484d` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.8.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.8.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.8/HorizenDesktopGUIWallet-1.0.8.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +93e2c2ffd3ab2bb45f8aaf84ade9858b2e7a49ad29dfa86ebef3f12fd0d7b830 HorizenDesktopGUIWallet-1.0.8.dmg +``` +**If the resulting checksum is not `93e2c2ffd3ab2bb45f8aaf84ade9858b2e7a49ad29dfa86ebef3f12fd0d7b830` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.8.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/Release_1.0.9.md b/docs/Release_1.0.9.md new file mode 100644 index 00000000..a2dfa2c1 --- /dev/null +++ b/docs/Release_1.0.9.md @@ -0,0 +1,85 @@ +## [Horizen](https://horizen.io/) Desktop GUI Wallet binary release 1.0.9 + +It includes [Horizen 3.3.0 binaries](https://github.com/HorizenOfficial/zen/releases/tag/v3.3.0). + +**This wallet is targeted at advanced users who understand the implications of running a full Zen node on** +**the local machine, maintaining a full local copy of the blockchain, maintaining and backing up the** +**Zen nodes's `wallet.dat` file etc! The wallet is not suitable for novice crypto-currency users!** + +**SECURITY WARNING: Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet** +**on a system infected with malware may result in wallet data/funds being stolen. The** +**wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40** +**outgoing transactions) and it must also be backed up after creating a new Z address.** + +**STABILITY WARNING: The GUI wallet is as yet considered experimental! It is known to exhibit occasional stability problems related to running a full Zen node.** +**Specifically if the locally running `zend` cannot start properly due to issues with the local blockchain, the GUI cannot start either!** +**Users need to be prepared to fix such problems manually as described in the [troubleshooting guide](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/master/docs/TroubleshootingGuide.md).** +**Doing so requires command line skills.** + +**AUTO-DEPRECATION WARNING: Wallet binary releases for Mac/Windows contain ZEN full node binaries. These have an auto-deprecation feature:** +**they are considered outdated after 16 weeks and stop working. So they need to be updated to a newer version before this term expires.** +**Users need to ensure they use an up-to-date version of the wallet (e.g. update the wallet every two months or so).** + +### Installing the Horizen Desktop GUI Wallet on Windows + +It requires a 64-bit Windows 7 or later version to run. + +1. Download the Wallet EXE file +[HorizenDesktopGUIWallet-1.0.9.exe](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.9/HorizenDesktopGUIWallet-1.0.9.exe). + +2. Security check: You may decide to run a virus scan on it, before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +18fb5f3360053a11481acb141027c53d0e4dd0f315ba1f367067f9a37f3764c6 HorizenDesktopGUIWallet-1.0.9.exe +``` +**If the resulting checksum is not `18fb5f3360053a11481acb141027c53d0e4dd0f315ba1f367067f9a37f3764c6` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Run the `HorizenDesktopGUIWallet-1.0.9.exe` installer and choose an installation folder. + +### Running the Horizen Desktop GUI Wallet on Windows + +Double click on `HorizenDesktopGUIWallet.exe` in the installation folder or run `HorizenDesktopGUIWallet` from the start menu. +On first run (only) the wallet will download the cryptographic keys (1.6GB or so). +In case of problems logs are written in `%LOCALAPPDATA%\ZENCashSwingWalletUI\` for diagnostics. + +### Installing the Horizen Desktop GUI Wallet on Mac OS + +It requires Mac OS Sierra/High Sierra/Mojave. + +1. Download the Wallet image file +[HorizenDesktopGUIWallet-1.0.9.dmg](https://github.com/HorizenOfficial/zencash-swing-wallet-ui/releases/download/1.0.9/HorizenDesktopGUIWallet-1.0.9.dmg). + +2. Security check: You may decide to run a virus scan on it before proceeding... In addition using a tool +such as [http://quickhash-gui.org/](http://quickhash-gui.org/) you may calculate the its SHA256 checksum. The +result should be: +``` +374d4cb62c48619efdf70d1fefd84b53da65a95c8f0c7528fb8de0b4f27bffd8 HorizenDesktopGUIWallet-1.0.9.dmg +``` +**If the resulting checksum is not `374d4cb62c48619efdf70d1fefd84b53da65a95c8f0c7528fb8de0b4f27bffd8` then** +**something is wrong and you should discard the downloaded wallet!** + +3. Install the wallet like any other downloaded Mac OS application: Open the disk image `HorizenWallet-1.0.9.dmg` +and copy the HorizenWallet application to the Applications folder. You can then discard the disk image. + +### Running the Horizen Desktop GUI Wallet on Mac OS + +Simply click on HorizenWallet in the Mac OS application launchpad. + +### Disclaimer + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +### Some known issues and limitations +1. If a system has a high resolution monitor with DPI scaling enabled, not all GUI elements scale alike. +As a result the Wallet UI may feel inconvenient to use at scaling above 1.5x or even unusable at scaling above 3x. +This problem will be fixed in future versions. +1. Limitation: The list of transactions does not show all outgoing ones (specifically outgoing Z address +transactions). diff --git a/docs/TroubleshootingGuide.md b/docs/TroubleshootingGuide.md index 047e61f6..766a45cf 100644 --- a/docs/TroubleshootingGuide.md +++ b/docs/TroubleshootingGuide.md @@ -1,4 +1,4 @@ -## [ZENCash](https://zensystem.io/) Desktop GUI Wallet troubleshooting guide +## [Horizen](https://horizen.io/) Desktop GUI Wallet troubleshooting guide ![Screenshot1](ZENChat_small.png "Chat Window") ![Screenshot1](ZENCashWalletMac_0.74.7_small.png "Wallet Window") @@ -10,15 +10,15 @@ When wallet problems occur, the information about the errors that caused the iss ``` Linux: ~/.ZENCashSwingWalletUI/ZENCashGUIWallet_xxxx_xx_debug.log Windows: %LOCALAPPDATA%/ZENCashSwingWalletUI/ZENCashGUIWallet_xxxx_xx_debug.log -Mac OS: ~/Library/Application Support/ZENCashSwingWalletUI/ZENCashGUIWallet_xxxx_xx_debug.log +macOS: ~/Library/Application Support/ZENCashSwingWalletUI/ZENCashGUIWallet_xxxx_xx_debug.log ``` `zend` that is automatically started by the wallet, stores its logs at locations: ``` Linux: ~/.zen/debug.log, Windows: %APPDATA%/Zen/debug.log -Mac OS: ~/Library/Application Support/Zen/debug.log +macOS: ~/Library/Application Support/Zen/debug.log ``` -The log files are the first place too look for clues as to the nature of problem. +The log files are the first place to look for clues as to the nature of problem. ### Common Problem 1 - wallet fails during start up @@ -34,7 +34,7 @@ works in 90%+ of cases is to start `zend` manually with a `-reindex` option from ``` zend -reindex ``` -For non-technical users here is some information on how to open a terminal on [Windows](https://www.lifewire.com/how-to-open-command-prompt-2618089) and [Mac OS](https://www.wikihow.com/Open-a-Terminal-Window-in-Mac). The full command on Mac OS is: +For non-technical users here is some information on how to open a terminal on [Windows](https://www.lifewire.com/how-to-open-command-prompt-2618089) and [macOS](https://www.wikihow.com/Open-a-Terminal-Window-in-Mac). The full command on macOS is: ``` /Applications/ZENCashWallet.app/Contents/Java/zend -reindex ``` diff --git a/docs/ZENCashWallet.png b/docs/ZENCashWallet.png index c6f52a61..c30a59cc 100644 Binary files a/docs/ZENCashWallet.png and b/docs/ZENCashWallet.png differ diff --git a/docs/ZENCashWalletMac.png b/docs/ZENCashWalletMac.png deleted file mode 100644 index ccf7746f..00000000 Binary files a/docs/ZENCashWalletMac.png and /dev/null differ diff --git a/docs/ZENCashWalletMac_0.73.4.png b/docs/ZENCashWalletMac_0.73.4.png deleted file mode 100644 index 242265ae..00000000 Binary files a/docs/ZENCashWalletMac_0.73.4.png and /dev/null differ diff --git a/docs/ZENCashWalletMac_0.74.7.png b/docs/ZENCashWalletMac_0.74.7.png deleted file mode 100644 index 9f6e1c61..00000000 Binary files a/docs/ZENCashWalletMac_0.74.7.png and /dev/null differ diff --git a/docs/ZENCashWalletWindows.png b/docs/ZENCashWalletWindows.png deleted file mode 100644 index 62b85440..00000000 Binary files a/docs/ZENCashWalletWindows.png and /dev/null differ diff --git a/docs/ZENCashWalletWindows_0.74.2.png b/docs/ZENCashWalletWindows_0.74.2.png deleted file mode 100644 index 8ce08f2f..00000000 Binary files a/docs/ZENCashWalletWindows_0.74.2.png and /dev/null differ diff --git a/docs/zend.pdf b/docs/zend.pdf new file mode 100644 index 00000000..18d25837 Binary files /dev/null and b/docs/zend.pdf differ diff --git a/installer/goals.txt b/installer/goals.txt new file mode 100644 index 00000000..829d60e8 --- /dev/null +++ b/installer/goals.txt @@ -0,0 +1 @@ +clean package \ No newline at end of file diff --git a/installer/pom.xml b/installer/pom.xml new file mode 100644 index 00000000..8fe35f3a --- /dev/null +++ b/installer/pom.xml @@ -0,0 +1,229 @@ + + 4.0.0 + + + com.zencash + HorizenSwingWalletUI + 1.0.12-SNAPSHOT + + + installer + Horizen Wallet Installer + + + UTF-8 + ${project.build.directory}/staging + zencash-wallet-installer + https://github.com + HorizenOfficial/zen/releases/download/v2.0.16/Zen_Win_binaries_v2.0.16.zip + 5.0.6 + + + + + com.zencash + zencash-wallet-swing + ${project.version} + + + + + + installer + + package + + + + maven-resources-plugin + + + copy-resources + + validate + + copy-resources + + + ${staging.dir} + + + + src/main/izpack + + **/* + + false + + + ../zencash-wallet-swing/src/deb/resources + + licences/* + + false + + + + + + + + org.codehaus.mojo + wagon-maven-plugin + 1.0 + + + download-zen + validate + + download-single + + + ${zen.project.url} + ${zen.binaries.file.name.windows} + ${project.build.directory}/staging/zen-win-binaries.zip + + + + + + maven-antrun-plugin + + + generate-resources + + + + + + + + + + + + + + + run + + + + + + maven-dependency-plugin + + + + copy-izpack-dependencies + prepare-package + + copy-dependencies + + + ${staging.dir}/custom + false + true + true + true + true + zencash-wallet-swing,bitcoinj-core,sqlite-jdbc,minimal-json + + + + + + + + org.codehaus.izpack + izpack-maven-plugin + ${izpack.version} + + + package + izpack + + + ${staging.dir} + ${staging.dir}/install.xml + ${project.build.directory}/${installer-output-filename}.jar + + + + + + + com.zencash + zencash-wallet-swing + ${project.version} + + + + + com.akathist.maven.plugins.launch4j + launch4j-maven-plugin + + + l4j-gui + package + + launch4j + + + ${staging.dir}/win-shortcut/zencash.ico + gui + ${project.build.directory}/${installer-output-filename}.jar + ${project.build.directory}/${installer-output-filename}.exe + + com.izforge.izpack.installer.bootstrap.Installer + + + false + false + 1.8.0 + preferJre + 64/32 + + + 1.0.0.0 + 1.0.0.0 + ${project.name} + C + 1.0.0.0 + 1.0.0.0 + ${project.name} + ${installer-output-filename} + ${installer-output-filename}.exe + + + + + + + maven-assembly-plugin + + + assembly + package + single + + ${project.build.directory} + + ${staging.dir}/assembly.xml + + + + + + + + + + diff --git a/installer/src/main/izpack/TargetDirWindows.txt b/installer/src/main/izpack/TargetDirWindows.txt new file mode 100644 index 00000000..2d195f2e --- /dev/null +++ b/installer/src/main/izpack/TargetDirWindows.txt @@ -0,0 +1 @@ +C:\Program Files diff --git a/installer/src/main/izpack/assembly.xml b/installer/src/main/izpack/assembly.xml new file mode 100644 index 00000000..bf4110c4 --- /dev/null +++ b/installer/src/main/izpack/assembly.xml @@ -0,0 +1,18 @@ + + cdc-upgrade + + zip + + false + + + ${project.build.directory} + + + *.exe + + + + diff --git a/installer/src/main/izpack/customicons.xml b/installer/src/main/izpack/customicons.xml new file mode 100644 index 00000000..c6126485 --- /dev/null +++ b/installer/src/main/izpack/customicons.xml @@ -0,0 +1,6 @@ + + + diff --git a/installer/src/main/izpack/default_shortcut_spec.xml b/installer/src/main/izpack/default_shortcut_spec.xml new file mode 100644 index 00000000..d91eef9c --- /dev/null +++ b/installer/src/main/izpack/default_shortcut_spec.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/installer/src/main/izpack/i18n/customLangPack.xml_eng b/installer/src/main/izpack/i18n/customLangPack.xml_eng new file mode 100644 index 00000000..b8c3a6d5 --- /dev/null +++ b/installer/src/main/izpack/i18n/customLangPack.xml_eng @@ -0,0 +1,4 @@ + + + + diff --git a/installer/src/main/izpack/i18n/zencashPacksLang.xml_eng b/installer/src/main/izpack/i18n/zencashPacksLang.xml_eng new file mode 100644 index 00000000..0f836628 --- /dev/null +++ b/installer/src/main/izpack/i18n/zencashPacksLang.xml_eng @@ -0,0 +1,4 @@ + + + + diff --git a/installer/src/main/izpack/images/JFrameIcon.png b/installer/src/main/izpack/images/JFrameIcon.png new file mode 100644 index 00000000..c2d93569 Binary files /dev/null and b/installer/src/main/izpack/images/JFrameIcon.png differ diff --git a/installer/src/main/izpack/images/UninstallerIcon.png b/installer/src/main/izpack/images/UninstallerIcon.png new file mode 100644 index 00000000..c2d93569 Binary files /dev/null and b/installer/src/main/izpack/images/UninstallerIcon.png differ diff --git a/installer/src/main/izpack/images/left.2.png b/installer/src/main/izpack/images/left.2.png new file mode 100644 index 00000000..9a0bcd01 Binary files /dev/null and b/installer/src/main/izpack/images/left.2.png differ diff --git a/installer/src/main/izpack/images/left.3.png b/installer/src/main/izpack/images/left.3.png new file mode 100644 index 00000000..32b9d8b1 Binary files /dev/null and b/installer/src/main/izpack/images/left.3.png differ diff --git a/installer/src/main/izpack/images/left.6.png b/installer/src/main/izpack/images/left.6.png new file mode 100644 index 00000000..2f4ecced Binary files /dev/null and b/installer/src/main/izpack/images/left.6.png differ diff --git a/installer/src/main/izpack/images/zencash-logo.png b/installer/src/main/izpack/images/zencash-logo.png new file mode 100644 index 00000000..d0b8d627 Binary files /dev/null and b/installer/src/main/izpack/images/zencash-logo.png differ diff --git a/installer/src/main/izpack/install.xml b/installer/src/main/izpack/install.xml new file mode 100644 index 00000000..639037fe --- /dev/null +++ b/installer/src/main/izpack/install.xml @@ -0,0 +1,123 @@ + + + + HorizenSwingWalletUI + 1.0.12 + https://horizen.io + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Core files + + + + + + + Zencash Binaries + + + + diff --git a/installer/src/main/izpack/welcome.html b/installer/src/main/izpack/welcome.html new file mode 100644 index 00000000..764ebe2b --- /dev/null +++ b/installer/src/main/izpack/welcome.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+

$WELCOME_TEXT

+
+

$WELCOME_VERSION

+
+ + diff --git a/installer/src/main/izpack/win-shortcut/zencash.ico b/installer/src/main/izpack/win-shortcut/zencash.ico new file mode 100644 index 00000000..6bd78e07 Binary files /dev/null and b/installer/src/main/izpack/win-shortcut/zencash.ico differ diff --git a/installer/src/main/izpack/win-shortcut/zencashwallet.bat b/installer/src/main/izpack/win-shortcut/zencashwallet.bat new file mode 100644 index 00000000..4b4d6fa9 --- /dev/null +++ b/installer/src/main/izpack/win-shortcut/zencashwallet.bat @@ -0,0 +1,3 @@ +@ECHO OFF +chdir app +start javaw -jar zencash-wallet-swing.jar diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..b9b63c2e --- /dev/null +++ b/pom.xml @@ -0,0 +1,138 @@ + + + 4.0.0 + + com.zencash + HorizenSwingWalletUI + 1.0.12-SNAPSHOT + pom + Horizen Swing Wallet UI + + + UTF-8 + 1.8 + ${project.basedir} + + + + + MIT License + http://www.opensource.org/licenses/mit-license.php + + + + + + zencash-wallet-swing + installer + + + + + + junit + junit + 4.13.1 + + + + + org.bitcoinj + bitcoinj-core + 0.14.5 + + + + org.xerial + sqlite-jdbc + 3.41.2.2 + + + + com.eclipsesource.minimal-json + minimal-json + 0.9.5 + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + + org.vafer + jdeb + 1.6 + + + org.apache.maven.plugins + maven-resources-plugin + 2.3 + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.0 + + + com.akathist.maven.plugins.launch4j + launch4j-maven-plugin + 1.7.21 + + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.0 + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${source.version} + ${source.version} + + + + + + + + + + java8 + + 8 + + + + + + maven-compiler-plugin + + + true + javac8 + + + + + + + diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 00000000..305c747f --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1 @@ +!signtool.exe diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 00000000..9f813b2c --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +set -eo pipefail + +cd "${TRAVIS_BUILD_DIR}" +# Build jars +ant -buildfile ./src/build/build.xml +#TODO sign JARS in ant + +# Download zend and zend-cli +if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + export PLATFORM_NAME=Mac +elif [[ "${TRAVIS_OS_NAME}" == "windows" ]]; then + export PLATFORM_NAME=Win +fi + +if [[ "${TRAVIS_OS_NAME}" == "osx" || "${TRAVIS_OS_NAME}" == "windows" ]]; then + export FOLDER_NAME="Zen_${PLATFORM_NAME}_binaries_v${ZEND_VERSION}_legacy_cpu" + export ZEND_FILE_NAME="${FOLDER_NAME}.zip" + export FILE_EXT="" + + curl -sL "https://github.com/HorizenOfficial/zen/releases/download/v${ZEND_VERSION}/${ZEND_FILE_NAME}" > "${ZEND_FILE_NAME}" + curl -sL "https://github.com/HorizenOfficial/zen/releases/download/v${ZEND_VERSION}/${ZEND_FILE_NAME}.sha256" > "${ZEND_FILE_NAME}.sha256" + + echo "DOWLNOADED" + + if [[ "${TRAVIS_OS_NAME}" == "windows" ]]; then + export FILE_EXT=".exe" + + # Check sha256 + powershell -file "scripts\windows-verify-checksum.ps1" "${ZEND_FILE_NAME}.sha256" sha256 + + # Extract ZEND binaries + 7z x "${ZEND_FILE_NAME}" + + # Verify extracted binaries + pushd "${FOLDER_NAME}" + powershell -file "..\scripts\windows-verify-checksum.ps1" checksums.sha256 sha256 + popd + else + # Check sha256 + shasum -a256 -c "${ZEND_FILE_NAME}.sha256" + + # Extract ZEND binaries + unzip "${ZEND_FILE_NAME}" + + # Verify extracted binaries + pushd "${FOLDER_NAME}" + shasum -a256 -c checksums.sha256 + popd + fi + + mv "./${FOLDER_NAME}/zend${FILE_EXT}" "${JARS_PATH}/zend${FILE_EXT}" + chmod a+x "./${JARS_PATH}/zend${FILE_EXT}" + mv "./${FOLDER_NAME}/zen-cli${FILE_EXT}" "${JARS_PATH}/zen-cli${FILE_EXT}" + chmod a+x "./${JARS_PATH}/zen-cli${FILE_EXT}" + mv "./${FOLDER_NAME}/zen-tx${FILE_EXT}" "${JARS_PATH}/zen-tx${FILE_EXT}" + chmod a+x "./${JARS_PATH}/zen-tx${FILE_EXT}" + rm -f "${JARS_PATH}/ZENCashSwingWalletUI-src.jar" +fi + +if [[ "${TRAVIS_OS_NAME}" != "linux" ]]; then + # TODO jpackage has no code signing support on windows yet, so the launcher is unsigned. https://bugs.openjdk.java.net/browse/JDK-8230668 + echo "Running jpackage command: ${JAVA_HOME}/bin/jpackage --type ${PACKAGE_TYPE} -d ${BUILD_PATH} -i ${JARS_PATH} --app-version ${VERSION} --main-class ${MAIN_CLASS} --main-jar ${MAIN_JAR} -n ${NAME} ${COMMON_PARAMS} ${MAC_PARAMS} ${WINDOWS_PARAMS}" + bash -c "${JAVA_HOME}/bin/jpackage --type ${PACKAGE_TYPE} -d ${BUILD_PATH} -i ${JARS_PATH} --app-version ${VERSION} --main-class ${MAIN_CLASS} --main-jar ${MAIN_JAR} -n ${NAME} ${COMMON_PARAMS} ${MAC_PARAMS} ${WINDOWS_PARAMS}" +fi + +if [[ "${TRAVIS_OS_NAME}" == "windows" ]]; then + # Sign installer + if [[ "${SIGN}" == "true" ]]; then + powershell -file "scripts/windows-sign.ps1" + fi + + # Create checksum + pushd "${BUILD_PATH}" + powershell -File "..\..\scripts\windows-get-checksum.ps1" "${APPLICATION_NAME}" sha256 > "${APPLICATION_NAME}.sha256" + echo "" >> "${APPLICATION_NAME}.sha256" + popd +elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + # Sign DMG + if [[ "${SIGN}" == "true" ]]; then + /usr/bin/codesign --deep --force --verbose --sign "Developer ID Application" "${APPLICATION_PATH}" + fi + + # Create checksum + pushd "${BUILD_PATH}" + shasum -a256 "${APPLICATION_NAME}" > "${APPLICATION_NAME}.sha256" + popd +fi + +# Move files to "releases" folder in HOME +if [[ "${TRAVIS_OS_NAME}" == "osx" || "${TRAVIS_OS_NAME}" == "windows" ]]; then + rm -rf "${RELEASES_PATH:?}/*" + mv "./${APPLICATION_PATH}" "${RELEASES_PATH}/${APPLICATION_NAME}" + mv "./${APPLICATION_PATH}.sha256" "${RELEASES_PATH}/${APPLICATION_NAME}.sha256" +fi +if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + rm -rf "${RELEASES_PATH:?}/*" + mv ./build/ubuntu-package/*.deb "${RELEASES_PATH}/" + pushd "${RELEASES_PATH}/" + for file in *.deb; do sha256sum "${file}" > "${file}.sha256"; done + popd +fi diff --git a/scripts/bump_version_devtool.sh b/scripts/bump_version_devtool.sh new file mode 100755 index 00000000..dfb4d1c2 --- /dev/null +++ b/scripts/bump_version_devtool.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -euo pipefail + +zend_version_old="4.0.0" +zend_version_new="4.1.0" + +swing_version_old="1.0.11" +swing_version_new="1.0.12" + +# bump zend version +sed -i "s/${zend_version_old//./\\.}/${zend_version_new//./\\.}/g" .travis.yml + +# bump swing version +grep -lr --exclude-dir=.git --exclude-dir=docs --exclude-dir=scripts "${swing_version_old//./\\.}" | xargs sed -i "s/${swing_version_old//./\\.}/${swing_version_new//./\\.}/g" + +# create release notes +new_notes="docs/Release_${swing_version_new}.md" +cp "docs/Release_${swing_version_old}.md" "${new_notes}" +sed -i "s/${zend_version_old//./\\.}/${zend_version_new//./\\.}/g" "${new_notes}" +sed -i "s/${swing_version_old//./\\.}/${swing_version_new//./\\.}/g" "${new_notes}" +sed -i 's/is\ not\ `.*`/is\ not\ `TODO`/g' "${new_notes}" +sed -i 's/^.*\ \ HorizenDesktopGUIWallet/TODO\ \ HorizenDesktopGUIWallet/g' "${new_notes}" diff --git a/scripts/install-jdk.sh b/scripts/install-jdk.sh new file mode 100755 index 00000000..23cb74f4 --- /dev/null +++ b/scripts/install-jdk.sh @@ -0,0 +1,315 @@ +#!/usr/bin/env bash + +# +# Install JDK for Linux and Mac OS +# +# This script determines the most recent early-access build number, +# downloads the JDK archive to the user home directory and extracts +# it there. +# +# Exported environment variables (when sourcing this script) +# +# JAVA_HOME is set to the extracted JDK directory +# PATH is prepended with ${JAVA_HOME}/bin +# +# (C) 2019 Christian Stein +# +# https://github.com/sormuras/bach/blob/master/install-jdk.sh +# + +set -o errexit +#set -o nounset # https://github.com/travis-ci/travis-ci/issues/5434 +#set -o xtrace + +function initialize() { + readonly script_name="$(basename "${BASH_SOURCE[0]}")" + readonly script_version='2020-01-14' + + dry=false + silent=false + verbose=false + emit_java_home=false + + feature='ea' + license='GPL' # Force GPLv2+CE + os='?' + url='?' + workspace="${HOME}" + target='?' + cacerts=false +} + +function usage() { +cat << EOF +Usage: ${script_name} [OPTION]... +Download and extract latest-and-greatest JDK from https://jdk.java.net + +Version: ${script_version} +Options: + -h|--help Displays this help + -d|--dry-run Activates dry-run mode + -s|--silent Displays no output + -e|--emit-java-home Print value of "JAVA_HOME" to stdout (ignores silent mode) + -v|--verbose Displays verbose output + + -f|--feature 11|12|...|ea JDK feature release number, defaults to "ea" + -o|--os linux-x64|osx-x64 Operating system identifier + -u|--url "https://..." Use custom JDK archive (provided as .tar.gz file) + -w|--workspace PATH Working directory defaults to \${HOME} [${HOME}] + -t|--target PATH Target directory, defaults to first component of the tarball + -c|--cacerts Link system CA certificates (currently only Debian/Ubuntu is supported) +EOF +} + +function script_exit() { + if [[ $# -eq 1 ]]; then + printf '%s\n' "$1" + exit 0 + fi + + if [[ $# -eq 2 && $2 =~ ^[0-9]+$ ]]; then + printf '%b\n' "$1" + exit "$2" + fi + + script_exit 'Invalid arguments passed to script_exit()!' 2 +} + +function say() { + if [[ ${silent} != true ]]; then + echo "$@" + fi +} + +function verbose() { + if [[ ${verbose} == true ]]; then + echo "$@" + fi +} + +function parse_options() { + local option + while [[ $# -gt 0 ]]; do + option="$1" + shift + case ${option} in + -h|-H|--help) + usage + exit 0 + ;; + -v|-V|--verbose) + verbose=true + ;; + -s|-S|--silent) + silent=true + verbose "Silent mode activated" + ;; + -d|-D|--dry-run) + dry=true + verbose "Dry-run mode activated" + ;; + -e|-E|--emit-java-home) + emit_java_home=true + verbose "Emitting JAVA_HOME" + ;; + -f|-F|--feature) + feature="$1" + verbose "feature=${feature}" + shift + ;; + -l|-L|--license) + # license="$1" + say "Ignoring license option: $1 -- using GPLv2+CE by default" + verbose "license=${license}" + shift + ;; + -o|-O|--os) + os="$1" + verbose "os=${os}" + shift + ;; + -u|-U|--url) + url="$1" + verbose "url=${url}" + shift + ;; + -w|-W|--workspace) + workspace="$1" + verbose "workspace=${workspace}" + shift + ;; + -t|-T|--target) + target="$1" + verbose "target=${target}" + shift + ;; + -c|-C|--cacerts) + cacerts=true + verbose "Linking system CA certificates" + ;; + *) + script_exit "Invalid argument was provided: ${option}" 2 + ;; + esac + done +} + +function determine_latest_jdk() { + latest_jdk=22 + verbose "Latest JDK feature release number is: ${latest_jdk}" +} + +function perform_sanity_checks() { + if [[ ${feature} == '?' ]] || [[ ${feature} == 'ea' ]]; then + feature=${latest_jdk} + fi + if [[ ${feature} -lt 9 ]] || [[ ${feature} -gt ${latest_jdk} ]]; then + script_exit "Expected feature release number in range of 9 to ${latest_jdk}, but got: ${feature}" 3 + fi + if [[ -d "$target" ]]; then + script_exit "Target directory must not exist, but it does: $(du -hs '${target}')" 3 + fi +} + +function determine_url() { + local JAVA_NET="https://jdk.java.net/${feature}" + local DOWNLOAD='https://download.java.net/java' + + # An official GA build or an archived feature? Use predefined URL + case "${feature}" in + 9) url="${DOWNLOAD}/GA/jdk9/9.0.4/binaries/openjdk-9.0.4_${os}_bin.tar.gz"; return;; + 10) url="${DOWNLOAD}/GA/jdk10/10.0.2/19aef61b38124481863b1413dce1855f/13/openjdk-10.0.2_${os}_bin.tar.gz"; return;; + 11) url="${DOWNLOAD}/GA/jdk11/9/GPL/openjdk-11.0.2_${os}_bin.tar.gz"; return;; + 12) url="${DOWNLOAD}/GA/jdk12.0.2/e482c34c86bd4bf8b56c0b35558996b9/10/GPL/openjdk-12.0.2_${os}_bin.tar.gz"; return;; + 13) url="${DOWNLOAD}/GA/jdk13.0.2/d4173c853231432d94f001e99d882ca7/8/GPL/openjdk-13.0.2_${os}_bin.tar.gz"; return;; + 16) url="${DOWNLOAD}/GA/jdk16.0.1/7147401fd7354114ac51ef3e1328291f/9/GPL/openjdk-16.0.1_${os}_bin.${ext}"; return;; + esac + + # EA or RC build? Grab URL from HTML source of jdk.java.net/${feature} + local candidates=$(wget --quiet --output-document - ${JAVA_NET} | grep -Eo 'href[[:space:]]*=[[:space:]]*"[^\"]+"' | grep -Eo '(http|https)://[^"]+') + url=$(echo "${candidates}" | grep -Eo "${DOWNLOAD}/.+/jdk${feature}.+/.*${license}/.*jdk-${feature}.+${os}_bin(.tar.gz|.zip)$" || true) + + if [[ -z ${url} ]]; then + script_exit "Couldn't determine a download url for ${feature}-${license} on ${os}" 1 + fi +} + +function prepare_variables() { + if [[ ${os} == '?' ]]; then + if [[ "$OSTYPE" == "darwin"* ]]; then + os='osx-x64' + ext='tar.gz' + elif [[ "$OSTYPE" == "msys" ]]; then + os='windows-x64' + ext='zip' + else + os='linux-x64' + ext='tar.gz' + fi + fi + if [[ ${url} == '?' ]]; then + determine_latest_jdk + perform_sanity_checks + determine_url + else + feature='' + license='' + os='' + fi + status=$(curl -o /dev/null --silent --head --write-out %{http_code} ${url}) +} + +function print_variables() { +cat << EOF +Variables: + feature = ${feature} + os = ${os} + url = ${url} + status = ${status} +EOF +} + +function download_and_extract_and_set_target() { + local filename="jdk.tar.gz" + + if [[ "$OSTYPE" == "msys" ]]; then + filename="jdk.zip" + cd "${workspace}" + fi + + local quiet='--quiet'; if [[ ${verbose} == true ]]; then quiet=''; fi + local local="--directory-prefix ${workspace} --output-document=${filename}" + local remote='--timestamping --continue' + local wget_options="${quiet} ${local} ${remote}" + local tar_options="--file ${filename}" + + say "Downloading JDK from ${url}..." + verbose "Using wget options: ${wget_options}" + wget ${wget_options} ${url} + + verbose "Using tar options: ${tar_options}" + if [[ ${target} == '?' ]]; then + tar --extract ${tar_options} -C "${workspace}" + if [[ "$OSTYPE" != "darwin"* ]]; then + target="${workspace}"/$(tar --list ${tar_options} | grep 'bin/javac' | tr '/' '\n' | tail -3 | head -1) + else + target="${workspace}"/$(tar --list ${tar_options} | head -2 | tail -1 | cut -f 2 -d '/' -)/Contents/Home + fi + verbose "Set target to: ${target}" + else + echo "Using custom target: ${target}" + if [[ "$OSTYPE" == "msys" ]]; then + powershell -command "Expand-Archive -Force ./${filename} ./" + local extractdir="$(find "${workspace}" -maxdepth 1 -type d | grep "$(basename "${target}")")" + mv "${extractdir}" "${target}" + elif [[ "$OSTYPE" != "darwin"* ]]; then + mkdir --parents "${target}" + tar --extract ${tar_options} -C "${target}" --strip-components=1 + else + mkdir -p "${target}" + tar --extract ${tar_options} -C "${target}" --strip-components=4 + fi + fi + + if [[ ${verbose} == true ]]; then + echo "Content of target directory:" + ls "${target}" + echo "Content of release file:" + [[ ! -f "${target}/release" ]] || cat "${target}/release" + fi + + # Link to system certificates + # https://openjdk.java.net/jeps/319 + # https://bugs.openjdk.java.net/browse/JDK-8196141 + if [[ ${cacerts} == true ]]; then + local directory="${target}/lib/security/cacerts" + if [[ -f "${directory}" ]]; then + mv "${directory}" "${directory}.jdk" + ln -s /etc/ssl/certs/java/cacerts "${directory}" + else + verbose "Directory ${directory} doesn't exist, didn't link system CA certificates." + fi + fi +} + +function main() { + initialize + parse_options "$@" + + say "$script_name $script_version" + prepare_variables + + if [[ ${silent} == false ]]; then print_variables; fi + if [[ ${dry} == true ]]; then exit 0; fi + + download_and_extract_and_set_target + + export JAVA_HOME=$(cd "${target}"; pwd) + export PATH=${JAVA_HOME}/bin:$PATH + + if [[ ${silent} == false ]]; then java -Xmx100m -version; fi + if [[ ${emit_java_home} == true ]]; then echo "${JAVA_HOME}"; fi +} + +main "$@" +set +o errexit diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 00000000..bf2577bd --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +cd "${HOME}" + +# jpackage +export JAVA_HOME="${HOME}/jdk-${JDK}" +source "${TRAVIS_BUILD_DIR}/scripts/install-jdk.sh" --feature "${JDK}" -v --target "${JAVA_HOME}" + +set -eo pipefail +# ant +antver="1.10.14" +antdir="apache-ant-${antver}" +antfile="${antdir}-bin.zip" +anturl="https://downloads.apache.org/ant/binaries/${antfile}" +curl -sL "${anturl}" > "${HOME}/${antfile}" +curl -sL "${anturl}.sha512" | xargs -I {} echo "{} ${antfile}" > "${HOME}/${antfile}.sha512" +if [[ "${TRAVIS_OS_NAME}" == "windows" ]]; then + powershell -file "${TRAVIS_BUILD_DIR}\scripts\windows-verify-checksum.ps1" "${HOME}/${antfile}.sha512" sha512 + 7z x "${HOME}/${antfile}" +else + shasum -a512 -c "${HOME}/${antfile}.sha512" + unzip "${HOME}/$antfile" +fi + +# hack to always use "codesign --force" on mac, needed to not error when already signed files are in the .app bundle +if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + cat << EOF > "${HOME}/${antdir}/bin/codesign" +#!/bin/bash + +exec /usr/bin/codesign -f "\$@" +EOF + chmod +x "${HOME}/${antdir}/bin/codesign" +fi + +set +e +set +o pipefail +set +o errexit + +export PATH="${HOME}/${antdir}/bin:${PATH}" + +cd "${TRAVIS_BUILD_DIR}" diff --git a/scripts/setup-env.sh b/scripts/setup-env.sh new file mode 100755 index 00000000..032bb505 --- /dev/null +++ b/scripts/setup-env.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +set -eo pipefail + +SEMVER_REGEX="^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?(\\+[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" + +if [ ! -z "${TRAVIS_TAG+x}" ] && [[ "${TRAVIS_TAG}" =~ ${SEMVER_REGEX} ]] && [[ "${TRAVIS_OS_NAME}" != "linux" ]]; then + echo "Release tag found, packages will be code signed." + export SIGN=true + curl -sLH "Authorization: token ${GITHUB_AUTH}" -H "Accept: application/vnd.github.v3.raw" https://api.github.com/repos/HorizenOfficial/codesign_ci/contents/current | openssl enc -d -aes-256-cbc -md sha256 -pass "pass:${CERT_ARCHIVE_PASSWORD}" | tar -xzf- + if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + source ./scripts/setup-macos-keychain.sh + fi +else + export SIGN=false + unset CERT_ARCHIVE_PASSWORD + unset MAC_CERT_PASSWORD + unset WIN_CERT_PASSWORD +fi + +export BUILD_PATH="build/native" +export RELEASES_PATH="releases" +export JARS_PATH="build/jars" +export MAC_BUNDLE_NAME="HorizenWallet" +export NAME="HorizenDesktopGUIWallet" +export MAIN_CLASS="com.vaklinov.zcashui.HorizenUI" +export MAIN_JAR="ZENCashSwingWalletUI.jar" +export PNG_ICON="./zencash-wallet-swing/src/icons/ZENCashWallet.iconset/icon_128x128.png" +export ICNS_ICON="./zencash-wallet-swing/src/icons/ZENCashWallet.icns" +export ICO_ICON="./zencash-wallet-swing/src/icons/ZEN.ico" +export VERSION="$(if [ ! -z "${TRAVIS_TAG+x}" ] && [[ "$TRAVIS_TAG" =~ ${SEMVER_REGEX} ]]; then echo "${TRAVIS_TAG}"; else echo "1.0.0"; fi)" +export PACKAGE_TYPE="$(if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then echo dmg; elif [[ "${TRAVIS_OS_NAME}" == "windows" ]]; then echo exe; fi)" +export MAC_PARAMS="$(if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then echo -n "--icon ${ICNS_ICON}"; if [[ "${SIGN}" = true ]]; then echo " --mac-sign"; fi; fi)" +export WINDOWS_PARAMS="$(if [[ "${TRAVIS_OS_NAME}" == "windows" ]]; then echo "--icon ${ICO_ICON} --win-dir-chooser --win-shortcut --win-menu --win-upgrade-uuid e51de4ee-2dc7-45d8-b32d-aebd3fe81547"; fi)" +export COMMON_PARAMS="--java-options -Xmx1536m --verbose --license-file ./LICENSE --copyright \"Copyright (c) 2023 The Horizen Foundation, Copyright (c) 2021 Zen Blockchain Foundation\" --description \"Horizen Desktop GUI Wallet ${VERSION}\"" +export APPLICATION_NAME="${NAME}-${VERSION}.${PACKAGE_TYPE}" +export APPLICATION_PATH="${BUILD_PATH}/${APPLICATION_NAME}" +export READABLE_NAME="Horizen Desktop GUI Wallet $(if [[ "${TRAVIS_TAG}" != "${TRAVIS_BRANCH}" && "${TRAVIS_TAG}" ]]; then echo "${VERSION}"; else echo "${TRAVIS_BRANCH}"; fi)" + +mkdir -p "${RELEASES_PATH}" diff --git a/scripts/setup-macos-keychain.sh b/scripts/setup-macos-keychain.sh new file mode 100755 index 00000000..c909f284 --- /dev/null +++ b/scripts/setup-macos-keychain.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -eo pipefail + +export KEY_CHAIN=mac-build.keychain +security create-keychain -p travis "${KEY_CHAIN}" +security import ./mac.p12 -k "${KEY_CHAIN}" -P "${MAC_CERT_PASSWORD}" -T /usr/bin/codesign + +security list-keychain -s "${KEY_CHAIN}" +security unlock-keychain -p travis "${KEY_CHAIN}" +security set-keychain-settings -t 3600 -u "${KEY_CHAIN}" + +security default-keychain -s "${KEY_CHAIN}" + +# to see if this process succeeded +security find-identity -v -p codesigning + +# set key partition list to avoid UI permission popup that causes hanging at CI +security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k travis "${KEY_CHAIN}" diff --git a/scripts/signtool.exe b/scripts/signtool.exe new file mode 100755 index 00000000..71c3d23f Binary files /dev/null and b/scripts/signtool.exe differ diff --git a/scripts/windows-get-checksum.ps1 b/scripts/windows-get-checksum.ps1 new file mode 100755 index 00000000..ef25c583 --- /dev/null +++ b/scripts/windows-get-checksum.ps1 @@ -0,0 +1,11 @@ +param +( + [Parameter(Mandatory=$true, HelpMessage='The input file')] + [string]$File, + [Parameter(Mandatory=$true, HelpMessage='The Algorithm to use')] + [string]$Algorithm +) +$hash = Get-FileHash $File -Algorithm $Algorithm +$fileHash = $hash.Hash.ToLower() + +Write-Host -NoNewline $fileHash" "$File diff --git a/scripts/windows-sign.ps1 b/scripts/windows-sign.ps1 new file mode 100755 index 00000000..2abae154 --- /dev/null +++ b/scripts/windows-sign.ps1 @@ -0,0 +1,7 @@ +$Password = ConvertTo-SecureString -String $Env:WIN_CERT_PASSWORD -AsPlainText -Force + +Import-PfxCertificate -FilePath windows.p12 -CertStoreLocation Cert:\LocalMachine\My -Password $Password + +Set-ItemProperty -Path $Env:APPLICATION_PATH -Name IsReadOnly -Value $false +scripts/signtool.exe sign /debug /v /f windows.p12 /t http://timestamp.digicert.com /du https://github.com/HorizenOfficial/zen /p $Env:WIN_CERT_PASSWORD /n "Zen Blockchain Foundation" $Env:APPLICATION_PATH +scripts/signtool.exe sign /debug /v /f windows.p12 /as /fd sha256 /tr http://timestamp.digicert.com /td sha256 /du https://github.com/HorizenOfficial/zen /p $Env:WIN_CERT_PASSWORD /n "Zen Blockchain Foundation" $Env:APPLICATION_PATH diff --git a/scripts/windows-verify-checksum.ps1 b/scripts/windows-verify-checksum.ps1 new file mode 100755 index 00000000..a34cdd98 --- /dev/null +++ b/scripts/windows-verify-checksum.ps1 @@ -0,0 +1,26 @@ +param +( + [Parameter(Mandatory=$true, HelpMessage='The file containing the hash.')] + [string]$File, + [Parameter(Mandatory=$true, HelpMessage='The Algorithm to use')] + [string]$Algorithm +) +foreach ($line in (Get-Content $File)) { + $fields = $line -split '\s+' + $hash = $fields[0].Trim().ToUpper() + $filename = $fields[1].Trim() + if($filename.StartsWith("*")){ + $filename = $filename.Substring(1).Trim() + } + + $computedHash = (Get-FileHash -Algorithm $Algorithm $filename).Hash.ToUpper() + + if($hash.Equals($computedHash)){ + Write-Host $filename, ": Passed" + }else{ + Write-Host $filename, ": Not Passed" + Write-Host "Read from file: ", $hash + Write-Host "Computed: ", $computedHash + exit 1 + } +} diff --git a/src/build/build.xml b/src/build/build.xml index 8e70ced1..987ed872 100644 --- a/src/build/build.xml +++ b/src/build/build.xml @@ -1,12 +1,13 @@ + + + - + @@ -60,7 +64,7 @@ - + @@ -71,13 +75,14 @@ + - + - + @@ -99,8 +104,8 @@ - @@ -130,13 +135,13 @@ --> - + - + - + @@ -144,7 +149,7 @@ diff --git a/src/java/com/vaklinov/zcashui/AboutDialog.java b/src/java/com/vaklinov/zcashui/AboutDialog.java index a90f9b14..55dbf078 100644 --- a/src/java/com/vaklinov/zcashui/AboutDialog.java +++ b/src/java/com/vaklinov/zcashui/AboutDialog.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -51,8 +52,6 @@ /** * Typical about box stuff... - * - * @author Ivan Vaklinov */ public class AboutDialog extends JDialog @@ -60,7 +59,8 @@ public class AboutDialog public AboutDialog(JFrame parent) throws UnsupportedEncodingException { - this.setTitle("About..."); + LanguageUtil langUtil = LanguageUtil.instance(); + this.setTitle(langUtil.getString("dialog.about.title")); this.setSize(620, 440); this.setLocation(100, 100); this.setLocationRelativeTo(parent); @@ -74,192 +74,28 @@ public AboutDialog(JFrame parent) copyrigthPanel.setLayout(new BorderLayout(3, 3)); JLabel copyrightLabel = new JLabel(); - copyrightLabel.setText(new String(new byte[] { - (byte)0x3c,(byte)0x68,(byte)0x74,(byte)0x6d,(byte)0x6c,(byte)0x3e,(byte)0x3c,(byte)0x62,(byte)0x6f,(byte)0x64, - (byte)0x79,(byte)0x3e,(byte)0x3c,(byte)0x73,(byte)0x70,(byte)0x61,(byte)0x6e,(byte)0x20,(byte)0x73,(byte)0x74, - (byte)0x79,(byte)0x6c,(byte)0x65,(byte)0x3d,(byte)0x22,(byte)0x66,(byte)0x6f,(byte)0x6e,(byte)0x74,(byte)0x2d, - (byte)0x77,(byte)0x65,(byte)0x69,(byte)0x67,(byte)0x68,(byte)0x74,(byte)0x3a,(byte)0x62,(byte)0x6f,(byte)0x6c, - (byte)0x64,(byte)0x22,(byte)0x3e,(byte)0x5a,(byte)0x45,(byte)0x4e,(byte)0x43,(byte)0x61,(byte)0x73,(byte)0x68, - (byte)0x20,(byte)0x53,(byte)0x77,(byte)0x69,(byte)0x6e,(byte)0x67,(byte)0x20,(byte)0x57,(byte)0x61,(byte)0x6c, - (byte)0x6c,(byte)0x65,(byte)0x74,(byte)0x20,(byte)0x55,(byte)0x49,(byte)0x3c,(byte)0x2f,(byte)0x73,(byte)0x70, - (byte)0x61,(byte)0x6e,(byte)0x3e,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x3c,(byte)0x62, - (byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x43,(byte)0x6f,(byte)0x70,(byte)0x79,(byte)0x72,(byte)0x69,(byte)0x67, - (byte)0x68,(byte)0x74,(byte)0x3a,(byte)0x20,(byte)0x49,(byte)0x76,(byte)0x61,(byte)0x6e,(byte)0x20,(byte)0x56, - (byte)0x61,(byte)0x6b,(byte)0x6c,(byte)0x69,(byte)0x6e,(byte)0x6f,(byte)0x76,(byte)0x20,(byte)0x26,(byte)0x6c, - (byte)0x74,(byte)0x3b,(byte)0x69,(byte)0x76,(byte)0x61,(byte)0x6e,(byte)0x40,(byte)0x76,(byte)0x61,(byte)0x6b, - (byte)0x6c,(byte)0x69,(byte)0x6e,(byte)0x6f,(byte)0x76,(byte)0x2e,(byte)0x63,(byte)0x6f,(byte)0x6d,(byte)0x26, - (byte)0x67,(byte)0x74,(byte)0x3b,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x3c,(byte)0x62, - (byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x54,(byte)0x68,(byte)0x69,(byte)0x73,(byte)0x20,(byte)0x70,(byte)0x72, - (byte)0x6f,(byte)0x67,(byte)0x72,(byte)0x61,(byte)0x6d,(byte)0x20,(byte)0x69,(byte)0x73,(byte)0x20,(byte)0x69, - (byte)0x6e,(byte)0x74,(byte)0x65,(byte)0x6e,(byte)0x64,(byte)0x65,(byte)0x64,(byte)0x20,(byte)0x74,(byte)0x6f, - (byte)0x20,(byte)0x6d,(byte)0x61,(byte)0x6b,(byte)0x65,(byte)0x20,(byte)0x69,(byte)0x74,(byte)0x20,(byte)0x65, - (byte)0x61,(byte)0x73,(byte)0x79,(byte)0x20,(byte)0x74,(byte)0x6f,(byte)0x20,(byte)0x77,(byte)0x6f,(byte)0x72, - (byte)0x6b,(byte)0x20,(byte)0x77,(byte)0x69,(byte)0x74,(byte)0x68,(byte)0x20,(byte)0x74,(byte)0x68,(byte)0x65, - (byte)0x20,(byte)0x5a,(byte)0x45,(byte)0x4e,(byte)0x43,(byte)0x61,(byte)0x73,(byte)0x68,(byte)0x20,(byte)0x63, - (byte)0x6c,(byte)0x69,(byte)0x65,(byte)0x6e,(byte)0x74,(byte)0x20,(byte)0x74,(byte)0x6f,(byte)0x6f,(byte)0x6c, - (byte)0x73,(byte)0x20,(byte)0x62,(byte)0x79,(byte)0x20,(byte)0x70,(byte)0x72,(byte)0x6f,(byte)0x76,(byte)0x69, - (byte)0x64,(byte)0x69,(byte)0x6e,(byte)0x67,(byte)0x20,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e, - (byte)0x61,(byte)0x20,(byte)0x47,(byte)0x72,(byte)0x61,(byte)0x70,(byte)0x68,(byte)0x69,(byte)0x63,(byte)0x61, - (byte)0x6c,(byte)0x20,(byte)0x55,(byte)0x73,(byte)0x65,(byte)0x72,(byte)0x20,(byte)0x49,(byte)0x6e,(byte)0x74, - (byte)0x65,(byte)0x72,(byte)0x66,(byte)0x61,(byte)0x63,(byte)0x65,(byte)0x20,(byte)0x28,(byte)0x47,(byte)0x55, - (byte)0x49,(byte)0x29,(byte)0x20,(byte)0x74,(byte)0x68,(byte)0x61,(byte)0x74,(byte)0x20,(byte)0x61,(byte)0x63, - (byte)0x74,(byte)0x73,(byte)0x20,(byte)0x61,(byte)0x73,(byte)0x20,(byte)0x61,(byte)0x20,(byte)0x77,(byte)0x72, - (byte)0x61,(byte)0x70,(byte)0x70,(byte)0x65,(byte)0x72,(byte)0x20,(byte)0x61,(byte)0x6e,(byte)0x64,(byte)0x20, - (byte)0x70,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x65,(byte)0x6e,(byte)0x74,(byte)0x73,(byte)0x20,(byte)0x74, - (byte)0x68,(byte)0x65,(byte)0x20,(byte)0x69,(byte)0x6e,(byte)0x66,(byte)0x6f,(byte)0x72,(byte)0x6d,(byte)0x61, - (byte)0x74,(byte)0x69,(byte)0x6f,(byte)0x6e,(byte)0x20,(byte)0x69,(byte)0x6e,(byte)0x20,(byte)0x61,(byte)0x20, - (byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x75,(byte)0x73,(byte)0x65,(byte)0x72,(byte)0x2d, - (byte)0x66,(byte)0x72,(byte)0x69,(byte)0x65,(byte)0x6e,(byte)0x64,(byte)0x6c,(byte)0x79,(byte)0x20,(byte)0x6d, - (byte)0x61,(byte)0x6e,(byte)0x6e,(byte)0x65,(byte)0x72,(byte)0x2e,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f, - (byte)0x3e,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x41,(byte)0x63,(byte)0x6b,(byte)0x6e, - (byte)0x6f,(byte)0x77,(byte)0x6c,(byte)0x65,(byte)0x64,(byte)0x67,(byte)0x65,(byte)0x6d,(byte)0x65,(byte)0x6e, - (byte)0x74,(byte)0x73,(byte)0x3a,(byte)0x20,(byte)0x54,(byte)0x68,(byte)0x69,(byte)0x73,(byte)0x20,(byte)0x70, - (byte)0x72,(byte)0x6f,(byte)0x67,(byte)0x72,(byte)0x61,(byte)0x6d,(byte)0x20,(byte)0x69,(byte)0x6e,(byte)0x63, - (byte)0x6c,(byte)0x75,(byte)0x64,(byte)0x65,(byte)0x73,(byte)0x20,(byte)0x73,(byte)0x6f,(byte)0x66,(byte)0x74, - (byte)0x77,(byte)0x61,(byte)0x72,(byte)0x65,(byte)0x20,(byte)0x66,(byte)0x6f,(byte)0x72,(byte)0x20,(byte)0x4a, - (byte)0x53,(byte)0x4f,(byte)0x4e,(byte)0x20,(byte)0x70,(byte)0x72,(byte)0x6f,(byte)0x63,(byte)0x65,(byte)0x73, - (byte)0x73,(byte)0x69,(byte)0x6e,(byte)0x67,(byte)0x20,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e, - (byte)0x28,(byte)0x68,(byte)0x74,(byte)0x74,(byte)0x70,(byte)0x73,(byte)0x3a,(byte)0x2f,(byte)0x2f,(byte)0x67, - (byte)0x69,(byte)0x74,(byte)0x68,(byte)0x75,(byte)0x62,(byte)0x2e,(byte)0x63,(byte)0x6f,(byte)0x6d,(byte)0x2f, - (byte)0x72,(byte)0x61,(byte)0x6c,(byte)0x66,(byte)0x73,(byte)0x74,(byte)0x78,(byte)0x2f,(byte)0x6d,(byte)0x69, - (byte)0x6e,(byte)0x69,(byte)0x6d,(byte)0x61,(byte)0x6c,(byte)0x2d,(byte)0x6a,(byte)0x73,(byte)0x6f,(byte)0x6e, - (byte)0x29,(byte)0x20,(byte)0x74,(byte)0x68,(byte)0x61,(byte)0x74,(byte)0x20,(byte)0x69,(byte)0x73,(byte)0x20, - (byte)0x43,(byte)0x6f,(byte)0x70,(byte)0x79,(byte)0x72,(byte)0x69,(byte)0x67,(byte)0x68,(byte)0x74,(byte)0x20, - (byte)0x28,(byte)0x63,(byte)0x29,(byte)0x20,(byte)0x32,(byte)0x30,(byte)0x31,(byte)0x35,(byte)0x2c,(byte)0x20, - (byte)0x32,(byte)0x30,(byte)0x31,(byte)0x36,(byte)0x20,(byte)0x45,(byte)0x63,(byte)0x6c,(byte)0x69,(byte)0x70, - (byte)0x73,(byte)0x65,(byte)0x53,(byte)0x6f,(byte)0x75,(byte)0x72,(byte)0x63,(byte)0x65,(byte)0x2e,(byte)0x3c, - (byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x3c, - (byte)0x2f,(byte)0x62,(byte)0x6f,(byte)0x64,(byte)0x79,(byte)0x3e,(byte)0x3c,(byte)0x2f,(byte)0x68,(byte)0x74, - (byte)0x6d,(byte)0x6c,(byte)0x3e - }, "UTF-8") - ); + copyrightLabel.setText(langUtil.getString("dialog.about.front.text")); copyrightLabel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); copyrigthPanel.add(copyrightLabel, BorderLayout.NORTH); - - - JPanel PD = new JPanel(); - PD.setLayout(new BorderLayout(3, 3)); - PD.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); - JLabel l1 = new JLabel(new String(new byte[] { - (byte)0x3c,(byte)0x68,(byte)0x74,(byte)0x6d,(byte)0x6c,(byte)0x3e,(byte)0x3c,(byte)0x62,(byte)0x6f,(byte)0x64, - (byte)0x79,(byte)0x3e,(byte)0x3c,(byte)0x73,(byte)0x70,(byte)0x61,(byte)0x6e,(byte)0x20,(byte)0x73,(byte)0x74, - (byte)0x79,(byte)0x6c,(byte)0x65,(byte)0x3d,(byte)0x22,(byte)0x66,(byte)0x6f,(byte)0x6e,(byte)0x74,(byte)0x2d, - (byte)0x77,(byte)0x65,(byte)0x69,(byte)0x67,(byte)0x68,(byte)0x74,(byte)0x3a,(byte)0x62,(byte)0x6f,(byte)0x6c, - (byte)0x64,(byte)0x22,(byte)0x3e,(byte)0x44,(byte)0x6f,(byte)0x6e,(byte)0x61,(byte)0x74,(byte)0x69,(byte)0x6f, - (byte)0x6e,(byte)0x73,(byte)0x20,(byte)0x61,(byte)0x63,(byte)0x63,(byte)0x65,(byte)0x70,(byte)0x74,(byte)0x65, - (byte)0x64,(byte)0x3a,(byte)0x3c,(byte)0x2f,(byte)0x73,(byte)0x70,(byte)0x61,(byte)0x6e,(byte)0x3e,(byte)0x20, - (byte)0x54,(byte)0x68,(byte)0x69,(byte)0x73,(byte)0x20,(byte)0x5a,(byte)0x43,(byte)0x61,(byte)0x73,(byte)0x68, - (byte)0x20,(byte)0x47,(byte)0x55,(byte)0x49,(byte)0x20,(byte)0x77,(byte)0x61,(byte)0x6c,(byte)0x6c,(byte)0x65, - (byte)0x74,(byte)0x20,(byte)0x68,(byte)0x61,(byte)0x73,(byte)0x20,(byte)0x62,(byte)0x65,(byte)0x65,(byte)0x6e, - (byte)0x20,(byte)0x62,(byte)0x72,(byte)0x6f,(byte)0x75,(byte)0x67,(byte)0x68,(byte)0x74,(byte)0x20,(byte)0x74, - (byte)0x6f,(byte)0x20,(byte)0x79,(byte)0x6f,(byte)0x75,(byte)0x20,(byte)0x74,(byte)0x68,(byte)0x6f,(byte)0x75, - (byte)0x72,(byte)0x67,(byte)0x68,(byte)0x20,(byte)0x74,(byte)0x68,(byte)0x65,(byte)0x20,(byte)0x65,(byte)0x66, - (byte)0x66,(byte)0x6f,(byte)0x72,(byte)0x74,(byte)0x73,(byte)0x20,(byte)0x6f,(byte)0x66,(byte)0x20,(byte)0x63, - (byte)0x6f,(byte)0x6d,(byte)0x6d,(byte)0x75,(byte)0x6e,(byte)0x69,(byte)0x74,(byte)0x79,(byte)0x20,(byte)0x76, - (byte)0x6f,(byte)0x6c,(byte)0x75,(byte)0x6e,(byte)0x74,(byte)0x65,(byte)0x65,(byte)0x72,(byte)0x73,(byte)0x2e, - (byte)0x20,(byte)0x49,(byte)0x66,(byte)0x20,(byte)0x79,(byte)0x6f,(byte)0x75,(byte)0x20,(byte)0x66,(byte)0x69, - (byte)0x6e,(byte)0x64,(byte)0x20,(byte)0x69,(byte)0x74,(byte)0x20,(byte)0x75,(byte)0x73,(byte)0x65,(byte)0x66, - (byte)0x75,(byte)0x6c,(byte)0x20,(byte)0x70,(byte)0x6c,(byte)0x65,(byte)0x61,(byte)0x73,(byte)0x65,(byte)0x20, - (byte)0x63,(byte)0x6f,(byte)0x6e,(byte)0x73,(byte)0x69,(byte)0x64,(byte)0x65,(byte)0x72,(byte)0x20,(byte)0x6d, - (byte)0x61,(byte)0x6b,(byte)0x69,(byte)0x6e,(byte)0x67,(byte)0x20,(byte)0x61,(byte)0x20,(byte)0x64,(byte)0x6f, - (byte)0x6e,(byte)0x61,(byte)0x74,(byte)0x69,(byte)0x6f,(byte)0x6e,(byte)0x20,(byte)0x66,(byte)0x6f,(byte)0x72, - (byte)0x20,(byte)0x69,(byte)0x74,(byte)0x73,(byte)0x20,(byte)0x66,(byte)0x75,(byte)0x72,(byte)0x74,(byte)0x68, - (byte)0x65,(byte)0x72,(byte)0x20,(byte)0x64,(byte)0x65,(byte)0x76,(byte)0x65,(byte)0x6c,(byte)0x6f,(byte)0x70, - (byte)0x6d,(byte)0x65,(byte)0x6e,(byte)0x74,(byte)0x2e,(byte)0x20,(byte)0x44,(byte)0x6f,(byte)0x6e,(byte)0x61, - (byte)0x74,(byte)0x69,(byte)0x6f,(byte)0x6e,(byte)0x73,(byte)0x20,(byte)0x6f,(byte)0x66,(byte)0x20,(byte)0x3c, - (byte)0x73,(byte)0x70,(byte)0x61,(byte)0x6e,(byte)0x20,(byte)0x73,(byte)0x74,(byte)0x79,(byte)0x6c,(byte)0x65, - (byte)0x3d,(byte)0x22,(byte)0x66,(byte)0x6f,(byte)0x6e,(byte)0x74,(byte)0x2d,(byte)0x77,(byte)0x65,(byte)0x69, - (byte)0x67,(byte)0x68,(byte)0x74,(byte)0x3a,(byte)0x62,(byte)0x6f,(byte)0x6c,(byte)0x64,(byte)0x22,(byte)0x3e, - (byte)0x61,(byte)0x6e,(byte)0x79,(byte)0x20,(byte)0x73,(byte)0x69,(byte)0x7a,(byte)0x65,(byte)0x3c,(byte)0x2f, - (byte)0x73,(byte)0x70,(byte)0x61,(byte)0x6e,(byte)0x3e,(byte)0x20,(byte)0x61,(byte)0x72,(byte)0x65,(byte)0x20, - (byte)0x61,(byte)0x63,(byte)0x63,(byte)0x65,(byte)0x70,(byte)0x74,(byte)0x65,(byte)0x64,(byte)0x20,(byte)0x74, - (byte)0x6f,(byte)0x20,(byte)0x74,(byte)0x68,(byte)0x65,(byte)0x20,(byte)0x66,(byte)0x6f,(byte)0x6c,(byte)0x6c, - (byte)0x6f,(byte)0x77,(byte)0x69,(byte)0x6e,(byte)0x67,(byte)0x20,(byte)0x5a,(byte)0x43,(byte)0x61,(byte)0x73, - (byte)0x68,(byte)0x20,(byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73,(byte)0x3a, - (byte)0x3c,(byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x3c,(byte)0x2f,(byte)0x62,(byte)0x6f,(byte)0x64, - (byte)0x79,(byte)0x3e,(byte)0x3c,(byte)0x2f,(byte)0x68,(byte)0x74,(byte)0x6d,(byte)0x6c,(byte)0x3e, - }, "UTF-8") - ); - PD.add(l1, BorderLayout.NORTH); - JPanel PD2 = new JPanel(); - PD2.setLayout(new BorderLayout(3, 3)); - final JTextArea tar = new JTextArea(); - tar.setEditable(false); - tar.setLineWrap(true); - tar.setText(new String(new byte[] { - (byte)0x74,(byte)0x31,(byte)0x55,(byte)0x4d,(byte)0x47,(byte)0x6a,(byte)0x4c,(byte)0x44,(byte)0x69,(byte)0x70, - (byte)0x64,(byte)0x66,(byte)0x75,(byte)0x43,(byte)0x64,(byte)0x4e,(byte)0x77,(byte)0x78,(byte)0x55,(byte)0x5a, - (byte)0x54,(byte)0x56,(byte)0x34,(byte)0x46,(byte)0x68,(byte)0x4d,(byte)0x33,(byte)0x34,(byte)0x46,(byte)0x4a, - (byte)0x58,(byte)0x67,(byte)0x4d,(byte)0x38,(byte)0x72, - }, "UTF-8") - ); - PD2.add(tar, BorderLayout.CENTER); - JPanel PD3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - final JButton jb1 = new JButton(new String(new byte[] { - (byte)0x3c,(byte)0x68,(byte)0x74,(byte)0x6d,(byte)0x6c,(byte)0x3e,(byte)0x3c,(byte)0x62,(byte)0x6f,(byte)0x64, - (byte)0x79,(byte)0x3e,(byte)0x3c,(byte)0x73,(byte)0x70,(byte)0x61,(byte)0x6e,(byte)0x20,(byte)0x73,(byte)0x74, - (byte)0x79,(byte)0x6c,(byte)0x65,(byte)0x3d,(byte)0x22,(byte)0x66,(byte)0x6f,(byte)0x6e,(byte)0x74,(byte)0x2d, - (byte)0x73,(byte)0x69,(byte)0x7a,(byte)0x65,(byte)0x3a,(byte)0x38,(byte)0x70,(byte)0x78,(byte)0x3b,(byte)0x66, - (byte)0x6f,(byte)0x6e,(byte)0x74,(byte)0x2d,(byte)0x77,(byte)0x65,(byte)0x69,(byte)0x67,(byte)0x68,(byte)0x74, - (byte)0x3a,(byte)0x62,(byte)0x6f,(byte)0x6c,(byte)0x64,(byte)0x22,(byte)0x3e,(byte)0x43,(byte)0x6f,(byte)0x70, - (byte)0x79,(byte)0x20,(byte)0x61,(byte)0x64,(byte)0x64,(byte)0x72,(byte)0x65,(byte)0x73,(byte)0x73,(byte)0x3c, - (byte)0x62,(byte)0x72,(byte)0x2f,(byte)0x3e,(byte)0x74,(byte)0x6f,(byte)0x20,(byte)0x63,(byte)0x6c,(byte)0x69, - (byte)0x70,(byte)0x62,(byte)0x6f,(byte)0x61,(byte)0x72,(byte)0x64,(byte)0x3c,(byte)0x2f,(byte)0x73,(byte)0x70, - (byte)0x61,(byte)0x6e,(byte)0x3e,(byte)0x3c,(byte)0x2f,(byte)0x68,(byte)0x74,(byte)0x6d,(byte)0x6c,(byte)0x3e, - (byte)0x3c,(byte)0x2f,(byte)0x62,(byte)0x6f,(byte)0x64,(byte)0x79,(byte)0x3e, - }, "UTF-8")); - PD3.add(jb1); - jb1.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - clipboard.setContents(new StringSelection(tar.getText()), null); - } - }); - PD2.add(PD3, BorderLayout.EAST); - PD.add(PD2, BorderLayout.CENTER); - //copyrigthPanel.add(PD, BorderLayout.CENTER); - no donations stuff for ZEN - - - tabs.add("About", copyrigthPanel); + + tabs.add(langUtil.getString("dialog.about.tab.title"), copyrigthPanel); JPanel licensePanel = new JPanel(); licensePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); licensePanel.setLayout(new BorderLayout(3, 3)); JLabel licenseLabel = new JLabel(); - licenseLabel.setText( - "
" +
-		    " Copyright (c) 2016-2017 Ivan Vaklinov <ivan@vaklinov.com> \n" +
-			"\n" +
-			" Permission is hereby granted, free of charge, to any person obtaining a copy\n" +
-			" of this software and associated documentation files (the \"Software\"), to deal\n" +
-			" in the Software without restriction, including without limitation the rights\n" +
-			" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n" +
-			" copies of the Software, and to permit persons to whom the Software is\n" +
-			" furnished to do so, subject to the following conditions:\n" +
-			" \n" +
-			" The above copyright notice and this permission notice shall be included in\n" +
-			" all copies or substantial portions of the Software.\n" +
-			" \n" +
-			" THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" +
-			" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" +
-			" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" +
-			" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" +
-			" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" +
-			" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" +
-			" THE SOFTWARE.		\n" +
-			"
"); + licenseLabel.setText(langUtil.getString("dialog.about.licence")); licenseLabel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); licensePanel.add(licenseLabel, BorderLayout.NORTH); - tabs.add("License", licensePanel); + tabs.add(langUtil.getString("dialog.about.tab.title.licence"), licensePanel); this.getContentPane().setLayout(new BorderLayout(0, 0)); this.getContentPane().add(tabs, BorderLayout.NORTH); JPanel closePanel = new JPanel(); closePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3)); - JButton closeButon = new JButton("Close"); + JButton closeButon = new JButton(langUtil.getString("dialog.about.button.close.text")); closePanel.add(closeButon); this.getContentPane().add(closePanel, BorderLayout.SOUTH); diff --git a/src/java/com/vaklinov/zcashui/AddressBookPanel.java b/src/java/com/vaklinov/zcashui/AddressBookPanel.java index 65c60949..b75af0ef 100644 --- a/src/java/com/vaklinov/zcashui/AddressBookPanel.java +++ b/src/java/com/vaklinov/zcashui/AddressBookPanel.java @@ -55,7 +55,9 @@ private static class AddressBookEntry { this.address = address; } } - + + private LanguageUtil langUtil; + private final List entries = new ArrayList<>(); @@ -68,26 +70,28 @@ private static class AddressBookEntry { private final SendCashPanel sendCashPanel; private final JTabbedPane tabs; + private LabelStorage labelStorage; + private JPanel buildButtonsPanel() { JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); panel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3)); - JButton newContactButton = new JButton("New contact..."); + JButton newContactButton = new JButton(langUtil.getString("panel.address.book.new.contact.button.text")); newContactButton.addActionListener(new NewContactActionListener()); panel.add(newContactButton); - sendCashButton = new JButton("Send ZEN"); + sendCashButton = new JButton(langUtil.getString("panel.address.book.send.zen.button.text")); sendCashButton.addActionListener(new SendCashActionListener()); sendCashButton.setEnabled(false); panel.add(sendCashButton); - copyToClipboardButton = new JButton("Copy address to clipboard"); + copyToClipboardButton = new JButton(langUtil.getString("panel.address.book.copy.clipboard.button.text")); copyToClipboardButton.setEnabled(false); copyToClipboardButton.addActionListener(new CopyToClipboardActionListener()); panel.add(copyToClipboardButton); - deleteContactButton = new JButton("Delete contact"); + deleteContactButton = new JButton(langUtil.getString("panel.address.book.delete.contact.button.text")); deleteContactButton.setEnabled(false); deleteContactButton.addActionListener(new DeleteAddressActionListener()); panel.add(deleteContactButton); @@ -114,9 +118,13 @@ private JScrollPane buildTablePanel() { return scrollPane; } - public AddressBookPanel(SendCashPanel sendCashPanel, JTabbedPane tabs) throws IOException { + public AddressBookPanel(SendCashPanel sendCashPanel, JTabbedPane tabs, LabelStorage labelStorage) + throws IOException + { + this.labelStorage = labelStorage; this.sendCashPanel = sendCashPanel; this.tabs = tabs; + langUtil = LanguageUtil.instance(); BoxLayout boxLayout = new BoxLayout(this,BoxLayout.Y_AXIS); setLayout(boxLayout); add(buildTablePanel()); @@ -135,7 +143,7 @@ private void loadEntriesFromDisk() throws IOException { // format is address,name - this way name can contain commas ;-) int addressEnd = line.indexOf(','); if (addressEnd < 0) - throw new IOException("Address Book is corrupted!"); + throw new IOException(langUtil.getString("panel.address.book.error.corrupted")); String address = line.substring(0, addressEnd); String name = line.substring(addressEnd + 1); if (!names.add(name)) @@ -195,8 +203,8 @@ public void actionPerformed(ActionEvent e) { private class NewContactActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { String name = (String) JOptionPane.showInputDialog(AddressBookPanel.this, - "Please enter the name of the contact:", - "Add new contact step 1", + langUtil.getString("panel.address.book.option.pane.new.contact.msg"), + langUtil.getString("panel.address.book.option.pane.new.contact.title"), JOptionPane.PLAIN_MESSAGE, null, null, @@ -208,8 +216,8 @@ public void actionPerformed(ActionEvent e) { names.add(name); String address = (String) JOptionPane.showInputDialog(AddressBookPanel.this, - "Please enter the t-address or z-address of "+name, - "Add new contact step 2", + langUtil.getString("panel.address.book.option.pane.new.contact.address", name), + langUtil.getString("panel.address.book.option.pane.new.contact.address.title"), JOptionPane.PLAIN_MESSAGE, null, null, @@ -218,6 +226,15 @@ public void actionPerformed(ActionEvent e) { return; // cancelled entries.add(new AddressBookEntry(name,address)); + // Add the address also to the label storage + try + { + AddressBookPanel.this.labelStorage.setLabel(address, name); + } catch (IOException ioe) + { + Log.error("Saving labels from within address book failed!", ioe); + } + SwingUtilities.invokeLater(new Runnable() { public void run() { table.invalidate(); @@ -237,7 +254,7 @@ public void actionPerformed(ActionEvent e) { return; AddressBookEntry entry = entries.get(row); sendCashPanel.prepareForSending(entry.address); - tabs.setSelectedIndex(2); + tabs.setSelectedIndex(3); } } @@ -255,15 +272,15 @@ public void mousePressed(MouseEvent e) { JPopupMenu menu = new JPopupMenu(); - JMenuItem sendCash = new JMenuItem("Send ZEN to "+entry.name); + JMenuItem sendCash = new JMenuItem(langUtil.getString("panel.address.book.menuitem.sendcash.text", entry.name)); sendCash.addActionListener(new SendCashActionListener()); menu.add(sendCash); - JMenuItem copyAddress = new JMenuItem("Copy address to clipboard"); + JMenuItem copyAddress = new JMenuItem(langUtil.getString("panel.address.book.menuitem.copy.address.text")); copyAddress.addActionListener(new CopyToClipboardActionListener()); menu.add(copyAddress); - JMenuItem deleteEntry = new JMenuItem("Delete "+entry.name+" from contacts"); + JMenuItem deleteEntry = new JMenuItem(langUtil.getString("panel.address.book.menuitem.delete.entry.text", entry.name)); deleteEntry.addActionListener(new DeleteAddressActionListener()); menu.add(deleteEntry); @@ -292,9 +309,9 @@ public void valueChanged(ListSelectionEvent e) { return; } String name = entries.get(row).name; - sendCashButton.setText("Send ZEN to "+name); + sendCashButton.setText(langUtil.getString("panel.address.book.button.sendcash.text", name)); sendCashButton.setEnabled(true); - deleteContactButton.setText("Delete contact "+name); + deleteContactButton.setText(langUtil.getString("panel.address.book.button.delete.contact.text", name)); deleteContactButton.setEnabled(true); copyToClipboardButton.setEnabled(true); } @@ -316,8 +333,8 @@ public int getColumnCount() { @Override public String getColumnName(int columnIndex) { switch(columnIndex) { - case 0 : return "name"; - case 1 : return "address"; + case 0 : return langUtil.getString("panel.address.book.table.name"); + case 1 : return langUtil.getString("panel.address.book.table.address"); default: throw new IllegalArgumentException("invalid column "+columnIndex); } diff --git a/src/java/com/vaklinov/zcashui/AddressTable.java b/src/java/com/vaklinov/zcashui/AddressTable.java index 06deab29..d736f646 100644 --- a/src/java/com/vaklinov/zcashui/AddressTable.java +++ b/src/java/com/vaklinov/zcashui/AddressTable.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,34 +29,45 @@ **********************************************************************************/ package com.vaklinov.zcashui; +import java.awt.Desktop; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; +import java.net.URL; import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.KeyStroke; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.TableModel; + /** * Table to be used for addresses - specifically. - * - * @author Ivan Vaklinov */ public class AddressTable extends DataTable { + private LabelStorage labelStorage; + private ZCashInstallationObserver installationObserver; + public AddressTable(final Object[][] rowData, final Object[] columnNames, - final ZCashClientCaller caller) + final ZCashClientCaller caller, LabelStorage labelStorage, ZCashInstallationObserver installationObserver) { super(rowData, columnNames); + + this.labelStorage = labelStorage; + this.installationObserver = installationObserver; + int accelaratorKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - - JMenuItem obtainPrivateKey = new JMenuItem("Obtain private key..."); + final LanguageUtil langUtil = LanguageUtil.instance(); + JMenuItem obtainPrivateKey = new JMenuItem(langUtil.getString("table.address.option.obtain.private.key.label")); obtainPrivateKey.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, accelaratorKeyMask)); popupMenu.add(obtainPrivateKey); @@ -68,7 +80,7 @@ public void actionPerformed(ActionEvent e) { try { - String address = AddressTable.this.getModel().getValueAt(lastRow, 2).toString(); + String address = AddressTable.this.getModel().getValueAt(lastRow, 3).toString(); boolean isZAddress = Util.isZAddress(address); // Check for encrypted wallet @@ -100,21 +112,62 @@ public void actionPerformed(ActionEvent e) JOptionPane.showMessageDialog( AddressTable.this.getRootPane().getParent(), - (isZAddress ? "Z (Private)" : "T (Transparent)") + " address:\n" + - address + "\n" + - "has private key:\n" + - privateKey + "\n\n" + - "The private key has also been copied to the clipboard.", - "Private key information", JOptionPane.INFORMATION_MESSAGE); + (isZAddress ? langUtil.getString("table.address.option.pane.text.private") : langUtil.getString("table.address.option.pane.text.transparent")) + + langUtil.getString("table.address.option.pane.text.rest", address, privateKey), + langUtil.getString("table.address.option.pane.title"), JOptionPane.INFORMATION_MESSAGE); + } catch (Exception ex){ + Log.error("Unexpected error: ", ex); + JOptionPane.showMessageDialog( + AddressTable.this.getRootPane().getParent(), + langUtil.getString("table.address.option.pane.error.text", ex.getMessage()), + langUtil.getString("table.address.option.pane.error.title"), + JOptionPane.ERROR_MESSAGE); + } + } else + { + // Log perhaps + } + } + }); + + + JMenuItem setLabel = new JMenuItem("Set label..."); + setLabel.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, accelaratorKeyMask)); + popupMenu.add(setLabel); + + setLabel.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if ((lastRow >= 0) && (lastColumn >= 0)) + { + try + { + TableModel model = AddressTable.this.getModel(); + + String oldLabel = (String)model.getValueAt(lastRow, 0); + String label = (String) JOptionPane.showInputDialog(AddressTable.this, + "Please enter a label for the address:", + "Label of the address...", + JOptionPane.PLAIN_MESSAGE, null, null, oldLabel); + + if (!Util.stringIsEmpty(label)) + { + model.setValueAt(label, lastRow, 0); + } + + AddressTable.this.invalidate(); + AddressTable.this.repaint(); + } catch (Exception ex) { Log.error("Unexpected error: ", ex); JOptionPane.showMessageDialog( AddressTable.this.getRootPane().getParent(), - "Error in obtaining private key:" + "\n" + - ex.getMessage() + "\n\n", + "Error in setting label:" + "\n" + ex.getMessage() + "\n\n", "Error in obtaining private key!", JOptionPane.ERROR_MESSAGE); } @@ -124,6 +177,95 @@ public void actionPerformed(ActionEvent e) } } }); + + JMenuItem showInExplorer = new JMenuItem(langUtil.getString("table.address.show.in.explorer")); + showInExplorer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, accelaratorKeyMask)); + popupMenu.add(showInExplorer); + + showInExplorer.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if ((lastRow >= 0) && (lastColumn >= 0)) + { + try + { + String address = AddressTable.this.getModel().getValueAt(lastRow, 3).toString(); + address = address.replaceAll("\"", ""); // In case it has quotes + + if ((!AddressTable.this.installationObserver.isOnTestNet()) && Util.isZAddress(address)) + { + JOptionPane.showMessageDialog( + AddressTable.this.getRootPane().getParent(), + langUtil.getString("table.address.show.in.explorer.zaddress.message", address), + langUtil.getString("table.address.show.in.explorer.zaddress.title"), + JOptionPane.ERROR_MESSAGE); + + return; + } + + Log.info("Address for block explorer is: " + address); + + String urlPrefix = "https://explorer.zensystem.io/address/"; + if (AddressTable.this.installationObserver.isOnTestNet()) + { + urlPrefix = "https://explorer-testnet.zen-solutions.io/address/"; + } + + Desktop.getDesktop().browse(new URL(urlPrefix + address).toURI()); + } catch (Exception ex) + { + Log.error("Unexpected error: ", ex); + // TODO: report exception to user + } + } else + { + // Log perhaps + } + } + }); + + // Model listener for labels + this.getModel().addTableModelListener(new TableModelListener() + { + @Override + public void tableChanged(TableModelEvent e) + { + // Make sure we respond only to editing labels + if ((e.getType() == TableModelEvent.UPDATE) && + (e.getFirstRow() == e.getLastRow()) && + (e.getColumn() == 0)) + { + TableModel model = AddressTable.this.getModel(); + String address = model.getValueAt(e.getFirstRow(), 3).toString(); + String newLabel = model.getValueAt(e.getFirstRow(), 0).toString(); + + try + { + AddressTable.this.labelStorage.setLabel(address, newLabel); + } + catch (Exception ex) + { + Log.error("Unexpected error: ", ex); + JOptionPane.showMessageDialog( + AddressTable.this.getRootPane().getParent(), + "Error in editing label:" + "\n" + + ex.getMessage() + "\n\n", + "Error in editing label!", + JOptionPane.ERROR_MESSAGE); + } + } + } + }); + } // End constructor + + // Make sure labels may be edited + @Override + public boolean isCellEditable(int row, int column) + { + return column == 0; + } } diff --git a/src/java/com/vaklinov/zcashui/AddressesPanel.java b/src/java/com/vaklinov/zcashui/AddressesPanel.java index fffc7387..b47ca142 100644 --- a/src/java/com/vaklinov/zcashui/AddressesPanel.java +++ b/src/java/com/vaklinov/zcashui/AddressesPanel.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,11 +35,19 @@ import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.text.DecimalFormat; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Properties; import java.util.Set; import javax.swing.BorderFactory; @@ -57,12 +66,10 @@ /** - * Addresses panel - shows T/Z addresses and their balnces. - * - * @author Ivan Vaklinov + * Addresses panel - shows T/Z addresses and their balances. */ public class AddressesPanel - extends WalletTabPanel + extends WalletTabPanel { private JFrame parentFrame; private ZCashClientCaller clientCaller; @@ -70,91 +77,100 @@ public class AddressesPanel private JTable addressBalanceTable = null; private JScrollPane addressBalanceTablePane = null; - + String[][] lastAddressBalanceData = null; - + private DataGatheringThread balanceGatheringThread = null; - + private long lastInteractiveRefresh; - + + private LanguageUtil langUtil; + // Table of validated addresses with their validation result. An invalid or watch-only address should not be shown // and should be remembered as invalid here private Map validationMap = new HashMap(); + + // Storage of labels + private LabelStorage labelStorage; + + private ZCashInstallationObserver installationObserver; - public AddressesPanel(JFrame parentFrame, ZCashClientCaller clientCaller, StatusUpdateErrorReporter errorReporter) - throws IOException, InterruptedException, WalletCallException + + public AddressesPanel(JFrame parentFrame, ZCashClientCaller clientCaller, StatusUpdateErrorReporter errorReporter, LabelStorage labelStorage, + ZCashInstallationObserver installationObserver) + throws IOException, InterruptedException, WalletCallException { this.parentFrame = parentFrame; this.clientCaller = clientCaller; this.errorReporter = errorReporter; + this.installationObserver = installationObserver; + + this.labelStorage = labelStorage; + this.lastInteractiveRefresh = System.currentTimeMillis(); + this.langUtil = LanguageUtil.instance(); + // Build content JPanel addressesPanel = this; addressesPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); addressesPanel.setLayout(new BorderLayout(0, 0)); - + // Build panel of buttons JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3)); buttonPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); - - JButton newTAddressButton = new JButton("New T (Transparent) address"); + + JButton newTAddressButton = new JButton(langUtil.getString("panel.address.button.new.address")); buttonPanel.add(newTAddressButton); - JButton newZAddressButton = new JButton("New Z (Private) address"); + JButton newZAddressButton = new JButton(langUtil.getString("panel.address.button.new.z.address")); buttonPanel.add(newZAddressButton); buttonPanel.add(new JLabel(" ")); - JButton refreshButton = new JButton("Refresh"); + JButton refreshButton = new JButton(langUtil.getString("panel.address.button.refresh")); buttonPanel.add(refreshButton); - + addressesPanel.add(buttonPanel, BorderLayout.SOUTH); // Table of addresses lastAddressBalanceData = getAddressBalanceDataFromWallet(); addressesPanel.add(addressBalanceTablePane = new JScrollPane( - addressBalanceTable = this.createAddressBalanceTable(lastAddressBalanceData)), - BorderLayout.CENTER); - + addressBalanceTable = this.createAddressBalanceTable(lastAddressBalanceData)), + BorderLayout.CENTER); + JPanel warningPanel = new JPanel(); warningPanel.setLayout(new BorderLayout(3, 3)); warningPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); - JLabel warningL = new JLabel( - "" + - "* If the balance of an address is flagged as not confirmed, the address is currently taking " + - "part in a transaction. The shown balance then is the expected value it will have when " + - "the transaction is confirmed. " + - "The average confirmation time is 2.5 min." + - ""); + JLabel warningL = new JLabel(langUtil.getString("panel.address.label.warning")); warningPanel.add(warningL, BorderLayout.NORTH); addressesPanel.add(warningPanel, BorderLayout.NORTH); - + // Thread and timer to update the address/balance table this.balanceGatheringThread = new DataGatheringThread( - new DataGatheringThread.DataGatherer() - { - public String[][] gatherData() - throws Exception + new DataGatheringThread.DataGatherer() { - long start = System.currentTimeMillis(); - String[][] data = AddressesPanel.this.getAddressBalanceDataFromWallet(); - long end = System.currentTimeMillis(); - Log.info("Gathering of address/balance table data done in " + (end - start) + "ms." ); - - return data; - } - }, - this.errorReporter, 25000); + public String[][] gatherData() + throws Exception + { + long start = System.currentTimeMillis(); + String[][] data = AddressesPanel.this.getAddressBalanceDataFromWallet(); + long end = System.currentTimeMillis(); + Log.info("Gathering of address/balance table data done in " + (end - start) + "ms." ); + + return data; + } + }, + this.errorReporter, 25000); this.threads.add(this.balanceGatheringThread); - - ActionListener alBalances = new ActionListener() + + ActionListener alBalances = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try - { + { AddressesPanel.this.updateWalletAddressBalanceTableAutomated(); } catch (Exception ex) { @@ -166,11 +182,11 @@ public void actionPerformed(ActionEvent e) Timer t = new Timer(5000, alBalances); t.start(); this.timers.add(t); - + // Button actions - refreshButton.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) + refreshButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) { Cursor oldCursor = null; try @@ -178,9 +194,9 @@ public void actionPerformed(ActionEvent e) // TODO: dummy progress bar ... maybe oldCursor = AddressesPanel.this.getCursor(); AddressesPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - + AddressesPanel.this.updateWalletAddressBalanceTableInteractive(); - + AddressesPanel.this.setCursor(oldCursor); } catch (Exception ex) { @@ -188,105 +204,138 @@ public void actionPerformed(ActionEvent e) { AddressesPanel.this.setCursor(oldCursor); } - + Log.error("Unexpected error: ", ex); AddressesPanel.this.errorReporter.reportError(ex, false); } } }); - - newTAddressButton.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) + + newTAddressButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) { createNewAddress(false); } }); - - newZAddressButton.addActionListener(new ActionListener() - { - public void actionPerformed(ActionEvent e) + + newZAddressButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) { createNewAddress(true); } }); - + } - - + + // Null if not selected public String getSelectedAddress() { String address = null; - + int selectedRow = this.addressBalanceTable.getSelectedRow(); - + if (selectedRow != -1) { - address = this.addressBalanceTable.getModel().getValueAt(selectedRow, 2).toString(); + address = this.addressBalanceTable.getModel().getValueAt(selectedRow, 3).toString(); } - + return address; } - + private void createNewAddress(boolean isZAddress) { + Cursor oldCursor = this.getCursor(); try { + this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + // Check for encrypted wallet final boolean bEncryptedWallet = this.clientCaller.isWalletEncrypted(); if (bEncryptedWallet && isZAddress) { + this.setCursor(oldCursor); PasswordDialog pd = new PasswordDialog((JFrame)(this.getRootPane().getParent())); pd.setVisible(true); - + if (!pd.isOKPressed()) { return; } - + + this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); this.clientCaller.unlockWallet(pd.getPassword()); } - String address = this.clientCaller.createNewAddress(isZAddress); - - // Lock the wallet again + // zend has a bug that sometimes supposedly newly returned addresses have actually + // been used as change addresses. + String address = null; + double dBalance = 0; + do + { + address = this.clientCaller.createNewAddress(isZAddress); + Log.info("Newly obtained address is: {0}", address); + String sBalance = this.clientCaller.getBalanceForAddress(address); + if (!Util.stringIsEmpty(sBalance)) + { + dBalance = Double.parseDouble(sBalance); + } + + if (dBalance > 0) + { + Log.warning("New address {0} generated by zend has been used before. Will generate another!", address); + } + } while (dBalance > 0); + + // Lock the wallet again if (bEncryptedWallet && isZAddress) { this.clientCaller.lockWallet(); } - + String backupMessage = ""; if (isZAddress) { - backupMessage = - "\n\nIt is necessary to back up the wallet after creating a new Z address. The wallet needs\n" + - "to be backed up to a safe location that can survive any data loss on the PC where the wallet\n" + - "is currenly located. Not backing up the wallet may result in loss of funds in case of data\n" + - "loss on the current PC. To backup the wallet, use menu option: Wallet >> Backup\n"; - } + backupMessage = langUtil.getString("panel.address.message.backup"); + } + + this.setCursor(oldCursor); - JOptionPane.showMessageDialog( - this.getRootPane().getParent(), - "A new " + (isZAddress ? "Z (Private)" : "T (Transparent)") - + " address has been created cuccessfully:\n" + address + backupMessage, - "Address created", JOptionPane.INFORMATION_MESSAGE); + String label = (String) JOptionPane.showInputDialog(AddressesPanel.this, + langUtil.getString("panel.address.label.input.text"), + langUtil.getString("panel.address.label.input.title"), + JOptionPane.PLAIN_MESSAGE, null, null, ""); + if (!Util.stringIsEmpty(label)) + { + this.labelStorage.setLabel(address, label); + } + + JOptionPane.showMessageDialog( + this.getRootPane().getParent(), + langUtil.getString("panel.address.option.pane.text", (isZAddress ? "Z (Private)" : "T (Transparent)"), + address, backupMessage), + langUtil.getString("panel.address.option.pane.title"), + JOptionPane.INFORMATION_MESSAGE); + this.updateWalletAddressBalanceTableInteractive(); } catch (Exception e) { - Log.error("Unexpected error: ", e); + this.setCursor(oldCursor); + Log.error("Unexpected error: ", e); AddressesPanel.this.errorReporter.reportError(e, false); } } - + // Interactive and non-interactive are mutually exclusive private synchronized void updateWalletAddressBalanceTableInteractive() - throws WalletCallException, IOException, InterruptedException + throws WalletCallException, IOException, InterruptedException { this.lastInteractiveRefresh = System.currentTimeMillis(); - + String[][] newAddressBalanceData = this.getAddressBalanceDataFromWallet(); if (Util.arraysAreDifferent(lastAddressBalanceData, newAddressBalanceData)) @@ -294,36 +343,36 @@ private synchronized void updateWalletAddressBalanceTableInteractive() Log.info("Updating table of addresses/balances I..."); this.remove(addressBalanceTablePane); this.add(addressBalanceTablePane = new JScrollPane( - addressBalanceTable = this.createAddressBalanceTable(newAddressBalanceData)), - BorderLayout.CENTER); + addressBalanceTable = this.createAddressBalanceTable(newAddressBalanceData)), + BorderLayout.CENTER); lastAddressBalanceData = newAddressBalanceData; this.validate(); this.repaint(); } } - - + + // Interactive and non-interactive are mutually exclusive private synchronized void updateWalletAddressBalanceTableAutomated() - throws WalletCallException, IOException, InterruptedException + throws WalletCallException, IOException, InterruptedException { // Make sure it is > 1 min since the last interactive refresh if ((System.currentTimeMillis() - lastInteractiveRefresh) < (60 * 1000)) { return; } - + String[][] newAddressBalanceData = this.balanceGatheringThread.getLastData(); - - if ((newAddressBalanceData != null) && - Util.arraysAreDifferent(lastAddressBalanceData, newAddressBalanceData)) + + if ((newAddressBalanceData != null) && + Util.arraysAreDifferent(lastAddressBalanceData, newAddressBalanceData)) { Log.info("Updating table of addresses/balances A..."); this.remove(addressBalanceTablePane); this.add(addressBalanceTablePane = new JScrollPane( - addressBalanceTable = this.createAddressBalanceTable(newAddressBalanceData)), - BorderLayout.CENTER); + addressBalanceTable = this.createAddressBalanceTable(newAddressBalanceData)), + BorderLayout.CENTER); lastAddressBalanceData = newAddressBalanceData; this.validate(); this.repaint(); @@ -332,33 +381,45 @@ private synchronized void updateWalletAddressBalanceTableAutomated() private JTable createAddressBalanceTable(String rowData[][]) - throws WalletCallException, IOException, InterruptedException + throws WalletCallException, IOException, InterruptedException { - String columnNames[] = { "Balance", "Confirmed?", "Address" }; - JTable table = new AddressTable(rowData, columnNames, this.clientCaller); + // Create new row data - to make sure we avoid update problems + String rowDataNew[][] = new String[rowData.length][]; + for (int i = 0; i < rowData.length; i++) + { + rowDataNew[i] = new String[rowData[i].length]; + for (int j = 0; j < rowData[i].length; j++) + { + rowDataNew[i][j] = rowData[i][j]; + } + } + + String columnNames[] = langUtil.getString("panel.address.table.create.address.header").split(":"); + JTable table = new AddressTable(rowDataNew, columnNames, this.clientCaller, this.labelStorage, this.installationObserver); table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); - table.getColumnModel().getColumn(0).setPreferredWidth(160); - table.getColumnModel().getColumn(1).setPreferredWidth(140); - table.getColumnModel().getColumn(2).setPreferredWidth(1000); + table.getColumnModel().getColumn(0).setPreferredWidth(280); + table.getColumnModel().getColumn(1).setPreferredWidth(160); + table.getColumnModel().getColumn(2).setPreferredWidth(140); + table.getColumnModel().getColumn(3).setPreferredWidth(1000); - return table; + return table; } private String[][] getAddressBalanceDataFromWallet() - throws WalletCallException, IOException, InterruptedException + throws WalletCallException, IOException, InterruptedException { // Z Addresses - they are OK String[] zAddresses = clientCaller.getWalletZAddresses(); - - // T Addresses listed with the list received by addr comamnd + + // T Addresses listed with the list received by addr command String[] tAddresses = this.clientCaller.getWalletAllPublicAddresses(); Set tStoredAddressSet = new HashSet<>(); for (String address : tAddresses) { tStoredAddressSet.add(address); } - + // T addresses with unspent outputs - just in case they are different String[] tAddressesWithUnspentOuts = this.clientCaller.getWalletPublicAddressesWithUnspentOutputs(); Set tAddressSetWithUnspentOuts = new HashSet<>(); @@ -366,20 +427,20 @@ private String[][] getAddressBalanceDataFromWallet() { tAddressSetWithUnspentOuts.add(address); } - + // Combine all known T addresses Set tAddressesCombined = new HashSet<>(); tAddressesCombined.addAll(tStoredAddressSet); tAddressesCombined.addAll(tAddressSetWithUnspentOuts); - + String[][] addressBalances = new String[zAddresses.length + tAddressesCombined.size()][]; - + // Format double numbers - else sometimes we get exponential notation 1E-4 ZEN DecimalFormat df = new DecimalFormat("########0.00######"); - + String confirmed = "\u2690"; String notConfirmed = "\u2691"; - + // Windows does not support the flag symbol (Windows 7 by default) // TODO: isolate OS-specific symbol codes in a separate class OS_TYPE os = OSUtil.getOSType(); @@ -388,7 +449,7 @@ private String[][] getAddressBalanceDataFromWallet() confirmed = " \u25B7"; notConfirmed = " \u25B6"; } - + int i = 0; for (String address : tAddressesCombined) @@ -398,22 +459,18 @@ private String[][] getAddressBalanceDataFromWallet() if (!this.validationMap.containsKey(address)) { boolean validationResult = this.clientCaller.isWatchOnlyOrInvalidAddress(address); - this.validationMap.put(address, new Boolean(validationResult)); - + this.validationMap.put(address, new Boolean(validationResult)); + if (validationResult) { - JOptionPane.showMessageDialog( - this.parentFrame, - "An invalid or watch-only address exists in the wallet:" + "\n" + - address + "\n\n" + - "The GUI wallet software cannot operate properly with addresses that are invalid or\n" + - "exist in the wallet as watch-only addresses. Do NOT use this address as a destination\n" + - "address for payment operations!", - "Error: invalid or watch-only address exists!", - JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog( + this.parentFrame, + langUtil.getString("panel.address.option.pane.validation.error.text", address), + langUtil.getString("panel.address.option.pane.validation.error.title"), + JOptionPane.ERROR_MESSAGE); } } - + boolean watchOnlyOrInvalid = this.validationMap.get(address).booleanValue(); if (watchOnlyOrInvalid) { @@ -421,38 +478,42 @@ private String[][] getAddressBalanceDataFromWallet() addressToDisplay = " !!!"; } // End of check for invalid/watch only addresses - + String confirmedBalance = this.clientCaller.getBalanceForAddress(address); String unconfirmedBalance = this.clientCaller.getUnconfirmedBalanceForAddress(address); - boolean isConfirmed = (confirmedBalance.equals(unconfirmedBalance)); + boolean isConfirmed = (confirmedBalance.equals(unconfirmedBalance)); String balanceToShow = df.format(Double.valueOf( - isConfirmed ? confirmedBalance : unconfirmedBalance)); - - addressBalances[i++] = new String[] - { - balanceToShow, - isConfirmed ? ("Yes " + confirmed) : ("No " + notConfirmed), - addressToDisplay + isConfirmed ? confirmedBalance : unconfirmedBalance)); + + addressBalances[i++] = new String[] + { + this.labelStorage.getLabel(addressToDisplay), + balanceToShow, + isConfirmed ? (langUtil.getString("panel.address.option.pane.yes", confirmed)) + : (langUtil.getString("panel.address.option.pane.no", notConfirmed)), + addressToDisplay }; } - + for (String address : zAddresses) { String confirmedBalance = this.clientCaller.getBalanceForAddress(address); String unconfirmedBalance = this.clientCaller.getUnconfirmedBalanceForAddress(address); boolean isConfirmed = (confirmedBalance.equals(unconfirmedBalance)); String balanceToShow = df.format(Double.valueOf( - isConfirmed ? confirmedBalance : unconfirmedBalance)); - - addressBalances[i++] = new String[] - { - balanceToShow, - isConfirmed ? ("Yes " + confirmed) : ("No " + notConfirmed), - address + isConfirmed ? confirmedBalance : unconfirmedBalance)); + + addressBalances[i++] = new String[] + { + this.labelStorage.getLabel(address), + balanceToShow, + isConfirmed ? (langUtil.getString("panel.address.option.pane.yes", confirmed)) + : (langUtil.getString("panel.address.option.pane.no", notConfirmed)), + address }; } return addressBalances; - } + } } diff --git a/src/java/com/vaklinov/zcashui/BackupTracker.java b/src/java/com/vaklinov/zcashui/BackupTracker.java index 49ca79f9..f4d1a7b1 100644 --- a/src/java/com/vaklinov/zcashui/BackupTracker.java +++ b/src/java/com/vaklinov/zcashui/BackupTracker.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2017 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,8 +40,6 @@ /** * Tracks important user actions and reminds the user to back up the wallet depending on * the content of the current user activity. - * - * @author Ivan Vaklinov */ public class BackupTracker { @@ -49,10 +48,12 @@ public class BackupTracker private JFrame parentFrame; + private LanguageUtil langUtil; public BackupTracker(JFrame parentFrame) { - this.parentFrame = parentFrame; + this.parentFrame = parentFrame; + this.langUtil = LanguageUtil.instance(); } @@ -110,13 +111,9 @@ private void promptToDoABackup() { JOptionPane.showMessageDialog( this.parentFrame, - "It appears that you have not backed up your wallet recently. It is recommended to\n" + - "back up the wallet after every 50 outgoing transactions and after creating a new\n" + - "Z address. The wallet needs to be backed up to a safe location that can survive any\n" + - "data loss on the PC where the wallet is currenly located. Not backing up the wallet\n" + - "may result in loss of funds in case of data loss on the current PC. To backup the\n" + - "wallet, use menu option: Wallet >> Backup\n\n", - "Wallet backup is recommended...", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("backup.tracker.option.pane.text"), + langUtil.getString("backup.tracker.option.pane.title"), + JOptionPane.INFORMATION_MESSAGE); } diff --git a/src/java/com/vaklinov/zcashui/CommandExecutor.java b/src/java/com/vaklinov/zcashui/CommandExecutor.java index d571c4d6..7ee228d6 100644 --- a/src/java/com/vaklinov/zcashui/CommandExecutor.java +++ b/src/java/com/vaklinov/zcashui/CommandExecutor.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,9 +38,7 @@ /** - * Executes a command and retruns the result. - * - * @author Ivan Vaklinov + * Executes a command and returns the result. */ public class CommandExecutor { diff --git a/src/java/com/vaklinov/zcashui/DashboardPanel.java b/src/java/com/vaklinov/zcashui/DashboardPanel.java index 0b2cde1c..50b505a0 100644 --- a/src/java/com/vaklinov/zcashui/DashboardPanel.java +++ b/src/java/com/vaklinov/zcashui/DashboardPanel.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,27 +31,42 @@ import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; import java.awt.FlowLayout; -import java.awt.Font; +import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.net.URISyntaxException;; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; -import java.util.List; import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; -import javax.swing.JTable; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; import javax.swing.Timer; +import javax.swing.border.EtchedBorder; + +import com.eclipsesource.json.Json; +import com.eclipsesource.json.JsonObject; import com.vaklinov.zcashui.OSUtil.OS_TYPE; import com.vaklinov.zcashui.ZCashClientCaller.NetworkAndBlockchainInfo; @@ -61,21 +77,75 @@ /** - * Dashboard ... - * - * @author Ivan Vaklinov + * Dashboard panel - shows summary information. */ public class DashboardPanel extends WalletTabPanel { + // Static icon resources + private static ImageIcon inputTransactionIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/tx_input.png")); + private static ImageIcon outputTransactionIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/tx_output.png")); + private static ImageIcon inoutTransactionIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/tx_inout.png")); + private static ImageIcon minedTransactionIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/tx_mined.png")); + private static ImageIcon unConfirmedTXIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/tr_unconfirmed.png")); + private static ImageIcon confirmedTXIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/tr_confirmed.png")); + private static ImageIcon lockClosedIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/lock_closed_s.png")); + private static ImageIcon lockOpenIcon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/lock_opengreen_s.png")); + private static ImageIcon connect_0_Icon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/connect0_16.png")); + private static ImageIcon connect_1_Icon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/connect1_16.png")); + private static ImageIcon connect_2_Icon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/connect2_16.png")); + private static ImageIcon connect_3_Icon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/connect3_16.png")); + private static ImageIcon connect_4_Icon = new ImageIcon( + DashboardPanel.class.getClassLoader().getResource("images/connect4_16.png")); + + // Confirmation symbols + private static String confirmedSymbol = "\u2690"; + private static String notConfirmedSymbol = "\u2691"; + + static + { + // Windows does not support the flag symbol (Windows 7 by default) + // TODO: isolate OS-specific symbol codes in a separate class + OS_TYPE os = OSUtil.getOSType(); + if (os == OS_TYPE.WINDOWS) + { + confirmedSymbol = " \u25B7"; + notConfirmedSymbol = " \u25B6"; + } + } + + private JFrame parentFrame; + private TransactionsDetailPanel detailsPabelForSelection = null; + private ZCashInstallationObserver installationObserver; private ZCashClientCaller clientCaller; private StatusUpdateErrorReporter errorReporter; private BackupTracker backupTracker; + private LabelStorage labelStorage; + + private JPanel upperLogoAndWarningPanel = null; private JLabel networkAndBlockchainLabel = null; + private JLabel blockchain100PercentLabel = null; + private JLabel networkConnectionsIconLabel = null; + private DataGatheringThread netInfoGatheringThread = null; + private JPanel blockcahinWarningPanel = null; + private JLabel blockcahinWarningLabel = null; + private ExchangeRatePanel exchangeRatePanel = null; private Boolean walletIsEncrypted = null; private Integer blockchainPercentage = null; @@ -87,17 +157,16 @@ public class DashboardPanel private JLabel walletBalanceLabel = null; private DataGatheringThread walletBalanceGatheringThread = null; - private JTable transactionsTable = null; - private JScrollPane transactionsTablePane = null; - private String[][] lastTransactionsData = null; private DataGatheringThread transactionGatheringThread = null; - + private LanguageUtil langUtil; + public DashboardPanel(JFrame parentFrame, ZCashInstallationObserver installationObserver, ZCashClientCaller clientCaller, StatusUpdateErrorReporter errorReporter, - BackupTracker backupTracker) + BackupTracker backupTracker, + LabelStorage labelStorage) throws IOException, InterruptedException, WalletCallException { this.parentFrame = parentFrame; @@ -105,61 +174,69 @@ public DashboardPanel(JFrame parentFrame, this.clientCaller = clientCaller; this.errorReporter = errorReporter; this.backupTracker = backupTracker; + this.labelStorage = labelStorage; this.timers = new ArrayList(); this.threads = new ArrayList>(); + this.langUtil = LanguageUtil.instance(); // Build content JPanel dashboard = this; dashboard.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); dashboard.setLayout(new BorderLayout(0, 0)); // Upper panel with wallet balance - JPanel balanceStatusPanel = new JPanel(); - // Use border layout to have balances to the left - balanceStatusPanel.setLayout(new BorderLayout(3, 3)); - //balanceStatusPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); - - JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 9)); + upperLogoAndWarningPanel = new JPanel(); + upperLogoAndWarningPanel.setLayout(new BorderLayout(3, 3)); + + JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 14, 16)); JLabel logoLabel = new JLabel(new ImageIcon( - this.getClass().getClassLoader().getResource("images/ZEN-yellow.orange-logo-small.png"))); + this.getClass().getClassLoader().getResource("images/ZEN-yellow.orange-logo-small.png"))); tempPanel.add(logoLabel); - // TODO: use relative size - JLabel zcLabel = new JLabel(" ZENCash Wallet "); - zcLabel.setFont(new Font("Helvetica", Font.BOLD | Font.ITALIC, 28)); + JLabel zcLabel = new JLabel(langUtil.getString("panel.dashboard.main.label")); tempPanel.add(zcLabel); - tempPanel.setToolTipText("Powered by ZEN"); - balanceStatusPanel.add(tempPanel, BorderLayout.WEST); - // TODO: use relative size - only! - JLabel transactionHeadingLabel = new JLabel( - "
Transactions:"); - tempPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 1, 1)); - transactionHeadingLabel.setFont(new Font("Helvetica", Font.BOLD, 19)); - tempPanel.add(transactionHeadingLabel); - balanceStatusPanel.add(tempPanel, BorderLayout.CENTER); - - PresentationPanel walletBalancePanel = new PresentationPanel(); - walletBalancePanel.add(walletBalanceLabel = new JLabel()); - balanceStatusPanel.add(walletBalancePanel, BorderLayout.EAST); - - dashboard.add(balanceStatusPanel, BorderLayout.NORTH); + tempPanel.setToolTipText(langUtil.getString("panel.dashboard.tooltip")); + upperLogoAndWarningPanel.add(tempPanel, BorderLayout.WEST); + dashboard.add(upperLogoAndWarningPanel, BorderLayout.NORTH); - // Table of transactions - lastTransactionsData = getTransactionsDataFromWallet(); - dashboard.add(transactionsTablePane = new JScrollPane( - transactionsTable = this.createTransactionsTable(lastTransactionsData)), - BorderLayout.CENTER); + JPanel roundedLeftPanel = new JPanel(); + roundedLeftPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 12, 0)); + JPanel leftInsidePanel = new JPanel(); + leftInsidePanel.setLayout(new BorderLayout(8, 8)); + leftInsidePanel.add(walletBalanceLabel = new JLabel(), BorderLayout.NORTH); + roundedLeftPanel.add(leftInsidePanel); + tempPanel = new JPanel(new BorderLayout(0, 0)); + tempPanel.add(roundedLeftPanel, BorderLayout.NORTH); + tempPanel.add(this.exchangeRatePanel = new ExchangeRatePanel(errorReporter), BorderLayout.CENTER); + dashboard.add(tempPanel, BorderLayout.WEST); + + // List of transactions + tempPanel = new JPanel(new BorderLayout(0, 0)); + tempPanel.setBorder(BorderFactory.createEmptyBorder(0, 14, 8, 4)); + tempPanel.add(new LatestTransactionsPanel(), BorderLayout.CENTER); + dashboard.add(tempPanel, BorderLayout.CENTER); // Lower panel with installation status JPanel installationStatusPanel = new JPanel(); installationStatusPanel.setLayout(new BorderLayout(3, 3)); - //installationStatusPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); PresentationPanel daemonStatusPanel = new PresentationPanel(); daemonStatusPanel.add(daemonStatusLabel = new JLabel()); installationStatusPanel.add(daemonStatusPanel, BorderLayout.WEST); + // Build the network and blockchain labels - could be better! + JPanel netandBCPanel = new JPanel(new BorderLayout(0, 0)); + netandBCPanel.setOpaque(false); + netandBCPanel.add(networkAndBlockchainLabel = new JLabel(), BorderLayout.CENTER); + JPanel netandBCIconsPanel = new JPanel(new BorderLayout(0, 0)); + netandBCIconsPanel.setOpaque(false); + this.blockchain100PercentLabel = new JLabel(" "); + netandBCIconsPanel.add(this.blockchain100PercentLabel, BorderLayout.NORTH); + this.networkConnectionsIconLabel = new JLabel(" "); + this.networkConnectionsIconLabel.setIcon(this.connect_0_Icon); + netandBCIconsPanel.add(this.networkConnectionsIconLabel, BorderLayout.SOUTH); + netandBCPanel.add(netandBCIconsPanel, BorderLayout.EAST); PresentationPanel networkAndBlockchainPanel = new PresentationPanel(); - networkAndBlockchainPanel.add(networkAndBlockchainLabel = new JLabel()); + networkAndBlockchainPanel.add(netandBCPanel); installationStatusPanel.add(networkAndBlockchainPanel, BorderLayout.EAST); dashboard.add(installationStatusPanel, BorderLayout.SOUTH); @@ -253,7 +330,7 @@ public String[][] gatherData() throws Exception { long start = System.currentTimeMillis(); - String[][] data = DashboardPanel.this.getTransactionsDataFromWallet(); + String[][] data = DashboardPanel.this.getTransactionsDataFromWallet(); long end = System.currentTimeMillis(); Log.info("Gathering of dashboard wallet transactions table data done in " + (end - start) + "ms." ); @@ -263,24 +340,6 @@ public String[][] gatherData() this.errorReporter, 20000); this.threads.add(this.transactionGatheringThread); - ActionListener alTransactions = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) - { - try - { - DashboardPanel.this.updateWalletTransactionsTable(); - } catch (Exception ex) - { - Log.error("Unexpected error: ", ex); - DashboardPanel.this.errorReporter.reportError(ex); - } - } - }; - t = new Timer(5000, alTransactions); - t.start(); - this.timers.add(t); - // Thread and timer to update the network and blockchain details this.netInfoGatheringThread = new DataGatheringThread( new DataGatheringThread.DataGatherer() @@ -320,15 +379,27 @@ public void actionPerformed(ActionEvent e) } + public void setDetailsPanelForSelection(TransactionsDetailPanel detailsPanel) + { + this.detailsPabelForSelection = detailsPanel; + } + + // May be null! public Integer getBlockchainPercentage() { return this.blockchainPercentage; } + + public DataGatheringThread getTransactionGatheringThread() + { + return this.transactionGatheringThread; + } + private void updateDaemonStatusLabel() - throws IOException, InterruptedException, WalletCallException + throws IOException, InterruptedException, WalletCallException, URISyntaxException { DaemonInfo daemonInfo = this.daemonInfoGatheringThread.getLastData(); @@ -338,10 +409,10 @@ private void updateDaemonStatusLabel() return; } - String daemonStatus = "RUNNING"; + String daemonStatus = langUtil.getString("panel.dashboard.deamon.status.running"); if (daemonInfo.status != DAEMON_STATUS.RUNNING) { - daemonStatus = "NOT RUNNING"; + daemonStatus = langUtil.getString("panel.dashboard.deamon.status.not.running"); } String runtimeInfo = ""; @@ -350,20 +421,19 @@ private void updateDaemonStatusLabel() String virtual = ""; if (daemonInfo.virtualSizeMB > 0) { - virtual = ", Virtual: " + daemonInfo.virtualSizeMB + " MB"; + virtual = langUtil.getString("panel.dashboard.deamon.info.virtual", daemonInfo.virtualSizeMB); } String cpuPercentage = ""; if (daemonInfo.cpuPercentage > 0) { - cpuPercentage = ", CPU: " + daemonInfo.cpuPercentage + "%"; + cpuPercentage = langUtil.getString("panel.dashboard.deamon.info.cpu", daemonInfo.cpuPercentage); } if (daemonInfo.status == DAEMON_STATUS.RUNNING) { - runtimeInfo = "" + - "Resident: " + daemonInfo.residentSizeMB + " MB" + virtual + - cpuPercentage + ""; + runtimeInfo = langUtil.getString("panel.dashboard.deamon.runtime.info", + daemonInfo.residentSizeMB, virtual, cpuPercentage); } // TODO: what if ZCash directory is non-default... @@ -382,22 +452,20 @@ private void updateDaemonStatusLabel() // TODO: Use a one-off data gathering thread - better design if (this.walletIsEncrypted != null) { - walletEncryption = - "" + - " (" + (this.walletIsEncrypted ? "" : "not ") + "encrypted)" + - ""; + String encryptionText = + (this.walletIsEncrypted ? "" : + langUtil.getString("panel.dashboard.deamon.status.not")) + + langUtil.getString("panel.dashboard.deamon.status.encrypted"); + + walletEncryption =langUtil.getString("panel.dashboard.deamon.status.walletencrypted.text", encryptionText); + } - String text = - "zend status: " + - daemonStatus + ", " + runtimeInfo + "
" + - "Wallet: " + walletDAT.getCanonicalPath() + "" + - walletEncryption + "
" + - "
" + - "" + - "Installation: " + OSUtil.getProgramDirectory() + ", " + - "Blockchain: " + OSUtil.getBlockchainDirectory() + "
" + - "System: " + this.OSInfo + "
"; + String text =langUtil.getString("panel.dashboard.deamon.status.text", + daemonStatus, runtimeInfo, walletDAT.getCanonicalPath(), + walletEncryption, OSUtil.getProgramDirectory(), OSUtil.getBlockchainDirectory(), + this.OSInfo); + this.daemonStatusLabel.setText(text); } @@ -421,7 +489,7 @@ private void updateNetworkAndBlockchainLabel() long remainingTime = nowDate.getTime() - info.lastBlockDate.getTime(); String percentage = "100"; - if (remainingTime > 20 * 60 * 1000) // After 20 min we report 100% anyway + if (remainingTime > 30 * 60 * 1000) // After 30 min we report 100% anyway { double dPercentage = 100d - (((double)remainingTime / (double) fullTime) * 100d); if (dPercentage < 0) @@ -448,50 +516,84 @@ private void updateNetworkAndBlockchainLabel() // TODO: write log that we fix minimum date! - this condition should not occur info.lastBlockDate = startDate; } + + String text =langUtil.getString("panel.dashboard.network.blockchain.label", + percentage, info.lastBlockDate.toLocaleString(), info.numConnections ); + + this.networkAndBlockchainLabel.setText(text); - String connections = " \u26D7"; - String tickSymbol = " \u2705"; - OS_TYPE os = OSUtil.getOSType(); - // Handling special symbols on Mac OS/Windows - // TODO: isolate OS-specific symbol stuff in separate code - if ((os == OS_TYPE.MAC_OS) || (os == OS_TYPE.WINDOWS)) + // Connections check (typically not an open node with more than 8) + int numConnections = info.numConnections; + if (numConnections > 8) { - connections = " \u21D4"; - tickSymbol = " \u2606"; + numConnections = 8; } - String tick = ""; - if (percentage.equals("100")) + // Set the correct number of connections (icon) + switch (numConnections) { - tick = "" + tickSymbol + ""; + case 8: + case 7: + this.networkConnectionsIconLabel.setIcon(connect_4_Icon); + break; + case 6: + case 5: + this.networkConnectionsIconLabel.setIcon(connect_3_Icon); + break; + case 4: + case 3: + this.networkConnectionsIconLabel.setIcon(connect_2_Icon); + break; + case 2: + case 1: + this.networkConnectionsIconLabel.setIcon(connect_1_Icon); + break; + case 0: + default: + this.networkConnectionsIconLabel.setIcon(connect_0_Icon); } - String netColor = "red"; - if (info.numConnections > 0) + // Set the blockchain synchronization icon + if (this.blockchainPercentage < 100) + { + this.blockchain100PercentLabel.setIcon(null); + } else { - netColor = "#cc3300"; + this.blockchain100PercentLabel.setIcon(this.confirmedTXIcon); } - if (info.numConnections > 2) + // Possibly show a blockchain synchronization warning + if (this.blockchainPercentage < 100) { - netColor = "black"; - } - - if (info.numConnections > 6) + String warningText = langUtil.getString("panel.dashboard.synchronisation.warning", + info.lastBlockDate.toLocaleString()); + + if (this.blockcahinWarningPanel == null) + { + // Create a new warning panel + JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + PresentationPanel warningPanel = new PresentationPanel(); + this.blockcahinWarningLabel = new JLabel(warningText); + warningPanel.add(this.blockcahinWarningLabel); + tempPanel.add(warningPanel); + this.blockcahinWarningPanel = tempPanel; + this.upperLogoAndWarningPanel.add(this.blockcahinWarningPanel, BorderLayout.EAST); + } else if (this.blockcahinWarningLabel != null) + { + this.blockcahinWarningLabel.setText(warningText); + } + } else { - netColor = "green"; - } - - String text = - " " + - "Blockchain synchronized: " + - percentage + "% " + tick + "
" + - "Up to: " + - info.lastBlockDate.toLocaleString() + "
" + - "
" + - "Network: " + info.numConnections + " connections" + - "" + connections + ""; - this.networkAndBlockchainLabel.setText(text); + if (this.blockcahinWarningPanel != null) + { + this.upperLogoAndWarningPanel.remove(this.blockcahinWarningPanel); + this.upperLogoAndWarningPanel.revalidate(); + this.upperLogoAndWarningPanel.repaint(); + this.revalidate(); // The entire dashboard panel + this.blockcahinWarningPanel = null; + this.blockcahinWarningLabel = null; + } + } } @@ -521,31 +623,43 @@ private void updateWalletStatusLabel() String color2 = privateBalance.equals(privateUCBalance) ? "" : "color:#cc3300;"; String color3 = totalBalance.equals(totalUCBalance) ? "" : "color:#cc3300;"; - String text = - "" + - "Transparent balance: " + - transparentUCBalance + " ZEN
" + - "Private (Z) balance: " + - privateUCBalance + " ZEN
" + - "Total (Z+T) balance: " + - totalUCBalance + " ZEN " + - "
"; + Double usdBalance = (this.exchangeRatePanel != null) ? this.exchangeRatePanel.getUsdPrice() : null; + String usdBalanceStr = ""; + if (usdBalance != null) + { + usdBalance = usdBalance * balance.totalUnconfirmedBalance; + DecimalFormat usdDF = new DecimalFormat("########0.00"); + String formattedUSDVal = usdDF.format(usdBalance); + + // make sure ZEN and USD are aligned + int diff = totalUCBalance.length() - formattedUSDVal.length(); + while (diff-- > 0) + { + formattedUSDVal += " "; + } + + // TODO: Remove + //System.out.println("formattedUSDVal = [" + formattedUSDVal + "]"); + usdBalanceStr = langUtil.getString("panel.dashboard.marketcap.usd.balance.string", color3, formattedUSDVal); + } + + String text = langUtil.getString("panel.dashboard.marketcap.usd.balance.text", + color1, transparentUCBalance, color2, privateUCBalance, + color3, totalUCBalance, usdBalanceStr); + + // TODO: Remove + //System.out.println("totalUCBalance = [" + totalUCBalance + "]"); + //System.out.println("usdBalanceStr = [" + usdBalanceStr + "]"); + //System.out.println("FULL TEXT: " + text); this.walletBalanceLabel.setText(text); - + String toolTip = null; if ((!transparentBalance.equals(transparentUCBalance)) || (!privateBalance.equals(privateUCBalance)) || (!totalBalance.equals(totalUCBalance))) { - toolTip = "" + - "Unconfirmed (unspendable) balance is being shown due to an
" + - "ongoing transaction! Actual confirmed (spendable) balance is:
" + - "
" + - "Transparent: " + transparentBalance + " ZEN
" + - "Private ( Z ): " + privateBalance + " ZEN
" + - "Total ( Z+T ): " + totalBalance + " ZEN" + - ""; + toolTip = langUtil.getString("panel.dashboard.balance.tooltip", transparentBalance, privateBalance, totalBalance); } this.walletBalanceLabel.setToolTipText(toolTip); @@ -555,52 +669,7 @@ private void updateWalletStatusLabel() this.backupTracker.handleWalletBalanceUpdate(balance.totalBalance); } } - - - private void updateWalletTransactionsTable() - throws WalletCallException, IOException, InterruptedException - { - String[][] newTransactionsData = this.transactionGatheringThread.getLastData(); - - // May be null - not even gathered once - if (newTransactionsData == null) - { - return; - } - - if (Util.arraysAreDifferent(lastTransactionsData, newTransactionsData)) - { - Log.info("Updating table of transactions..."); - this.remove(transactionsTablePane); - this.add(transactionsTablePane = new JScrollPane( - transactionsTable = this.createTransactionsTable(newTransactionsData)), - BorderLayout.CENTER); - } - - lastTransactionsData = newTransactionsData; - - this.validate(); - this.repaint(); - } - - - private JTable createTransactionsTable(String rowData[][]) - throws WalletCallException, IOException, InterruptedException - { - String columnNames[] = { "Type", "Direction", "Confirmed?", "Amount", "Date", "Destination Address"}; - JTable table = new TransactionTable( - rowData, columnNames, this.parentFrame, this.clientCaller, this.installationObserver); - table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); - table.getColumnModel().getColumn(0).setPreferredWidth(190); - table.getColumnModel().getColumn(1).setPreferredWidth(145); - table.getColumnModel().getColumn(2).setPreferredWidth(170); - table.getColumnModel().getColumn(3).setPreferredWidth(210); - table.getColumnModel().getColumn(4).setPreferredWidth(405); - table.getColumnModel().getColumn(5).setPreferredWidth(800); - - return table; - } - + private String[][] getTransactionsDataFromWallet() throws WalletCallException, IOException, InterruptedException @@ -628,13 +697,13 @@ private String[][] getTransactionsDataFromWallet() public int compare(String[] o1, String[] o2) { Date d1 = new Date(0); - if (!o1[4].equals("N/A")) + if ((!o1[4].equals("N/A")) && (Util.isNumeric(o1[4]))) { d1 = new Date(Long.valueOf(o1[4]).longValue() * 1000L); } Date d2 = new Date(0); - if (!o2[4].equals("N/A")) + if (!o2[4].equals("N/A") && Util.isNumeric(o2[4])) { d2 = new Date(Long.valueOf(o2[4]).longValue() * 1000L); } @@ -649,20 +718,6 @@ public int compare(String[] o1, String[] o2) } }); - - // Confirmation symbols - String confirmed = "\u2690"; - String notConfirmed = "\u2691"; - - // Windows does not support the flag symbol (Windows 7 by default) - // TODO: isolate OS-specific symbol codes in a separate class - OS_TYPE os = OSUtil.getOSType(); - if (os == OS_TYPE.WINDOWS) - { - confirmed = " \u25B7"; - notConfirmed = " \u25B6"; - } - DecimalFormat df = new DecimalFormat("########0.00######"); // Change the direction and date etc. attributes for presentation purposes @@ -684,7 +739,7 @@ public int compare(String[] o1, String[] o2) }; // Date - if (!trans[4].equals("N/A")) + if ((!trans[4].equals("N/A")) && Util.isNumeric(trans[4])) { trans[4] = new Date(Long.valueOf(trans[4]).longValue() * 1000L).toLocaleString(); } @@ -709,7 +764,9 @@ public int compare(String[] o1, String[] o2) { boolean isConfirmed = !trans[2].trim().equals("0"); - trans[2] = isConfirmed ? ("Yes " + confirmed) : ("No " + notConfirmed); + trans[2] = isConfirmed ? + (langUtil.getString("panel.dashboard.table.transactions.confirmed.yes") + confirmedSymbol) : + (langUtil.getString("panel.dashboard.table.transactions.confirmed.no") + notConfirmedSymbol); } catch (NumberFormatException nfe) { Log.error("Error occurred while formatting confirmations: " + trans[2] + @@ -721,4 +778,362 @@ public int compare(String[] o1, String[] o2) return allTransactions; } + + // Specific panel class for showing the exchange rates and values in FIAT + class ExchangeRatePanel + extends JPanel + { + private DataGatheringThread zenDataGatheringThread = null; + + private DataTable table; + private JScrollPane tablePane; + + private Double lastUsdPrice; + + public ExchangeRatePanel(StatusUpdateErrorReporter errorReporter) + { + // Start the thread to gather the exchange data + this.zenDataGatheringThread = new DataGatheringThread( + new DataGatheringThread.DataGatherer() + { + public JsonObject gatherData() + throws Exception + { + long start = System.currentTimeMillis(); + JsonObject exchangeData = ExchangeRatePanel.this.getExchangeDataFromRemoteService(); + long end = System.currentTimeMillis(); + Log.info("Gathering of ZEN Exchange data done in " + (end - start) + "ms." ); + + return exchangeData; + } + }, + errorReporter, 60000, true); + + this.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 18)); + this.recreateExchangeTable(); + + // Start the timer to update the table + ActionListener alExchange = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) + { + try + { + ExchangeRatePanel.this.recreateExchangeTable(); + } catch (Exception ex) + { + Log.error("Unexpected error: ", ex); + DashboardPanel.this.errorReporter.reportError(ex); + } + } + }; + Timer t = new Timer(30000, alExchange); // TODO: add timer for disposal ??? + t.setInitialDelay(1000); + t.start(); + } + + + private void recreateExchangeTable() + { + if (this.table != null) + { + this.remove(this.tablePane); + } + + this.table = new DataTable(getExchangeDataInTableForm(), + new String[] { + langUtil.getString("panel.dashboard.marketcap.column.exchange.info"), + langUtil.getString("panel.dashboard.marketcap.column.exchange.value") + }); + Dimension d = this.table.getPreferredSize(); + d.setSize((d.getWidth() * 26) / 10, d.getHeight()); // TODO: better sizing + this.table.setPreferredScrollableViewportSize(d); + this.table.setFillsViewportHeight(false); + this.add(this.tablePane = new JScrollPane(this.table)); + } + + + // Forms the exchange data for a table + private Object[][] getExchangeDataInTableForm() + { + // sample data + // { + // "usd": 5.48, + // "btc": "0.00056185", + // "24h": -0.35, + // "7d": 1.06, + // "cap": 49858001.8, + // "date": "2020-05-20T07:58:59" + // } + JsonObject data = this.zenDataGatheringThread.getLastData(); + if (data == null) + { + data = new JsonObject(); + } + + String usdPrice = "N/A"; + Double usdPriceD = data.getDouble("usd", 0); + if (usdPriceD != 0) + { + usdPrice = new DecimalFormat("###,###,###,##0.00").format(usdPriceD); + this.lastUsdPrice = usdPriceD; + } + + Double usdMarketCapD = data.getDouble("cap", 0); + String usdMarketCap = (usdMarketCapD != 0) ? new DecimalFormat("###,###,###,##0.00").format(usdMarketCapD) : "N/A"; + Double dailyChangeD = data.getDouble("24h", 0); + String dailyChange = (dailyChangeD != 0) ? new DecimalFormat("###0.00").format(dailyChangeD) : "N/A"; + Double weeklyChangeD = data.getDouble("7d", 0); + String weeklyChange = (weeklyChangeD != 0) ? new DecimalFormat("###0.00").format(weeklyChangeD) : "N/A"; + + // Query the object for individual fields + String tableData[][] = new String[][] + { + { langUtil.getString("panel.dashboard.marketcap.price.usd"), usdPrice }, + { langUtil.getString("panel.dashboard.marketcap.price.btc"), data.getString("btc", "N/A") }, + { langUtil.getString("panel.dashboard.marketcap.capitalisation"), usdMarketCap }, + { langUtil.getString("panel.dashboard.marketcap.daily.change"), dailyChange + "%" }, + { langUtil.getString("panel.dashboard.marketcap.weekly.change"), weeklyChange + "%" }, + }; + + return tableData; + } + + + private Double getUsdPrice() + { + return this.lastUsdPrice; + } + + + // Obtains the ZEN exchange data as a JsonObject + private JsonObject getExchangeDataFromRemoteService() + { + JsonObject data = new JsonObject(); + + try + { + //switched from deprecated CMC api to our own price api service + URL u = new URL("https://papi.zenchain.info/api/v1/flagship/overview"); + URLConnection uc = u.openConnection(); + uc.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HorizenSwingWallet Chrome/69.0.3497.128 Safari/537.36"); + Reader r = new InputStreamReader(uc.getInputStream(), "UTF-8"); + data = Json.parse(r).asObject().get("data").asObject().get("market").asObject(); + r.close(); + } catch (Exception ioe) + { + Log.warning("Could not obtain ZEN exchange information from price api due to: {0} {1}", + ioe.getClass().getName(), ioe.getMessage()); + } + + return data; + } + } + + + // Specific panel class for the latest transactions + class LatestTransactionsPanel + extends JPanel + { + LatestTransactionsList transactionList = null; + String[][] transactions = null; + + public LatestTransactionsPanel() + throws InterruptedException, IOException, WalletCallException + { + final JPanel content = new JPanel(); + content.setLayout(new BorderLayout(3, 3)); + content.add(new JLabel(langUtil.getString("panel.dashboard.transactions.label")), + BorderLayout.NORTH); + transactionList = new LatestTransactionsList(); + JPanel tempPanel = new JPanel(new BorderLayout(0, 0)); + tempPanel.add(transactionList, BorderLayout.NORTH); + content.add(tempPanel, BorderLayout.CENTER); + + // Pre-fill transaction list once + this.transactions = getTransactionsDataFromWallet(); + transactionList.updateTransactions(this.transactions); + + ActionListener al = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + LatestTransactionsPanel.this.transactions = transactionGatheringThread.getLastData(); + if (LatestTransactionsPanel.this.transactions != null) + { + transactionList.updateTransactions(LatestTransactionsPanel.this.transactions); + } + } + }; + + Timer latestTransactionsTimer = new Timer(8000, al); + latestTransactionsTimer.setInitialDelay(8000); + latestTransactionsTimer.start(); + + this.setLayout(new GridLayout(1, 1)); + this.add(content); + } + + + class LatestTransactionsList + extends JList + { + public LatestTransactionsList() + { + super(); + this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + this.setBackground(new JPanel().getBackground()); + + this.addMouseListener(new MouseAdapter() + { + public void mousePressed(MouseEvent e) + { + if ((!e.isConsumed()) && (e.isPopupTrigger() || (e.getClickCount() == 2))) + { + LatestTransactionsList list = (LatestTransactionsList)e.getSource(); + + // Select also via the right mouse button - seems not to work well + /*{ + if (SwingUtilities.isRightMouseButton(e)) + { + int row = list.locationToIndex(e.getPoint()); + if (row > 0) + { + list.setSelectedIndex(row); + } + } + }*/ + + if (list.getSelectedValue() != null) + { + String[] transaction = list.getSelectedValue(); + // Select the right transaction here + if (detailsPabelForSelection != null) + { + detailsPabelForSelection.selectTransactionWithID(transaction[6]); + } + e.consume(); + } + } + } + + public void mouseReleased(MouseEvent e) + { + if ((!e.isConsumed()) && e.isPopupTrigger()) + { + mousePressed(e); + } + } + }); + } + + + public void updateTransactions(String[][] transactions) + { + DefaultListModel model = new DefaultListModel(); + + // By default only 5 transactions are shown + int i = 0; + for (String[] trans : transactions) + { + if (++i > 5) + { + break; + } + + model.addElement(trans); + } + + this.setModel(model); + } + + + @Override + public ListCellRenderer getCellRenderer() + { + return new ListCellRenderer() + { + @Override + public Component getListCellRendererComponent( + JList list, + String[] data, int index, boolean isSelected, boolean cellHasFocus) + { + return new SingleTransactionPanel(data); + } + }; + } + + } + + + class SingleTransactionPanel + extends JPanel + { + // TODO: depends on the format of the gathering thread + public SingleTransactionPanel(String[] transactionFields) + { + this.setLayout(new FlowLayout(FlowLayout.LEFT, 3, 3)); + this.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); + + String destinationAddress = transactionFields[5]; + + String label = DashboardPanel.this.labelStorage.getLabel(destinationAddress); + if ((label != null) && (label.length() > 0)) + { + destinationAddress = label + " - " + destinationAddress; + } + + if (destinationAddress.length() > 37) + { + destinationAddress = destinationAddress.substring(0, 37) + "..."; + } + + // Set the correct icon for input/output + ImageIcon inOutIcon = inoutTransactionIcon; + if (transactionFields[1] != null) + { + if (transactionFields[1].contains("IN")) + { + inOutIcon = inputTransactionIcon; + } else if (transactionFields[1].contains("OUT")) + { + inOutIcon = outputTransactionIcon; + } + } + + JLabel imgLabel = new JLabel(); + imgLabel.setIcon(inOutIcon); + this.add(imgLabel); + + // Set the two icons for public/private and confirmations + ImageIcon confirmationIcon = + transactionFields[2].contains((langUtil.getString("panel.dashboard.table.transactions.confirmed.yes"))) + ? confirmedTXIcon : unConfirmedTXIcon; + ImageIcon pubPrivIcon = + transactionFields[0].contains("Private") ? lockClosedIcon : lockOpenIcon; + JPanel iconsPanel = new JPanel(new BorderLayout(0, 1)); + iconsPanel.add(new JLabel(pubPrivIcon), BorderLayout.SOUTH); + iconsPanel.add(new JLabel(confirmationIcon), BorderLayout.NORTH); + this.add(iconsPanel); + + this.add(new JLabel(" ")); + + // Set the transaction information + JLabel transactionInfo = new JLabel( + langUtil.getString("panel.dashboard.transactions.info", + transactionFields[0], + transactionFields[1], + transactionFields[2], + transactionFields[3], + transactionFields[4], + destinationAddress + ) + ); + this.add(transactionInfo); + } + } + } + + } // End class diff --git a/src/java/com/vaklinov/zcashui/DataGatheringThread.java b/src/java/com/vaklinov/zcashui/DataGatheringThread.java index 4a003560..683952a7 100644 --- a/src/java/com/vaklinov/zcashui/DataGatheringThread.java +++ b/src/java/com/vaklinov/zcashui/DataGatheringThread.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,8 +37,6 @@ * quickly since it is stored in the thread. * * @param the type of data that is gathered. - * - * @author Ivan Vaklinov */ public class DataGatheringThread extends Thread diff --git a/src/java/com/vaklinov/zcashui/DataTable.java b/src/java/com/vaklinov/zcashui/DataTable.java index 9c52dee8..ab5d732b 100644 --- a/src/java/com/vaklinov/zcashui/DataTable.java +++ b/src/java/com/vaklinov/zcashui/DataTable.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -57,8 +58,6 @@ /** * Table to be used for transactions, addresses etc. - * - * @author Ivan Vaklinov */ public class DataTable extends JTable @@ -67,6 +66,8 @@ public class DataTable protected int lastColumn = -1; protected JPopupMenu popupMenu; + + private LanguageUtil langUtil = LanguageUtil.instance(); public DataTable(final Object[][] rowData, final Object[] columnNames) { @@ -80,7 +81,7 @@ public DataTable(final Object[][] rowData, final Object[] columnNames) popupMenu = new JPopupMenu(); int accelaratorKeyMask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask(); - JMenuItem copy = new JMenuItem("Copy value"); + JMenuItem copy = new JMenuItem(langUtil.getString("data.table.menu.item.copy")); popupMenu.add(copy); copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, accelaratorKeyMask)); copy.addActionListener(new ActionListener() @@ -102,7 +103,7 @@ public void actionPerformed(ActionEvent e) }); - JMenuItem exportToCSV = new JMenuItem("Export data to CSV..."); + JMenuItem exportToCSV = new JMenuItem(langUtil.getString("data.table.menu.item.export")); popupMenu.add(exportToCSV); exportToCSV.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, accelaratorKeyMask)); exportToCSV.addActionListener(new ActionListener() @@ -119,10 +120,9 @@ public void actionPerformed(ActionEvent e) // TODO: better error handling JOptionPane.showMessageDialog( DataTable.this.getRootPane().getParent(), - "An unexpected error occurred when exporting data to CSV file.\n" + - "\n" + - ex.getMessage(), - "Error in CSV export", JOptionPane.ERROR_MESSAGE); + langUtil.getString("data.table.option.pane.export.error.text", + ex.getMessage()), + langUtil.getString("data.table.option.pane.export.error.title"), JOptionPane.ERROR_MESSAGE); } } }); @@ -192,7 +192,7 @@ private void exportToCSV() final String ENCODING = "UTF-8"; JFileChooser fileChooser = new JFileChooser(); - fileChooser.setDialogTitle("Export data to CSV file..."); + fileChooser.setDialogTitle(langUtil.getString("data.table.file.chooser.export.dialog.title")); fileChooser.setFileFilter(new FileNameExtensionFilter("CSV Files (*.csv)", "csv")); int result = fileChooser.showSaveDialog(this.getRootPane().getParent()); @@ -228,7 +228,17 @@ private void exportToCSV() StringBuilder rowBuf = new StringBuilder(); for (int col = 0; col < this.getColumnCount(); col++) { - rowBuf.append(this.getValueAt(row, col).toString()); + String currentValue = this.getValueAt(row, col).toString(); + // Make sure the field is escaped if it has commas + if (currentValue.contains(",") || currentValue.contains("\"")) + { + if (currentValue.contains("\"")) + { + currentValue = currentValue.replace("\"", "\"\""); + } + currentValue = "\"" + currentValue + "\""; + } + rowBuf.append(currentValue); if (col < (this.getColumnCount() - 1)) { @@ -243,8 +253,8 @@ private void exportToCSV() JOptionPane.showMessageDialog( this.getRootPane().getParent(), - "The data has been exported successfully as CSV to location:\n" + - f.getCanonicalPath(), - "Export successful...", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("data.table.option.pane.export.success.text", + f.getCanonicalPath()), + langUtil.getString("data.table.option.pane.export.success.title"), JOptionPane.INFORMATION_MESSAGE); } } diff --git a/src/java/com/vaklinov/zcashui/DropdownComboBox.java b/src/java/com/vaklinov/zcashui/DropdownComboBox.java new file mode 100644 index 00000000..c0171e01 --- /dev/null +++ b/src/java/com/vaklinov/zcashui/DropdownComboBox.java @@ -0,0 +1,83 @@ +/************************************************************************************************ + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **********************************************************************************/ +package com.vaklinov.zcashui; + +import javax.swing.JComboBox; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; + + +/** + * Combo Box that is aware of whether is is dropped down. + */ +public class DropdownComboBox + extends JComboBox +{ + protected boolean isMenuDown; + + public DropdownComboBox(E[] list) + { + super(list); + + this.isMenuDown = false; + this.initDownListener(); + } + + + public boolean isMenuDown() + { + return this.isMenuDown; + } + + + private void initDownListener() + { + this.addPopupMenuListener(new PopupMenuListener() + { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) + { + DropdownComboBox.this.isMenuDown = true; + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) + { + DropdownComboBox.this.isMenuDown = false; + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) + { + DropdownComboBox.this.isMenuDown = false; + } + }); + } +} diff --git a/src/java/com/vaklinov/zcashui/ZCashUI.java b/src/java/com/vaklinov/zcashui/HorizenUI.java similarity index 56% rename from src/java/com/vaklinov/zcashui/ZCashUI.java rename to src/java/com/vaklinov/zcashui/HorizenUI.java index 4b5d05ae..4f32da45 100644 --- a/src/java/com/vaklinov/zcashui/ZCashUI.java +++ b/src/java/com/vaklinov/zcashui/HorizenUI.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,20 +44,15 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.security.SecureRandom; import java.util.Date; +import java.util.Locale; import java.util.Random; -import javax.swing.ImageIcon; -import javax.swing.JFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JTabbedPane; -import javax.swing.KeyStroke; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; +import javax.swing.*; import javax.swing.UIManager.LookAndFeelInfo; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -71,11 +67,9 @@ /** - * Main ZENCash Window. - * - * @author Ivan Vaklinov + * Main Horizen Window. */ -public class ZCashUI +public class HorizenUI extends JFrame { private ZCashInstallationObserver installationObserver; @@ -100,23 +94,29 @@ public class ZCashUI private JMenuItem menuItemMessagingOptions; private JMenuItem menuItemShareFileViaIPFS; private JMenuItem menuItemExportToArizen; + private JMenuItem menuItemZendParameters; private DashboardPanel dashboard; + private TransactionsDetailPanel transactionDetailsPanel; private AddressesPanel addresses; private SendCashPanel sendPanel; private AddressBookPanel addressBookPanel; private MessagingPanel messagingPanel; - + private LanguageUtil langUtil; + JTabbedPane tabs; - public ZCashUI(StartupProgressDialog progressDialog) - throws IOException, InterruptedException, WalletCallException + public HorizenUI(StartupProgressDialog progressDialog) + throws IOException, InterruptedException, WalletCallException, URISyntaxException { - super("ZENCash Desktop GUI Wallet 0.76.3"); - + + langUtil = LanguageUtil.instance(); + + this.setTitle(langUtil.getString("main.frame.title")); + if (progressDialog != null) { - progressDialog.setProgressText("Starting GUI wallet..."); + progressDialog.setProgressText(langUtil.getString("main.frame.progressbar")); } ClassLoader cl = this.getClass().getClassLoader(); @@ -131,7 +131,7 @@ public ZCashUI(StartupProgressDialog progressDialog) if (installationObserver.isOnTestNet()) { - this.setTitle(this.getTitle() + " [using TESTNET]"); + this.setTitle(this.getTitle() + langUtil.getString("main.frame.title.testnet")); } // Build content @@ -140,98 +140,131 @@ public ZCashUI(StartupProgressDialog progressDialog) Font newTabFont = new Font(oldTabFont.getName(), Font.BOLD | Font.ITALIC, oldTabFont.getSize() * 57 / 50); tabs.setFont(newTabFont); BackupTracker backupTracker = new BackupTracker(this); - - tabs.addTab("Overview ", + LabelStorage labelStorage = new LabelStorage(); + tabs.addTab(langUtil.getString("main.frame.tab.overview.title"), new ImageIcon(cl.getResource("images/overview.png")), dashboard = new DashboardPanel(this, installationObserver, clientCaller, - errorReporter, backupTracker)); - tabs.addTab("Own addresses ", + errorReporter, backupTracker, labelStorage)); + tabs.addTab(langUtil.getString("main.frame.tab.transactions.title"), + new ImageIcon(cl.getResource("images/transactions.png")), + transactionDetailsPanel = new TransactionsDetailPanel( + this, tabs, installationObserver, clientCaller, + errorReporter, dashboard.getTransactionGatheringThread(), labelStorage)); + this.dashboard.setDetailsPanelForSelection(this.transactionDetailsPanel); + tabs.addTab(langUtil.getString("main.frame.tab.own.address.title"), new ImageIcon(cl.getResource("images/own-addresses.png")), - addresses = new AddressesPanel(this, clientCaller, errorReporter)); - tabs.addTab("Send cash ", + addresses = new AddressesPanel(this, clientCaller, errorReporter, labelStorage, installationObserver)); + tabs.addTab(langUtil.getString("main.frame.tab.send.cash.title"), new ImageIcon(cl.getResource("images/send.png")), - sendPanel = new SendCashPanel(clientCaller, errorReporter, installationObserver, backupTracker)); - tabs.addTab("Address book ", + sendPanel = new SendCashPanel(clientCaller, errorReporter, installationObserver, backupTracker, labelStorage)); + tabs.addTab(langUtil.getString("main.frame.tab.address.book.title"), new ImageIcon(cl.getResource("images/address-book.png")), - addressBookPanel = new AddressBookPanel(sendPanel, tabs)); - tabs.addTab("Messaging ", + addressBookPanel = new AddressBookPanel(sendPanel, tabs, labelStorage)); + tabs.addTab(langUtil.getString("main.frame.tab.messaging.title"), new ImageIcon(cl.getResource("images/messaging.png")), - messagingPanel = new MessagingPanel(this, sendPanel, tabs, clientCaller, errorReporter)); + messagingPanel = new MessagingPanel(this, sendPanel, tabs, clientCaller, errorReporter, labelStorage)); contentPane.add(tabs); this.walletOps = new WalletOperations( this, tabs, dashboard, addresses, sendPanel, - installationObserver, clientCaller, errorReporter, backupTracker); - - int width = 870; - - OS_TYPE os = OSUtil.getOSType(); - - // Window needs to be larger on Mac/Windows - typically - if ((os == OS_TYPE.WINDOWS) || (os == OS_TYPE.MAC_OS)) - { - width += 100; - } - - this.setSize(new Dimension(width, 440)); + installationObserver, clientCaller, errorReporter, backupTracker); // Build menu JMenuBar mb = new JMenuBar(); - JMenu file = new JMenu("Main"); + JMenu file = new JMenu(langUtil.getString("menu.label.main")); file.setMnemonic(KeyEvent.VK_M); int accelaratorKeyMask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMask(); - file.add(menuItemAbout = new JMenuItem("About...", KeyEvent.VK_T)); + file.add(menuItemAbout = new JMenuItem(langUtil.getString("menu.label.about"), KeyEvent.VK_T)); menuItemAbout.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, accelaratorKeyMask)); file.addSeparator(); - file.add(menuItemExit = new JMenuItem("Quit", KeyEvent.VK_Q)); + file.add(menuItemExit = new JMenuItem(langUtil.getString("menu.label.quit"), KeyEvent.VK_Q)); menuItemExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, accelaratorKeyMask)); mb.add(file); - JMenu wallet = new JMenu("Wallet"); + JMenu wallet = new JMenu(langUtil.getString("menu.label.wallet")); wallet.setMnemonic(KeyEvent.VK_W); - wallet.add(menuItemBackup = new JMenuItem("Backup...", KeyEvent.VK_B)); + wallet.add(menuItemBackup = new JMenuItem(langUtil.getString("menu.label.backup"), KeyEvent.VK_B)); menuItemBackup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, accelaratorKeyMask)); - wallet.add(menuItemEncrypt = new JMenuItem("Encrypt...", KeyEvent.VK_E)); - menuItemEncrypt.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, accelaratorKeyMask)); - wallet.add(menuItemExportKeys = new JMenuItem("Export private keys...", KeyEvent.VK_K)); + // Encryption menu item is hidden since encryption is not possible + //wallet.add(menuItemEncrypt = new JMenuItem(langUtil.getString("menu.label.encrypt"), KeyEvent.VK_E)); + //menuItemEncrypt.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, accelaratorKeyMask)); + wallet.add(menuItemExportKeys = new JMenuItem(langUtil.getString("menu.label.export.private.keys"), KeyEvent.VK_K)); menuItemExportKeys.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_K, accelaratorKeyMask)); - wallet.add(menuItemImportKeys = new JMenuItem("Import private keys...", KeyEvent.VK_I)); + wallet.add(menuItemImportKeys = new JMenuItem(langUtil.getString("menu.label.import.private.keys"), KeyEvent.VK_I)); menuItemImportKeys.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, accelaratorKeyMask)); - wallet.add(menuItemShowPrivateKey = new JMenuItem("Show private key...", KeyEvent.VK_P)); + wallet.add(menuItemShowPrivateKey = new JMenuItem(langUtil.getString("menu.label.show.private.key"), KeyEvent.VK_P)); menuItemShowPrivateKey.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, accelaratorKeyMask)); - wallet.add(menuItemImportOnePrivateKey = new JMenuItem("Import one private key...", KeyEvent.VK_N)); + wallet.add(menuItemImportOnePrivateKey = new JMenuItem(langUtil.getString("menu.label.import.one.private.key"), KeyEvent.VK_N)); menuItemImportOnePrivateKey.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, accelaratorKeyMask)); - wallet.add(menuItemExportToArizen = new JMenuItem("Export to Arizen wallet...", KeyEvent.VK_A)); + wallet.add(menuItemExportToArizen = new JMenuItem(langUtil.getString("menu.label.export.to.arizen"), KeyEvent.VK_A)); menuItemExportToArizen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, accelaratorKeyMask)); + wallet.add(menuItemZendParameters = new JMenuItem(langUtil.getString("wallet.menu.edit.zend.params"), KeyEvent.VK_Z)); + menuItemZendParameters.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, accelaratorKeyMask)); mb.add(wallet); - JMenu messaging = new JMenu("Messaging"); + JMenu messaging = new JMenu(langUtil.getString("menu.label.messaging")); messaging.setMnemonic(KeyEvent.VK_S); - messaging.add(menuItemOwnIdentity = new JMenuItem("Own identity...", KeyEvent.VK_D)); + messaging.add(menuItemOwnIdentity = new JMenuItem(langUtil.getString("menu.label.own.identity"), KeyEvent.VK_D)); menuItemOwnIdentity.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D, accelaratorKeyMask)); - messaging.add(menuItemExportOwnIdentity = new JMenuItem("Export own identity...", KeyEvent.VK_X)); + messaging.add(menuItemExportOwnIdentity = new JMenuItem(langUtil.getString("menu.label.export.own.identity"), KeyEvent.VK_X)); menuItemExportOwnIdentity.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, accelaratorKeyMask)); - messaging.add(menuItemAddMessagingGroup = new JMenuItem("Add messaging group...", KeyEvent.VK_G)); + messaging.add(menuItemAddMessagingGroup = new JMenuItem(langUtil.getString("menu.label.add.messaging.group"), KeyEvent.VK_G)); menuItemAddMessagingGroup.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, accelaratorKeyMask)); - messaging.add(menuItemImportContactIdentity = new JMenuItem("Import contact identity...", KeyEvent.VK_Y)); + messaging.add(menuItemImportContactIdentity = new JMenuItem(langUtil.getString("menu.label.import.contact.identity"), KeyEvent.VK_Y)); menuItemImportContactIdentity.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, accelaratorKeyMask)); - messaging.add(menuItemRemoveContactIdentity = new JMenuItem("Remove contact...", KeyEvent.VK_R)); + messaging.add(menuItemRemoveContactIdentity = new JMenuItem(langUtil.getString("menu.label.remove.contact"), KeyEvent.VK_R)); menuItemRemoveContactIdentity.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, accelaratorKeyMask)); - messaging.add(menuItemMessagingOptions = new JMenuItem("Options...", KeyEvent.VK_O)); + messaging.add(menuItemMessagingOptions = new JMenuItem(langUtil.getString("menu.label.options"), KeyEvent.VK_O)); menuItemMessagingOptions.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, accelaratorKeyMask)); - JMenu shareFileVia = new JMenu("Share file via:"); + JMenu shareFileVia = new JMenu(langUtil.getString("menu.label.share.file")); shareFileVia.setMnemonic(KeyEvent.VK_V); // TODO: uncomment this for IPFS integration //messaging.add(shareFileVia); - shareFileVia.add(menuItemShareFileViaIPFS = new JMenuItem("IPFS", KeyEvent.VK_F)); + shareFileVia.add(menuItemShareFileViaIPFS = new JMenuItem(langUtil.getString("menu.label.ipfs"), KeyEvent.VK_F)); menuItemShareFileViaIPFS.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F, accelaratorKeyMask)); mb.add(messaging); - // TODO: Temporarily disable encryption until further notice - Oct 24 2016 - menuItemEncrypt.setEnabled(false); - + ActionListener languageSelectionAction = new ActionListener( ) { + public void actionPerformed(ActionEvent e) { + try { + Log.info("Action ["+e.getActionCommand( )+"] performed"); + LanguageMenuItem item = (LanguageMenuItem) e.getSource(); + langUtil.updatePreferredLanguage(item.getLocale()); + JOptionPane.showMessageDialog( + HorizenUI.this.getRootPane().getParent(), + langUtil.getString("dialog.message.language.prefs.update"), + langUtil.getString("dialog.message.language.prefs.update.title"), + JOptionPane.INFORMATION_MESSAGE); + } catch (Exception ex) { ex.printStackTrace( ); } + } + }; + JMenu languageMenu = new JMenu(langUtil.getString("menu.label.language")); + LanguageMenuItem italian = new + LanguageMenuItem(langUtil.getString("menu.label.language.italian"), + new ImageIcon(cl.getResource("images/italian.png")), Locale.ITALY); + italian.setHorizontalTextPosition(JMenuItem.RIGHT); + + italian.addActionListener(languageSelectionAction); + + + LanguageMenuItem english = new + LanguageMenuItem(langUtil.getString("menu.label.language.english"), + new ImageIcon(cl.getResource("images/uk.png")), Locale.US); + english.setHorizontalTextPosition(JMenuItem.RIGHT); + + english.addActionListener(languageSelectionAction); + + ButtonGroup group = new ButtonGroup( ); + group.add(italian); + group.add(english); + + languageMenu.add(italian); + languageMenu.add(english); + + mb.add(languageMenu); + this.setJMenuBar(mb); // Add listeners etc. @@ -241,7 +274,7 @@ public ZCashUI(StartupProgressDialog progressDialog) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.exitProgram(); + HorizenUI.this.exitProgram(); } } ); @@ -254,12 +287,12 @@ public void actionPerformed(ActionEvent e) { try { - AboutDialog ad = new AboutDialog(ZCashUI.this); + AboutDialog ad = new AboutDialog(HorizenUI.this); ad.setVisible(true); } catch (UnsupportedEncodingException uee) { Log.error("Unexpected error: ", uee); - ZCashUI.this.errorReporter.reportError(uee); + HorizenUI.this.errorReporter.reportError(uee); } } } @@ -271,21 +304,23 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.backupWallet(); + HorizenUI.this.walletOps.backupWallet(); } } ); + /** Encrypt menu item is not initialized menuItemEncrypt.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.encryptWallet(); + HorizenUI.this.walletOps.encryptWallet(); } } ); + */ menuItemExportKeys.addActionListener( new ActionListener() @@ -293,7 +328,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.exportWalletPrivateKeys(); + HorizenUI.this.walletOps.exportWalletPrivateKeys(); } } ); @@ -304,7 +339,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.importWalletPrivateKeys(); + HorizenUI.this.walletOps.importWalletPrivateKeys(); } } ); @@ -315,7 +350,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.showPrivateKey(); + HorizenUI.this.walletOps.showPrivateKey(); } } ); @@ -326,7 +361,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.importSinglePrivateKey(); + HorizenUI.this.walletOps.importSinglePrivateKey(); } } ); @@ -337,7 +372,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.openOwnIdentityDialog(); + HorizenUI.this.messagingPanel.openOwnIdentityDialog(); } } ); @@ -348,7 +383,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.exportOwnIdentity(); + HorizenUI.this.messagingPanel.exportOwnIdentity(); } } ); @@ -359,7 +394,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.importContactIdentity(); + HorizenUI.this.messagingPanel.importContactIdentity(); } } ); @@ -370,7 +405,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.addMessagingGroup(); + HorizenUI.this.messagingPanel.addMessagingGroup(); } } ); @@ -381,7 +416,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.removeSelectedContact(); + HorizenUI.this.messagingPanel.removeSelectedContact(); } } ); @@ -392,7 +427,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.openOptionsDialog(); + HorizenUI.this.messagingPanel.openOptionsDialog(); } } ); @@ -403,7 +438,7 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.messagingPanel.shareFileViaIPFS(); + HorizenUI.this.messagingPanel.shareFileViaIPFS(); } } ); @@ -414,11 +449,23 @@ public void actionPerformed(ActionEvent e) @Override public void actionPerformed(ActionEvent e) { - ZCashUI.this.walletOps.exportToArizenWallet(); + HorizenUI.this.walletOps.exportToArizenWallet(); + } + } + ); + + menuItemZendParameters.addActionListener( + new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + HorizenUI.this.walletOps.editZendOptions(); } } ); + // Close operation this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); this.addWindowListener(new WindowAdapter() @@ -426,7 +473,7 @@ public void actionPerformed(ActionEvent e) @Override public void windowClosing(WindowEvent e) { - ZCashUI.this.exitProgram(); + HorizenUI.this.exitProgram(); } }); @@ -438,13 +485,34 @@ public void run() try { String userDir = OSUtil.getSettingsDirectory(); - File warningFlagFile = new File(userDir + File.separator + "initialInfoShown_0.75.flag"); + File warningFlagFile = new File(userDir + File.separator + "initialInfoShown_0.85.flag"); if (warningFlagFile.exists()) { return; - } else + }; + + Object[] options = + { + langUtil.getString("main.frame.disclaimer.button.agree"), + langUtil.getString("main.frame.disclaimer.button.disagree") + }; + + int option = JOptionPane.showOptionDialog( + HorizenUI.this.getRootPane().getParent(), + langUtil.getString("main.frame.disclaimer.text"), + langUtil.getString("main.frame.disclaimer.title"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, + null, + options, + options[0]); + + if (option == 0) { warningFlagFile.createNewFile(); + } else + { + HorizenUI.this.exitProgram(); } } catch (IOException ioe) @@ -452,21 +520,6 @@ public void run() /* TODO: report exceptions to the user */ Log.error("Unexpected error: ", ioe); } - - JOptionPane.showMessageDialog( - ZCashUI.this.getRootPane().getParent(), - "The ZENCash GUI Wallet is currently considered experimental. Use of this software\n" + - "comes at your own risk! Be sure to read the list of known issues and limitations\n" + - "at this page: https://github.com/ZencashOfficial/zencash-swing-wallet-ui\n\n" + - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" + - "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" + - "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" + - "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" + - "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n" + - "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n" + - "THE SOFTWARE.\n\n" + - "(This message will be shown only once, per release)", - "Disclaimer", JOptionPane.INFORMATION_MESSAGE); } }); @@ -484,14 +537,32 @@ public void run() public void stateChanged(ChangeEvent e) { JTabbedPane tabs = (JTabbedPane)e.getSource(); - if (tabs.getSelectedIndex() == 4) + if (tabs.getSelectedIndex() == 5) { - ZCashUI.this.messagingPanel.tabSelected(); + HorizenUI.this.messagingPanel.tabSelected(); } } } ); + + this.validate(); + this.repaint(); + + + this.pack(); + Dimension currentSize = this.getSize(); + + OS_TYPE os = OSUtil.getOSType(); + int width = 1040; + if (os == OS_TYPE.MAC_OS) + { + width += 100; // Needs to be wider on macOS + } + + this.setSize(new Dimension(width, currentSize.height)); + this.validate(); + this.repaint(); } public void exitProgram() @@ -501,29 +572,34 @@ public void exitProgram() this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); this.dashboard.stopThreadsAndTimers(); + this.transactionDetailsPanel.stopThreadsAndTimers(); this.addresses.stopThreadsAndTimers(); this.sendPanel.stopThreadsAndTimers(); this.messagingPanel.stopThreadsAndTimers(); - ZCashUI.this.setVisible(false); - ZCashUI.this.dispose(); + HorizenUI.this.setVisible(false); + HorizenUI.this.dispose(); System.exit(0); } public static void main(String argv[]) - throws IOException + throws IOException, URISyntaxException { try { OS_TYPE os = OSUtil.getOSType(); + possiblyCreateZendOptionsFile(); + if ((os == OS_TYPE.WINDOWS) || (os == OS_TYPE.MAC_OS)) { possiblyCreateZENConfigFile(); } + + LanguageUtil langUtil = LanguageUtil.instance(); - Log.info("Starting ZENCash Swing Wallet ..."); + Log.info("Starting Horizen Swing Wallet ..."); Log.info("OS: " + System.getProperty("os.name") + " = " + os); Log.info("Current directory: " + new File(".").getCanonicalPath()); Log.info("Class path: " + System.getProperty("java.class.path")); @@ -593,7 +669,7 @@ public static void main(String argv[]) if ((zcashdInfo.status != DAEMON_STATUS.RUNNING) || (daemonStartInProgress)) { Log.info( - "zend is not runing at the moment or has not started/synchronized 100% - showing splash..."); + "zend is not running at the moment or has not started/synchronized 100% - showing splash..."); startupBar = new StartupProgressDialog(initialClientCaller); startupBar.setVisible(true); startupBar.waitForStartup(); @@ -601,7 +677,7 @@ public static void main(String argv[]) initialClientCaller = null; // Main GUI is created here - ZCashUI ui = new ZCashUI(startupBar); + HorizenUI ui = new HorizenUI(startupBar); ui.setVisible(true); } catch (InstallationDetectionException ide) @@ -609,10 +685,10 @@ public static void main(String argv[]) Log.error("Unexpected error: ", ide); JOptionPane.showMessageDialog( null, - "This program was started in directory: " + OSUtil.getProgramDirectory() + "\n" + - ide.getMessage() + "\n" + - "See the console/logfile output for more detailed error information!", - "Installation error", + LanguageUtil.instance().getString("main.frame.option.pane.installation.error.text", + OSUtil.getProgramDirectory(), + ide.getMessage() ), + LanguageUtil.instance().getString("main.frame.option.pane.installation.error.title"), JOptionPane.ERROR_MESSAGE); System.exit(1); } catch (WalletCallException wce) @@ -624,21 +700,15 @@ public static void main(String argv[]) { JOptionPane.showMessageDialog( null, - "It appears that zend has been started but is not ready to accept wallet\n" + - "connections. It is still loading the wallet and blockchain. Please try to \n" + - "start the GUI wallet later...", - "Wallet communication error", + LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.text"), + LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.title"), JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog( null, - "There was a problem communicating with the ZENCash daemon/wallet. \n" + - "Please ensure that the ZENCash server zend is started (e.g. via \n" + - "command \"zend --daemon\"). Error message is: \n" + - wce.getMessage() + - "See the console/logfile output for more detailed error information!", - "Wallet communication error", + LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.2.text", wce.getMessage()), + LanguageUtil.instance().getString("main.frame.option.pane.wallet.communication.error.2.title"), JOptionPane.ERROR_MESSAGE); } @@ -648,9 +718,8 @@ public static void main(String argv[]) Log.error("Unexpected error: ", e); JOptionPane.showMessageDialog( null, - "A general unexpected critical error has occurred: \n" + e.getMessage() + "\n" + - "See the console/logfile output for more detailed error information!", - "Error", + LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.text", e.getMessage()), + LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.title"), JOptionPane.ERROR_MESSAGE); System.exit(3); } catch (Error err) @@ -659,10 +728,9 @@ public static void main(String argv[]) err.printStackTrace(); JOptionPane.showMessageDialog( null, - "A general unexpected critical/unrecoverable error has occurred: \n" + err.getMessage() + "\n" + - "See the console/logfile output for more detailed error information!", - "Error", - JOptionPane.ERROR_MESSAGE); + LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.2.text", err.getMessage()), + LanguageUtil.instance().getString("main.frame.option.pane.wallet.critical.error.2.title"), + JOptionPane.ERROR_MESSAGE); System.exit(4); } } @@ -690,40 +758,99 @@ public static void possiblyCreateZENConfigFile() Log.info("ZEN configuration file " + zenConfigFile.getCanonicalPath() + " does not exist. It will be created with default settings."); - Random r = new Random(System.currentTimeMillis()); + Random r = new Random(System.nanoTime()); + SecureRandom r2 = new SecureRandom(); // Improved randomness PrintStream configOut = new PrintStream(new FileOutputStream(zenConfigFile)); configOut.println("#############################################################################"); configOut.println("# ZEN configuration file #"); configOut.println("#############################################################################"); - configOut.println("# This file has been automatically generated by the ZENCash GUI wallet with #"); + configOut.println("# This file has been automatically generated by the Horizen GUI wallet with #"); configOut.println("# default settings. It may be further cutsomized by hand only. #"); configOut.println("#############################################################################"); configOut.println("# Creation date: " + new Date().toString()); configOut.println("#############################################################################"); configOut.println(""); configOut.println("# The rpcuser/rpcpassword are used for the local call to zend"); - configOut.println("rpcuser=User" + Math.abs(r.nextInt())); + configOut.println("rpcuser=User" + Math.abs(r2.nextInt())); configOut.println("rpcpassword=Pass" + Math.abs(r.nextInt()) + "" + - Math.abs(r.nextInt()) + "" + - Math.abs(r.nextInt())); - configOut.println(""); + Math.abs(r2.nextInt()) + "" + + Math.abs(r2.nextInt())); + configOut.println(""); + configOut.close(); + } + } + + + /** + * Possibly creates the configuration file wit zend command line options. + * + * @throws IOException + */ + public static void possiblyCreateZendOptionsFile() + throws IOException + { + String settingsDir = OSUtil.getSettingsDirectory(); + File dir = new File(settingsDir); + + if (!dir.exists()) + { + if (!dir.mkdirs()) + { + Log.error("ERROR: Could not create settings directory: " + dir.getCanonicalPath()); + throw new IOException("Could not create settings directory: " + dir.getCanonicalPath()); + } + } + + File zendOptionsFile = new File(dir, "zend-cmd-options.conf"); + if (!zendOptionsFile.exists()) + { + Log.info("zend command line options configuration file " + zendOptionsFile.getCanonicalPath() + + " does not exist. It will be created with default settings."); - /* - * This is not necessary as of release: - * https://github.com/ZencashOfficial/zen/releases/tag/v2.0.9-3-b8d2ebf - configOut.println("# Well-known nodes to connect to - to speed up acquiring initial connections"); - configOut.println("addnode=zpool.blockoperations.com"); - configOut.println("addnode=luckpool.org:8333"); - configOut.println("addnode=zencash.cloud"); - configOut.println("addnode=zen.suprnova.cc"); - configOut.println("addnode=zen.bitfire.one"); - configOut.println("addnode=zenmine.pro"); - */ + PrintWriter configOut = new PrintWriter(zendOptionsFile, "UTF-8"); + String exportDir = OSUtil.getUserHomeDirectory().getCanonicalPath(); + + configOut.println("########################################################################################"); + configOut.println("# #"); + configOut.println("# zend command-line options configuration file #"); + configOut.println("# #"); + configOut.println("########################################################################################"); + configOut.println("# #"); + configOut.println("# This file has been automatically generated by the Horizen GUI wallet with #"); + configOut.println("# default settings. It may be further cutsomized by hand only. The command #"); + configOut.println("# line options specified here are used to start zend in the GUI wallet! #"); + configOut.println("# #"); + configOut.println("# The format of the file is the following: #"); + configOut.println("# 1. Each non-empty line of the file contains one command line option #"); + configOut.println("# 2. If a line has as its first non-white space character #, it is ignored #"); + configOut.println("# 3. Lines with white space only are ignored #"); + configOut.println("# #"); + configOut.println("# The file as automatically created by the GUI wallet contains some #"); + configOut.println("# common command line options. The complete list of options may be found #"); + configOut.println("# under this link: #"); + configOut.println("# https://github.com/HorizenOfficial/zencash-swing-wallet-ui/raw/master/docs/zend.pdf #"); + configOut.println("# #"); + configOut.println("########################################################################################"); + configOut.println("# #"); + configOut.println("# CAUTION: Editing the zend options is meant to be done by experienced #"); + configOut.println("# users. Any mistake made here may prevent the GUI wallet from #"); + configOut.println("# starting properly! #"); + configOut.println("# #"); + configOut.println("########################################################################################"); + configOut.println("# #"); + configOut.println("# Creation date: " + new Date().toString()); + configOut.println("# #"); + configOut.println("########################################################################################"); + configOut.println(""); + configOut.println(""); + configOut.println("# The default ZEN backup directory is the user home dir. This is the place for"); + configOut.println("# instance where the wallet backups are stored."); + configOut.println("-exportdir=" + exportDir); + configOut.println(""); configOut.close(); } } - } diff --git a/src/java/com/vaklinov/zcashui/LabelStorage.java b/src/java/com/vaklinov/zcashui/LabelStorage.java new file mode 100644 index 00000000..d88cbed8 --- /dev/null +++ b/src/java/com/vaklinov/zcashui/LabelStorage.java @@ -0,0 +1,127 @@ +/************************************************************************************************ + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **********************************************************************************/ +package com.vaklinov.zcashui; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; + + +// Manages the load/store operations for address labels +public class LabelStorage +{ + private static final String LABELS_FILE_NAME = "wallet.dat.labels"; + + // Address -> label + private Properties labels; + + public LabelStorage() + throws IOException + { + this.labels = new Properties(); + this.loadLabels(); + } + + + public synchronized String getLabel(String address) + { + String label = ""; + + if (this.labels.containsKey(address)) + { + label = this.labels.getProperty(address); + } + + return label; + } + + + public synchronized void setLabel(String address, String label) + throws IOException + { + if (!this.getLabel(address).equals(label)) + { + this.labels.setProperty(address, label); + this.storeLabels(); + } + } + + + private synchronized void loadLabels() + throws IOException + { + File labelsFile = new File(OSUtil.getSettingsDirectory() + File.separator + LABELS_FILE_NAME); + if (!labelsFile.exists()) + { + Log.info("Wallet labels file does not exist: {0}", labelsFile.getCanonicalPath()); + return; + } + + InputStream in = null; + try + { + in = new BufferedInputStream(new FileInputStream(labelsFile)); + this.labels.load(in); + } finally + { + if (in != null) + { + in.close(); + } + } + } + + + private synchronized void storeLabels() + throws IOException + { + Util.renameFileForMultiVersionBackup(new File(OSUtil.getSettingsDirectory()), LABELS_FILE_NAME); + + File newLabelsFile = new File(OSUtil.getSettingsDirectory() + File.separator + LABELS_FILE_NAME); + OutputStream out = null; + try + { + out = new BufferedOutputStream(new FileOutputStream(newLabelsFile)); + this.labels.store(out, "Horizen GUI wallet address labels"); + } finally + { + if (out != null) + { + out.close(); + } + } + } +} diff --git a/src/java/com/vaklinov/zcashui/LanguageMenuItem.java b/src/java/com/vaklinov/zcashui/LanguageMenuItem.java new file mode 100644 index 00000000..c8738925 --- /dev/null +++ b/src/java/com/vaklinov/zcashui/LanguageMenuItem.java @@ -0,0 +1,19 @@ +package com.vaklinov.zcashui; + +import javax.swing.*; +import java.util.Locale; + +public class LanguageMenuItem extends JRadioButtonMenuItem { + + private Locale locale; + + public LanguageMenuItem(String text, Icon icon, Locale locale) { + super(text,icon); + this.locale = locale; + } + + @Override + public Locale getLocale() { + return locale; + } +} diff --git a/src/java/com/vaklinov/zcashui/LanguageUtil.java b/src/java/com/vaklinov/zcashui/LanguageUtil.java new file mode 100644 index 00000000..5c5bbf90 --- /dev/null +++ b/src/java/com/vaklinov/zcashui/LanguageUtil.java @@ -0,0 +1,100 @@ +package com.vaklinov.zcashui; + +import javax.swing.*; +import java.io.*; +import java.text.MessageFormat; +import java.util.*; +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; + +/** + * Language Utility resource bundle loader. + * + * @author aballaci + */ +public class LanguageUtil { + + private static final String PREFERRED_LOCALE_FILE_NAME = "language_preferences.txt"; + + private static final String RESOURCE_BUNDLE_FILE_NAME = "messages.zencash"; + + private static final Locale DEFAULT_LOCALE = Locale.US; + + + private LanguageUtil(){ + supportedLocale = new HashMap(); + supportedLocale.put(Locale.US.getCountry(), Locale.US); + supportedLocale.put(Locale.ITALY.getCountry(), Locale.ITALY); + supportedLocale.put(Locale.GERMANY.getCountry(), Locale.GERMANY); + } + + private static LanguageUtil instance; + + private Map supportedLocale; + + private ResourceBundle rb; + + public static LanguageUtil instance(){ + if(instance == null){ + instance = new LanguageUtil(); + instance.loadBundle(); + } + return instance; + } + + private void loadBundle(){ + Locale currentLocale = getUsersPreferredLocale(); + rb = ResourceBundle.getBundle(RESOURCE_BUNDLE_FILE_NAME, currentLocale); + Log.info("Loading locale: " + currentLocale.toString()); + } + + public String getString(String key){ + try { + return rb.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + public String getString(String key, Object... params ) { + try { + return MessageFormat.format(rb.getString(key), params); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } + + public void updatePreferredLanguage(Locale locale) { + try { + File languagePrefsFile = new File(OSUtil.getSettingsDirectory(),PREFERRED_LOCALE_FILE_NAME ); + try (PrintWriter printWriter = new PrintWriter(new FileWriter(languagePrefsFile))) { + printWriter.println(locale.getCountry()); + } + + } catch (IOException e) { + Log.error("Saving Preferred Locale Failed!!!!", e); + } + } + + public Locale getUsersPreferredLocale() { + File languagePrefsFile; + try { + languagePrefsFile = new File(OSUtil.getSettingsDirectory(),PREFERRED_LOCALE_FILE_NAME); + + if (!languagePrefsFile.exists()) { + return DEFAULT_LOCALE; + } + BufferedReader bufferedReader = new BufferedReader(new FileReader(languagePrefsFile)); + String country = bufferedReader.readLine().trim(); + bufferedReader.close(); + return supportedLocale.get(country); + } catch (FileNotFoundException e) { + Log.error("Loading Language file Failed!!!!", e); + return DEFAULT_LOCALE; + } catch (IOException e) { + Log.error("Loading Language file Failed!!!!", e); + return DEFAULT_LOCALE; + } + } + +} diff --git a/src/java/com/vaklinov/zcashui/Log.java b/src/java/com/vaklinov/zcashui/Log.java index 99587fa2..ab9393f3 100644 --- a/src/java/com/vaklinov/zcashui/Log.java +++ b/src/java/com/vaklinov/zcashui/Log.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016-2017 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/src/java/com/vaklinov/zcashui/OSUtil.java b/src/java/com/vaklinov/zcashui/OSUtil.java index f66aa9b8..3f60fe4f 100644 --- a/src/java/com/vaklinov/zcashui/OSUtil.java +++ b/src/java/com/vaklinov/zcashui/OSUtil.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +29,7 @@ **********************************************************************************/ package com.vaklinov.zcashui; - +import java.net.URISyntaxException; import java.io.File; import java.io.IOException; import java.util.Locale; @@ -36,8 +37,6 @@ /** * Utilities - may be OS dependent. - * - * @author Ivan Vaklinov */ public class OSUtil { @@ -131,11 +130,19 @@ public static String getZCashCli() // Returns the directory that the wallet program was started from public static String getProgramDirectory() - throws IOException + throws IOException, URISyntaxException { + final String JAR_NAME = "ZENCashSwingWalletUI.jar"; + File jarFile = new File(HorizenUI.class.getProtectionDomain().getCodeSource().getLocation().toURI()); + + if (jarFile.exists()) { + String path = jarFile.getCanonicalPath(); + + return new File(path.substring(0, path.length() - JAR_NAME.length())).getCanonicalPath(); + } + // TODO: this way of finding the dir is JAR name dependent - tricky, may not work // if program is repackaged as different JAR! - final String JAR_NAME = "ZENCashSwingWalletUI.jar"; String cp = System.getProperty("java.class.path"); if ((cp != null) && (cp.indexOf(File.pathSeparator) == -1) && (cp.endsWith(JAR_NAME))) diff --git a/src/java/com/vaklinov/zcashui/PasswordDialog.java b/src/java/com/vaklinov/zcashui/PasswordDialog.java index 77268166..318edff5 100644 --- a/src/java/com/vaklinov/zcashui/PasswordDialog.java +++ b/src/java/com/vaklinov/zcashui/PasswordDialog.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,8 +50,6 @@ /** * Dialog to get the user password for encrypted wallets - for unlock. - * - * @author Ivan Vaklinov */ public class PasswordDialog extends JDialog @@ -66,12 +65,13 @@ public class PasswordDialog protected JPanel freeSlotPanel; protected JPanel freeSlotPanel2; + private LanguageUtil langUtil; public PasswordDialog(JFrame parent) { super(parent); - - this.setTitle("Password..."); + langUtil = LanguageUtil.instance(); + this.setTitle(langUtil.getString("dialog.password.title")); this.setLocation(parent.getLocation().x + 50, parent.getLocation().y + 50); this.setModal(true); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); @@ -81,9 +81,7 @@ public PasswordDialog(JFrame parent) controlsPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); JPanel tempPanel = new JPanel(new BorderLayout(0, 0)); - tempPanel.add(this.upperLabel = new JLabel("The wallet is encrypted and protected with a password. " + - "Please enter the password to unlock it temporarily during " + - "the operation"), BorderLayout.CENTER); + tempPanel.add(this.upperLabel = new JLabel(langUtil.getString("dialog.password.temp.panel.upper.label.text")), BorderLayout.CENTER); controlsPanel.add(tempPanel); JLabel dividerLabel = new JLabel(" "); @@ -91,7 +89,7 @@ public PasswordDialog(JFrame parent) controlsPanel.add(dividerLabel); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(passwordLabel = new JLabel("Password: ")); + tempPanel.add(passwordLabel = new JLabel(langUtil.getString("dialog.password.temp.panel.password.label.text"))); tempPanel.add(passwordField = new JPasswordField(30)); controlsPanel.add(tempPanel); @@ -106,10 +104,7 @@ public PasswordDialog(JFrame parent) controlsPanel.add(this.freeSlotPanel2); tempPanel = new JPanel(new BorderLayout(0, 0)); - tempPanel.add(this.lowerLabel = new JLabel("" + - "WARNING: Never enter your password on a public/shared " + - "computer or one that you suspect has been infected with malware! " + - ""), BorderLayout.CENTER); + tempPanel.add(this.lowerLabel = new JLabel(langUtil.getString("dialog.password.temp.panel.lower.label.text")), BorderLayout.CENTER); controlsPanel.add(tempPanel); this.getContentPane().setLayout(new BorderLayout(0, 0)); @@ -118,10 +113,10 @@ public PasswordDialog(JFrame parent) // Form buttons JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3)); - JButton okButon = new JButton("OK"); + JButton okButon = new JButton(langUtil.getString("dialog.password.buton.ok.text")); buttonPanel.add(okButon); buttonPanel.add(new JLabel(" ")); - JButton cancelButon = new JButton("Cancel"); + JButton cancelButon = new JButton(langUtil.getString("dialog.password.buton.cancel.text")); buttonPanel.add(cancelButon); this.getContentPane().add(buttonPanel, BorderLayout.SOUTH); @@ -161,7 +156,8 @@ protected void processOK() { JOptionPane.showMessageDialog( PasswordDialog.this.getParent(), - "The password is empty. Please enter it into the text field.", "Empty...", + langUtil.getString("dialog.password.option.pane.process.text"), + langUtil.getString("dialog.password.option.pane.process.title"), JOptionPane.ERROR_MESSAGE); return; } diff --git a/src/java/com/vaklinov/zcashui/PasswordEncryptionDialog.java b/src/java/com/vaklinov/zcashui/PasswordEncryptionDialog.java index 15c72c55..5bc77df6 100644 --- a/src/java/com/vaklinov/zcashui/PasswordEncryptionDialog.java +++ b/src/java/com/vaklinov/zcashui/PasswordEncryptionDialog.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,24 +41,21 @@ /** * Dialog to get the user password - to encrypt a wallet. - * - * @author Ivan Vaklinov */ public class PasswordEncryptionDialog extends PasswordDialog { protected JTextField passwordConfirmationField = null; + + private LanguageUtil langUtil; public PasswordEncryptionDialog(JFrame parent) { super(parent); - - this.upperLabel.setText( - "The wallet.dat file will be encrypted with a password. If the operation is successful, " + - "zend will automatically stop and will need to be restarted. The GUI wallet will also be stopped " + - "and will need to be restarted. Please enter the password:"); + langUtil = LanguageUtil.instance(); + this.upperLabel.setText(langUtil.getString("dialog.password.encryption.upper.label.text")); - JLabel confLabel = new JLabel("Confirmation: "); + JLabel confLabel = new JLabel(langUtil.getString("dialog.password.encryption.confirmation.label.text")); this.freeSlotPanel.add(confLabel); this.freeSlotPanel.add(passwordConfirmationField = new JPasswordField(30)); this.passwordLabel.setPreferredSize(confLabel.getPreferredSize()); @@ -91,7 +89,8 @@ protected void processOK() { JOptionPane.showMessageDialog( this.getParent(), - "The password and the confirmation do not match!", "Password mismatch...", + langUtil.getString("dialog.password.encryption.option.pane.mismatch.text"), + langUtil.getString("dialog.password.encryption.option.pane.mismatch.title") , JOptionPane.ERROR_MESSAGE); return; } diff --git a/src/java/com/vaklinov/zcashui/PresentationPanel.java b/src/java/com/vaklinov/zcashui/PresentationPanel.java index 5cfa469b..003049d1 100644 --- a/src/java/com/vaklinov/zcashui/PresentationPanel.java +++ b/src/java/com/vaklinov/zcashui/PresentationPanel.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,8 +43,6 @@ /** * Panel with gradient background etc. for pretty label presentations. - * - * @author Ivan Vaklinov */ public class PresentationPanel extends JPanel diff --git a/src/java/com/vaklinov/zcashui/ProvingKeyFetcher.java b/src/java/com/vaklinov/zcashui/ProvingKeyFetcher.java index 56a618a1..43327c3f 100644 --- a/src/java/com/vaklinov/zcashui/ProvingKeyFetcher.java +++ b/src/java/com/vaklinov/zcashui/ProvingKeyFetcher.java @@ -19,7 +19,6 @@ import javax.swing.JOptionPane; import javax.swing.ProgressMonitorInputStream; -import javax.xml.bind.DatatypeConverter; import com.vaklinov.zcashui.OSUtil.OS_TYPE; @@ -32,14 +31,22 @@ public class ProvingKeyFetcher { private static final int PROVING_KEY_SIZE = 910173851; private static final String SHA256 = "8bc20a7f013b2b58970cddd2e7ea028975c88ae7ceb9259a5344a16bc2c0eef7"; - private static final String pathURL = "https://zensystem.io/downloads/sprout-proving.key"; + private static final String pathURL = "https://downloads.horizen.io/file/TrustedSetup/sprout-proving.key"; + private static final int SPROUT_GROTH_SIZE = 725523612; + private static final String SHA256SG = "b685d700c60328498fbde589c8c7c484c722b788b265b72af448a5bf0ee55b50"; + private static final String pathURLSG = "https://downloads.horizen.io/file/TrustedSetup/sprout-groth16.params"; + private static final int SAPLING_SPEND_SIZE = 47958396; + private static final String SHA256SS = "8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13"; + private static final String pathURLSS = "https://downloads.horizen.io/file/TrustedSetup/sapling-spend.params"; // TODO: add backups - + private LanguageUtil langUtil; + public void fetchIfMissing(StartupProgressDialog parent) throws IOException { + langUtil = LanguageUtil.instance(); try { verifyOrFetch(parent); } catch (InterruptedIOException iox) { - JOptionPane.showMessageDialog(parent, "The ZENCash wallet cannot proceed without a proving key."); + JOptionPane.showMessageDialog(parent, langUtil.getString("proving.key.fetcher.option.pane.message")); System.exit(-3); } } @@ -63,9 +70,13 @@ private void verifyOrFetch(StartupProgressDialog parent) zCashParams = zCashParams.getCanonicalFile(); boolean needsFetch = false; + boolean needsFetchSG = false; + boolean needsFetchSS = false; if (!zCashParams.exists()) { needsFetch = true; + needsFetchSG = true; + needsFetchSS = true; zCashParams.mkdirs(); } @@ -76,9 +87,21 @@ private void verifyOrFetch(StartupProgressDialog parent) copy(is,fos); fos.close(); is = null; + + // sapling output params is small, always copy it + File saplingOutputFile = new File(zCashParams,"sapling-output.params"); + FileOutputStream fosB = new FileOutputStream(saplingOutputFile); + InputStream isB = ProvingKeyFetcher.class.getClassLoader().getResourceAsStream("keys/sapling-output.params"); + copy(isB,fosB); + fosB.close(); + isB = null; File provingKeyFile = new File(zCashParams,"sprout-proving.key"); provingKeyFile = provingKeyFile.getCanonicalFile(); + File sproutGrothFile = new File(zCashParams,"sprout-groth16.params"); + sproutGrothFile = sproutGrothFile.getCanonicalFile(); + File saplingSpendFile = new File(zCashParams,"sapling-spend.params"); + saplingSpendFile = saplingSpendFile.getCanonicalFile(); if (!provingKeyFile.exists()) { needsFetch = true; @@ -86,6 +109,23 @@ private void verifyOrFetch(StartupProgressDialog parent) { needsFetch = true; } + + if (!sproutGrothFile.exists()) + { + needsFetchSG = true; + } else if (sproutGrothFile.length() != SPROUT_GROTH_SIZE) + { + needsFetchSG = true; + } + + if (!saplingSpendFile.exists()) + { + needsFetchSS = true; + } else if (saplingSpendFile.length() != SAPLING_SPEND_SIZE) + { + needsFetchSS = true; + } + /* * We skip proving key verification every start - this is impractical. * If the proving key exists and is the correct size, then it should be OK. @@ -95,17 +135,17 @@ private void verifyOrFetch(StartupProgressDialog parent) needsFetch = !checkSHA256(provingKeyFile,parent); }*/ - if (!needsFetch) + if (!needsFetch && !needsFetchSG && !needsFetchSS) { return; } JOptionPane.showMessageDialog( parent, - "The wallet needs to download the Z cryptographic proving key (approx. 900 MB).\n" + - "This will be done only once. Please be patient... Press OK to continue"); + langUtil.getString("proving.key.fetcher.option.pane.verify.message")); - parent.setProgressText("Downloading proving key..."); + parent.setProgressText(langUtil.getString("proving.key.fetcher.option.pane.verify.progress.text")); + if (needsFetch) { provingKeyFile.delete(); OutputStream os = new BufferedOutputStream(new FileOutputStream(provingKeyFile)); URL keyURL = new URL(pathURL); @@ -115,7 +155,7 @@ private void verifyOrFetch(StartupProgressDialog parent) try { is = urlc.getInputStream(); - ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, "Downloading proving key", is); + ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, langUtil.getString("proving.key.fetcher.option.pane.verify.progress.monitor.text"), is); pmis.getProgressMonitor().setMaximum(PROVING_KEY_SIZE); pmis.getProgressMonitor().setMillisToPopup(10); @@ -125,12 +165,67 @@ private void verifyOrFetch(StartupProgressDialog parent) { try { if (is != null) is.close(); } catch (IOException ignore){} } - parent.setProgressText("Verifying downloaded proving key..."); + parent.setProgressText(langUtil.getString("proving.key.fetcher.option.pane.verify.key.text")); if (!checkSHA256(provingKeyFile, parent)) { - JOptionPane.showMessageDialog(parent, "Failed to download proving key properly. Cannot continue!"); + JOptionPane.showMessageDialog(parent, langUtil.getString("proving.key.fetcher.option.pane.verify.key.failed.text")); + System.exit(-4); + } + } + if (needsFetchSG) { + sproutGrothFile.delete(); + OutputStream os = new BufferedOutputStream(new FileOutputStream(sproutGrothFile)); + URL keyURL = new URL(pathURLSG); + URLConnection urlc = keyURL.openConnection(); + urlc.setRequestProperty("User-Agent", "Wget/1.17.1 (linux-gnu)"); + + try + { + is = urlc.getInputStream(); + ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, langUtil.getString("sprout.groth.fetcher.option.pane.verify.progress.monitor.text"), is); + pmis.getProgressMonitor().setMaximum(SPROUT_GROTH_SIZE); + pmis.getProgressMonitor().setMillisToPopup(10); + + copy(pmis,os); + os.close(); + } finally + { + try { if (is != null) is.close(); } catch (IOException ignore){} + } + parent.setProgressText(langUtil.getString("sprout.groth.fetcher.option.pane.verify.key.text")); + if (!checkSHA256SG(sproutGrothFile, parent)) + { + JOptionPane.showMessageDialog(parent, langUtil.getString("sapsproutling.groth.fetcher.option.pane.verify.key.failed.text")); + System.exit(-4); + } + } + if (needsFetchSS) { + saplingSpendFile.delete(); + OutputStream os = new BufferedOutputStream(new FileOutputStream(saplingSpendFile)); + URL keyURL = new URL(pathURLSS); + URLConnection urlc = keyURL.openConnection(); + urlc.setRequestProperty("User-Agent", "Wget/1.17.1 (linux-gnu)"); + + try + { + is = urlc.getInputStream(); + ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, langUtil.getString("sapling.spend.fetcher.option.pane.verify.progress.monitor.text"), is); + pmis.getProgressMonitor().setMaximum(SAPLING_SPEND_SIZE); + pmis.getProgressMonitor().setMillisToPopup(10); + + copy(pmis,os); + os.close(); + } finally + { + try { if (is != null) is.close(); } catch (IOException ignore){} + } + parent.setProgressText(langUtil.getString("sapling.spend.fetcher.option.pane.verify.key.text")); + if (!checkSHA256SS(saplingSpendFile, parent)) + { + JOptionPane.showMessageDialog(parent, langUtil.getString("sapling.spend.fetcher.option.pane.verify.key.failed.text")); System.exit(-4); } + } } @@ -151,14 +246,61 @@ private static boolean checkSHA256(File provingKey, Component parent) throws IOE throw new IOException(impossible); } try (InputStream is = new BufferedInputStream(new FileInputStream(provingKey))) { - ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent,"Verifying proving key",is); + ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, + LanguageUtil.instance().getString("proving.key.fetcher.option.pane.verify.progress.monitor.text"), + is); pmis.getProgressMonitor().setMaximum(PROVING_KEY_SIZE); pmis.getProgressMonitor().setMillisToPopup(10); DigestInputStream dis = new DigestInputStream(pmis, sha256); byte [] temp = new byte[0x1 << 13]; while(dis.read(temp) >= 0); byte [] digest = sha256.digest(); - return SHA256.equalsIgnoreCase(DatatypeConverter.printHexBinary(digest)); + + return SHA256.equalsIgnoreCase(Util.bytesToHex(digest)); + } + } + + private static boolean checkSHA256SG(File sproutGroth, Component parent) throws IOException { + MessageDigest sha256; + try { + sha256 = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException impossible) { + throw new IOException(impossible); + } + try (InputStream is = new BufferedInputStream(new FileInputStream(sproutGroth))) { + ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, + LanguageUtil.instance().getString("sprout.groth.fetcher.option.pane.verify.progress.monitor.text"), + is); + pmis.getProgressMonitor().setMaximum(SPROUT_GROTH_SIZE); + pmis.getProgressMonitor().setMillisToPopup(10); + DigestInputStream dis = new DigestInputStream(pmis, sha256); + byte [] temp = new byte[0x1 << 13]; + while(dis.read(temp) >= 0); + byte [] digest = sha256.digest(); + + return SHA256SG.equalsIgnoreCase(Util.bytesToHex(digest)); + } + } + + private static boolean checkSHA256SS(File saplingSpend, Component parent) throws IOException { + MessageDigest sha256; + try { + sha256 = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException impossible) { + throw new IOException(impossible); + } + try (InputStream is = new BufferedInputStream(new FileInputStream(saplingSpend))) { + ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, + LanguageUtil.instance().getString("sapling.spend.fetcher.option.pane.verify.progress.monitor.text"), + is); + pmis.getProgressMonitor().setMaximum(SAPLING_SPEND_SIZE); + pmis.getProgressMonitor().setMillisToPopup(10); + DigestInputStream dis = new DigestInputStream(pmis, sha256); + byte [] temp = new byte[0x1 << 13]; + while(dis.read(temp) >= 0); + byte [] digest = sha256.digest(); + + return SHA256SS.equalsIgnoreCase(Util.bytesToHex(digest)); } } } diff --git a/src/java/com/vaklinov/zcashui/SendCashPanel.java b/src/java/com/vaklinov/zcashui/SendCashPanel.java index e5b96798..4d374ef8 100644 --- a/src/java/com/vaklinov/zcashui/SendCashPanel.java +++ b/src/java/com/vaklinov/zcashui/SendCashPanel.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +31,7 @@ import java.awt.BorderLayout; +import java.awt.Cursor; import java.awt.Desktop; import java.awt.Dimension; import java.awt.FlowLayout; @@ -42,17 +44,22 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.io.File; import java.io.IOException; +import java.math.BigDecimal; import java.net.URISyntaxException; import java.net.URL; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.HashSet; +import java.util.Locale; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; @@ -71,8 +78,6 @@ /** * Provides the functionality for sending cash - * - * @author Ivan Vaklinov */ public class SendCashPanel extends WalletTabPanel @@ -81,8 +86,9 @@ public class SendCashPanel private StatusUpdateErrorReporter errorReporter; private ZCashInstallationObserver installationObserver; private BackupTracker backupTracker; + private LabelStorage labelStorage; - private JComboBox balanceAddressCombo = null; + private DropdownComboBox balanceAddressCombo = null; private JPanel comboBoxParentPanel = null; private String[][] lastAddressBalanceData = null; private String[] comboBoxItems = null; @@ -93,6 +99,8 @@ public class SendCashPanel private JTextField destinationMemoField = null; private JTextField transactionFeeField = null; + private JCheckBox sendChangeBackToSourceAddress = null; + private JButton sendButton = null; private JPanel operationStatusPanel = null; @@ -101,14 +109,17 @@ public class SendCashPanel private Timer operationStatusTimer = null; private String operationStatusID = null; private int operationStatusCounter = 0; - + private LanguageUtil langUtil; + public SendCashPanel(ZCashClientCaller clientCaller, StatusUpdateErrorReporter errorReporter, ZCashInstallationObserver installationObserver, - BackupTracker backupTracker) + BackupTracker backupTracker, + LabelStorage labelStorage) throws IOException, InterruptedException, WalletCallException { + langUtil = LanguageUtil.instance(); this.timers = new ArrayList(); this.threads = new ArrayList>(); @@ -116,6 +127,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, this.errorReporter = errorReporter; this.installationObserver = installationObserver; this.backupTracker = backupTracker; + this.labelStorage = labelStorage; // Build content this.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); @@ -126,14 +138,11 @@ public SendCashPanel(ZCashClientCaller clientCaller, sendCashPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(new JLabel("Send cash from: ")); - tempPanel.add(new JLabel( - "" + - "* Only addresses with a confirmed balance are shown as sources for sending!" + - " ")); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label"))); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.info"))); sendCashPanel.add(tempPanel); - balanceAddressCombo = new JComboBox<>(new String[] { "" }); + balanceAddressCombo = new DropdownComboBox<>(new String[] { "" }); comboBoxParentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); comboBoxParentPanel.add(balanceAddressCombo); sendCashPanel.add(comboBoxParentPanel); @@ -143,7 +152,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, sendCashPanel.add(dividerLabel); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(new JLabel("Destination address:")); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.destination.address"))); sendCashPanel.add(tempPanel); destinationAddressField = new JTextField(73); @@ -156,11 +165,8 @@ public SendCashPanel(ZCashClientCaller clientCaller, sendCashPanel.add(dividerLabel); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(new JLabel("Memo (optional): ")); - tempPanel.add(new JLabel( - "" + - "* Memo may be specified only if the destination is a Z (Private) address!" + - " ")); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.memo"))); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.memo.info"))); sendCashPanel.add(tempPanel); destinationMemoField = new JTextField(73); @@ -175,7 +181,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, // Construct a more complex panel for the amount and transaction fee JPanel amountAndFeePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); JPanel amountPanel = new JPanel(new BorderLayout()); - amountPanel.add(new JLabel("Amount to send:"), BorderLayout.NORTH); + amountPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.amount")), BorderLayout.NORTH); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); tempPanel.add(destinationAmountField = new JTextField(13)); destinationAmountField.setHorizontalAlignment(SwingConstants.RIGHT); @@ -183,16 +189,24 @@ public SendCashPanel(ZCashClientCaller clientCaller, amountPanel.add(tempPanel, BorderLayout.SOUTH); JPanel feePanel = new JPanel(new BorderLayout()); - feePanel.add(new JLabel("Transaction fee:"), BorderLayout.NORTH); + feePanel.add(new JLabel(langUtil.getString("send.cash.panel.label.fee")), BorderLayout.NORTH); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); tempPanel.add(transactionFeeField = new JTextField(13)); transactionFeeField.setText("0.0001"); // Default value transactionFeeField.setHorizontalAlignment(SwingConstants.RIGHT); tempPanel.add(new JLabel(" ZEN")); feePanel.add(tempPanel, BorderLayout.SOUTH); + + JPanel sendChangeBoxPanel = new JPanel(new BorderLayout()); + sendChangeBoxPanel.add(new JLabel(" "), BorderLayout.NORTH); + tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + tempPanel.add(new JLabel(" ")); + tempPanel.add(sendChangeBackToSourceAddress = new JCheckBox(langUtil.getString("send.cash.panel.checkbox.send.change.back"))); + sendChangeBoxPanel.add(tempPanel, BorderLayout.SOUTH); amountAndFeePanel.add(amountPanel); amountAndFeePanel.add(feePanel); + amountAndFeePanel.add(sendChangeBoxPanel); sendCashPanel.add(amountAndFeePanel); dividerLabel = new JLabel(" "); @@ -200,7 +214,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, sendCashPanel.add(dividerLabel); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(sendButton = new JButton("Send \u27A4\u27A4\u27A4")); + tempPanel.add(sendButton = new JButton(langUtil.getString("send.cash.panel.button.send") + " \u27A4\u27A4\u27A4")); sendCashPanel.add(tempPanel); dividerLabel = new JLabel(" "); @@ -209,14 +223,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, JPanel warningPanel = new JPanel(); warningPanel.setLayout(new BorderLayout(7, 3)); - JLabel warningL = new JLabel( - "" + - " * When sending cash from a T (Transparent) address, the remaining unspent balance is sent to another " + - "auto-generated T address. When sending from a Z (Private) address, the remaining unspent balance remains with " + - "the Z address. In both cases the original sending address cannot be used for sending again until the " + - "transaction is confirmed. The address is temporarily removed from the list! Freshly mined coins may only "+ - "be sent to a Z (Private) address." + - ""); + JLabel warningL = new JLabel(langUtil.getString("send.cash.panel.label.send.warning")); warningPanel.add(warningL, BorderLayout.NORTH); sendCashPanel.add(warningPanel); @@ -230,7 +237,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, operationStatusPanel.setLayout(new BoxLayout(operationStatusPanel, BoxLayout.Y_AXIS)); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(new JLabel("Last operation status: ")); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.last.operation.status"))); tempPanel.add(operationStatusLabel = new JLabel("N/A")); operationStatusPanel.add(tempPanel); @@ -239,7 +246,7 @@ public SendCashPanel(ZCashClientCaller clientCaller, operationStatusPanel.add(dividerLabel); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(new JLabel("Progress: ")); + tempPanel.add(new JLabel(langUtil.getString("send.cash.panel.label.last.operation.progress"))); tempPanel.add(operationStatusProhgressBar = new JProgressBar(0, 200)); operationStatusProhgressBar.setPreferredSize(new Dimension(250, 17)); operationStatusPanel.add(tempPanel); @@ -268,11 +275,9 @@ public void actionPerformed(ActionEvent e) JOptionPane.showMessageDialog( SendCashPanel.this.getRootPane().getParent(), - "An unexpected error occurred when sending cash!\n" + - "Please ensure that the ZENCash daemon is running and\n" + - "parameters are correct. You may try again later...\n" + - errMessage, - "Error in sending cash", JOptionPane.ERROR_MESSAGE); + langUtil.getString("send.cash.panel.option.pane.error.text",errMessage), + langUtil.getString("send.cash.panel.option.pane.error.title"), + JOptionPane.ERROR_MESSAGE); } } }); @@ -302,7 +307,6 @@ public void actionPerformed(ActionEvent e) { try { - // TODO: if the user has opened the combo box - this closes it (maybe fix) SendCashPanel.this.updateWalletAddressPositiveBalanceComboBox(); } catch (Exception ex) { @@ -317,7 +321,7 @@ public void actionPerformed(ActionEvent e) this.timers.add(timerBalancesUpdater); // Add a popup menu to the destination address field - for convenience - JMenuItem paste = new JMenuItem("Paste address"); + JMenuItem paste = new JMenuItem(langUtil.getString("send.cash.panel.menu.item.paste")); final JPopupMenu popupMenu = new JPopupMenu(); popupMenu.add(paste); paste.addActionListener(new ActionListener() @@ -369,23 +373,25 @@ public void mouseReleased(MouseEvent e) private void sendCash() throws WalletCallException, IOException, InterruptedException { - if (balanceAddressCombo.getItemCount() <= 0) + if ((balanceAddressCombo.getItemCount() <= 0) || + (this.lastAddressBalanceData == null) || + (this.lastAddressBalanceData.length <= 0)) { JOptionPane.showMessageDialog( SendCashPanel.this.getRootPane().getParent(), - "There are no addresses with a positive balance to send\n" + - "cash from!", - "No funds available", JOptionPane.ERROR_MESSAGE); + langUtil.getString("send.cash.panel.option.pane.no.funds.text"), + langUtil.getString("send.cash.panel.option.pane.no.funds.title"), + JOptionPane.ERROR_MESSAGE); return; } if (this.balanceAddressCombo.getSelectedIndex() < 0) { JOptionPane.showMessageDialog( - SendCashPanel.this.getRootPane().getParent(), - "Please select a source address with a current positive\n" + - "balance to send cash from!", - "Please select source address", JOptionPane.ERROR_MESSAGE); + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.select.source.text"), + langUtil.getString("send.cash.panel.option.pane.select.source.title"), + JOptionPane.ERROR_MESSAGE); return; } @@ -394,118 +400,259 @@ private void sendCash() final String memo = this.destinationMemoField.getText(); final String amount = this.destinationAmountField.getText(); final String fee = this.transactionFeeField.getText(); + + Log.info("Send button processing: Parameters are: from address: {0}, to address: {1}, " + + "amount: {2}, memo: {3}, transaction fee: {4}", + sourceAddress, destinationAddress, amount, memo, fee); // Verify general correctness. String errorMessage = null; if ((sourceAddress == null) || (sourceAddress.trim().length() <= 20)) { - errorMessage = "Source address is invalid; it is too short or missing."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.source.address.invalid"); } else if (sourceAddress.length() > 512) { - errorMessage = "Source address is invalid; it is too long."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.source.address.too.long"); } // TODO: full address validation if ((destinationAddress == null) || (destinationAddress.trim().length() <= 0)) { - errorMessage = "Destination address is invalid; it is missing."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.destination.address.invalid"); } else if (destinationAddress.trim().length() <= 20) { - errorMessage = "Destination address is invalid; it is too short."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.destination.address.too.short"); } else if (destinationAddress.length() > 512) { - errorMessage = "Destination address is invalid; it is too long."; - } - - // Prevent accidental sending to non-ZEN addresses (which zend supports) probably because of - // ZClassic compatibility - if (!installationObserver.isOnTestNet()) + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.destination.address.too.long"); + } else if (destinationAddress.trim().length() != destinationAddress.length()) { - if (!(destinationAddress.startsWith("zc") || - destinationAddress.startsWith("zn") || - destinationAddress.startsWith("zs"))) - { - Object[] options = { "OK" }; - - JOptionPane.showOptionDialog( - SendCashPanel.this.getRootPane().getParent(), - "The destination address to send ZEN to:\n" + - destinationAddress + "\n"+ - "does not appear to be a valid ZEN address. ZEN addresses start with zc, zn or zs!", - "Destination address is incorrect...", - JOptionPane.DEFAULT_OPTION, - JOptionPane.ERROR_MESSAGE, - null, - options, - options[0]); - - return; // Do not send anything! - } + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.destination.address.has.spaces"); } - + if ((amount == null) || (amount.trim().length() <= 0)) { - errorMessage = "Amount to send is invalid; it is missing."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.amount.invalid"); } else { try { double d = Double.valueOf(amount); + if (d < 0) + { + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.amount.negative"); + } } catch (NumberFormatException nfe) { - errorMessage = "Amount to send is invalid; it is not a number."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.amount.not.number"); } } if ((fee == null) || (fee.trim().length() <= 0)) { - errorMessage = "Transaction fee is invalid; it is missing."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.fee.invalid"); } else { try { double d = Double.valueOf(fee); + if (d < 0) + { + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.fee.negative"); + } } catch (NumberFormatException nfe) { - errorMessage = "Transaction fee is invalid; it is not a number."; + errorMessage = langUtil.getString("send.cash.panel.option.pane.error.fee.not.number"); } } - if (errorMessage != null) { JOptionPane.showMessageDialog( SendCashPanel.this.getRootPane().getParent(), - errorMessage, "Sending parameters are incorrect", JOptionPane.ERROR_MESSAGE); + errorMessage, langUtil.getString("send.cash.panel.option.pane.error.incorrect.sending.parameters"), JOptionPane.ERROR_MESSAGE); return; } - // Check for encrypted wallet - final boolean bEncryptedWallet = this.clientCaller.isWalletEncrypted(); - if (bEncryptedWallet) + // Prevent accidental sending to non-ZEN addresses (which zend supports) probably because of + // ZClassic compatibility + if (!installationObserver.isOnTestNet()) { - PasswordDialog pd = new PasswordDialog((JFrame)(SendCashPanel.this.getRootPane().getParent())); - pd.setVisible(true); - - if (!pd.isOKPressed()) + if (!(destinationAddress.startsWith("zc") || + destinationAddress.startsWith("zn") || + destinationAddress.startsWith("zs"))) + { + Object[] options = { "OK" }; + + JOptionPane.showOptionDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.error.destination.address.incorrect.text", destinationAddress), + langUtil.getString("send.cash.panel.option.pane.error.destination.address.incorrect.title"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.ERROR_MESSAGE, + null, + options, + options[0]); + + return; // Do not send anything! + } + } + + // If a memo is specified, make sure the destination is a Z address. + if ((!installationObserver.isOnTestNet()) && + (!Util.stringIsEmpty(memo)) && + (!Util.isZAddress(destinationAddress))) + { + int reply = JOptionPane.showConfirmDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.error.destination.address.notz.text", destinationAddress), + langUtil.getString("send.cash.panel.option.pane.error.destination.address.notz.title"), + JOptionPane.YES_NO_OPTION); + + if (reply == JOptionPane.NO_OPTION) { - return; + return; + } + } + + // Warn the user if there are too many fractional digits in the amount and fee + if (hasExcessiveFractionalDigits(amount)) + { + int reply = JOptionPane.showConfirmDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.error.destination.amount.fractional.digits", amount), + langUtil.getString("send.cash.panel.option.pane.error.destination.fractional.digits.title"), + JOptionPane.YES_NO_OPTION); + + if (reply == JOptionPane.NO_OPTION) + { + return; } - - this.clientCaller.unlockWallet(pd.getPassword()); } - // Call the wallet send method - operationStatusID = this.clientCaller.sendCash(sourceAddress, destinationAddress, amount, memo, fee); + if (hasExcessiveFractionalDigits(fee)) + { + int reply = JOptionPane.showConfirmDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.error.destination.fee.fractional.digits", fee), + langUtil.getString("send.cash.panel.option.pane.error.destination.fractional.digits.title"), + JOptionPane.YES_NO_OPTION); + + if (reply == JOptionPane.NO_OPTION) + { + return; + } + } + + // Get a confirmation from the user about the operation + String userDir = OSUtil.getSettingsDirectory(); + File sendCashNotToBeShownFlagFile = new File(userDir + File.separator + "sendCashWarningNotToBeShown.flag"); + if (!sendCashNotToBeShownFlagFile.exists()) + { + Object[] options = + { + langUtil.getString("send.cash.panel.option.pane.confirm.operation.button.yes"), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.button.no"), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.button.not.again") + }; + + int option; + + if (Util.stringIsEmpty(memo)) + { + option = JOptionPane.showOptionDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.text", + amount, sourceAddress, destinationAddress, fee), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.title"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + } else + { + option = JOptionPane.showOptionDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.text.with.memo", + amount, sourceAddress, destinationAddress, fee, Util.blockWrapString(memo, 50)), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.title"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[0]); + } + + if (option == 2) + { + sendCashNotToBeShownFlagFile.createNewFile(); + } + + // on "no" or close ("X") + if (option == 1 || option == -1) + { + return; + } + + // 4e075d661a12376b13e9bd95831bc6a002824e029ff50059bd1e28662971e055 + } - // Make sure the keypool has spare addresses - if ((this.backupTracker.getNumTransactionsSinceLastBackup() % 5) == 0) + boolean bEncryptedWallet = false; + // Backend operations are wrapped inside a wait cursor + Cursor oldCursor = this.getRootPane().getParent().getCursor(); + try { - this.clientCaller.keypoolRefill(100); + this.getRootPane().getParent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + // Check for encrypted wallet + bEncryptedWallet = this.clientCaller.isWalletEncrypted(); + if (bEncryptedWallet) + { + this.getRootPane().getParent().setCursor(oldCursor); + PasswordDialog pd = new PasswordDialog((JFrame)(SendCashPanel.this.getRootPane().getParent())); + pd.setVisible(true); + this.getRootPane().getParent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + if (!pd.isOKPressed()) + { + return; + } + + this.clientCaller.unlockWallet(pd.getPassword()); + } + + boolean sendChangeBackToAddres = this.sendChangeBackToSourceAddress.isSelected(); + Log.info("Change send back flag: {0}", sendChangeBackToAddres); + if (sendChangeBackToAddres) + { + if (this.warnAndCheckConditionsForSendingBackChange(sourceAddress, destinationAddress, amount, memo, fee)) + { + String balance = this.clientCaller.getBalanceForAddress(sourceAddress); + // Call the send method with change going back to source address + operationStatusID = this.clientCaller.sendCashWithReturnOfChange(sourceAddress, destinationAddress, balance, amount, memo, fee); + } else + { + return; // Stop the operation + } + } else + { + // Call the wallet send method - old style + operationStatusID = this.clientCaller.sendCash(sourceAddress, destinationAddress, amount, memo, fee); + } + + // Make sure the keypool has spare addresses + if ((this.backupTracker.getNumTransactionsSinceLastBackup() % 5) == 0) + { + this.clientCaller.keypoolRefill(100); + } + } finally + { + this.getRootPane().getParent().setCursor(oldCursor); } // Disable controls after send + sendChangeBackToSourceAddress.setEnabled(false); sendButton.setEnabled(false); balanceAddressCombo.setEnabled(false); destinationAddressField.setEnabled(false); @@ -513,8 +660,10 @@ private void sendCash() destinationMemoField.setEnabled(false); transactionFeeField.setEnabled(false); - // Start a data gathering thread specific to the operation being executed - this is done is a separate - // thread since the server responds more slowly during JoinSPlits and this blocks he GUI somewhat. + + final boolean bEncryptedWalletForThread = bEncryptedWallet; + // Start a data gathering thread specific to the operation being executed - this is done in a separate + // thread since the server responds more slowly during JoinSplits and this blocks the GUI somewhat. final DataGatheringThread opFollowingThread = new DataGatheringThread( new DataGatheringThread.DataGatherer() { @@ -552,7 +701,7 @@ public void actionPerformed(ActionEvent e) amount, sourceAddress, destinationAddress); // Lock the wallet again - if (bEncryptedWallet) + if (bEncryptedWalletForThread) { SendCashPanel.this.clientCaller.lockWallet(); } @@ -564,6 +713,7 @@ public void actionPerformed(ActionEvent e) operationStatusTimer = null; operationStatusProhgressBar.setValue(0); + sendChangeBackToSourceAddress.setEnabled(true); sendButton.setEnabled(true); balanceAddressCombo.setEnabled(true); destinationAddressField.setEnabled(true); @@ -573,8 +723,7 @@ public void actionPerformed(ActionEvent e) } else { // Update the progress - operationStatusLabel.setText( - "IN PROGRESS"); + operationStatusLabel.setText(langUtil.getString("send.cash.panel.operation.status.progress.label")); operationStatusCounter += 2; int progress = 0; if (operationStatusCounter <= 100) @@ -609,6 +758,13 @@ public void prepareForSending(String address) private void updateWalletAddressPositiveBalanceComboBox() throws WalletCallException, IOException, InterruptedException { + // If the user has opened the combo box menu - skip update + if (this.balanceAddressCombo.isMenuDown()) + { + Log.info("Skipping refresh of available sending addresses - user menu is open..."); + return; + } + String[][] newAddressBalanceData = this.addressBalanceGatheringThread.getLastData(); // The data may be null if nothing is yet obtained @@ -617,27 +773,64 @@ private void updateWalletAddressPositiveBalanceComboBox() return; } + final int oldSelectedIndex = this.balanceAddressCombo.getSelectedIndex(); + String originalSelectedAddress = null; + if ((this.lastAddressBalanceData != null) && (this.lastAddressBalanceData.length > 0) && + (this.lastAddressBalanceData.length > oldSelectedIndex) && + (balanceAddressCombo.getItemCount() > 0) && (oldSelectedIndex >= 0)) + { + originalSelectedAddress = this.lastAddressBalanceData[oldSelectedIndex][1]; + } + lastAddressBalanceData = newAddressBalanceData; comboBoxItems = new String[lastAddressBalanceData.length]; for (int i = 0; i < lastAddressBalanceData.length; i++) { + // Form the current combo item for sending cash. If an address label is available, it gets + // displayed first. If the overall string is too long it gets cut at 120 chars + String address = lastAddressBalanceData[i][1]; + String formattedBalance = new DecimalFormat("########0.00######").format(Double.valueOf(lastAddressBalanceData[i][0])); + String label = this.labelStorage.getLabel(address); // Empty str if not found + if (label.length() > 0) + { + label = "[" + label + "] "; + } + String item = label + formattedBalance + " ZEN - " + address; + if (item.length() > 120) + { + item = item.substring(0, 118) + "..."; + } + // Do numeric formatting or else we may get 1.1111E-5 - comboBoxItems[i] = - new DecimalFormat("########0.00######").format(Double.valueOf(lastAddressBalanceData[i][0])) + - " - " + lastAddressBalanceData[i][1]; + comboBoxItems[i] = item; } - int selectedIndex = balanceAddressCombo.getSelectedIndex(); - boolean isEnabled = balanceAddressCombo.isEnabled(); + final boolean isEnabled = this.balanceAddressCombo.isEnabled(); this.comboBoxParentPanel.remove(balanceAddressCombo); - balanceAddressCombo = new JComboBox<>(comboBoxItems); + balanceAddressCombo = new DropdownComboBox<>(comboBoxItems); comboBoxParentPanel.add(balanceAddressCombo); - if ((balanceAddressCombo.getItemCount() > 0) && - (selectedIndex >= 0) && - (balanceAddressCombo.getItemCount() > selectedIndex)) + // We need to restore the previously selected address in the combo box + // The address count/order may have changed as a result of newly confirmed + // transactions, necessitating additional checks. + int newIndexToSelect = oldSelectedIndex; // By default index does not change + // Try to find the original selected address in the new data - its index may be different + // after the data was updated + for (int i = 0; i < this.lastAddressBalanceData.length; i++) { - balanceAddressCombo.setSelectedIndex(selectedIndex); + String currentAddress = this.lastAddressBalanceData[i][1]; + if ((currentAddress != null) && (originalSelectedAddress != null) && + currentAddress.trim().equalsIgnoreCase(originalSelectedAddress.trim())) + { + newIndexToSelect = i; + } + } + // Restore only the selected index - original address was found (perhaps) + if ((balanceAddressCombo.getItemCount() > 0) && + (newIndexToSelect >= 0) && + (balanceAddressCombo.getItemCount() > newIndexToSelect)) + { + balanceAddressCombo.setSelectedIndex(newIndexToSelect); } balanceAddressCombo.setEnabled(isEnabled); @@ -713,20 +906,19 @@ private void reportCompleteOperationToTheUser(String amount, String sourceAddres { if (clientCaller.isCompletedOperationSuccessful(operationStatusID)) { - operationStatusLabel.setText( - "SUCCESSFUL"); + operationStatusLabel.setText(langUtil.getString("send.cash.panel.operation.status.success.label")); String TXID = clientCaller.getSuccessfulOperationTXID(operationStatusID); - Object[] options = { "OK", "Copy transaction ID", "View on the blockchain" }; + Object[] options = langUtil.getString("send.cash.panel.operation.complete.report").split(":"); int option = JOptionPane.showOptionDialog( - SendCashPanel.this.getRootPane().getParent(), - "Succesfully sent " + amount + " ZEN from address: \n" + - sourceAddress + "\n" + - "to address: \n" + - destinationAddress + "\n\n" + - "Transaction ID: " + TXID, - "Cash sent successfully", + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.operation.complete.report.success.text", + amount, + sourceAddress, + destinationAddress, + TXID), + langUtil.getString("send.cash.panel.operation.complete.report.success.title"), JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, @@ -757,15 +949,98 @@ private void reportCompleteOperationToTheUser(String amount, String sourceAddres { String errorMessage = clientCaller.getOperationFinalErrorMessage(operationStatusID); operationStatusLabel.setText( - "ERROR: " + errorMessage + ""); + langUtil.getString("send.cash.panel.operation.status.error.label", errorMessage)); JOptionPane.showMessageDialog( SendCashPanel.this.getRootPane().getParent(), - "An error occurred when sending cash. Error message is:\n" + - errorMessage + "\n\n" + - "Please ensure that sending parameters are correct. You may try again later...\n", - "Error in sending cash", JOptionPane.ERROR_MESSAGE); + langUtil.getString("send.cash.panel.option.pane.error.report.text",errorMessage), + langUtil.getString("send.cash.panel.option.pane.error.report.title"), JOptionPane.ERROR_MESSAGE); + + } + } + + + // Checks if a number has more than 8 fractional digits. This is not normally allowed for ZEN + // Input must be a decimal number! + private boolean hasExcessiveFractionalDigits(String field) + { + BigDecimal num = new BigDecimal(field); + DecimalFormatSymbols decSymbols = new DecimalFormatSymbols(Locale.ROOT); + DecimalFormat longFormat = new DecimalFormat("############################0.00###############################", decSymbols); + String formattedNumber = longFormat.format(num); + String fractionalPart = formattedNumber.substring(formattedNumber.indexOf(".") + 1); + + if (fractionalPart.length() > 8) + { + return true; + } + + return false; + } + + + /** + * Checks the conditions necessary for sending back the change. Also issues a warning to the user on the nature of this operation. + * + * @param sourceAddress + * @param destinationAddress + * @param amount + * @param memo + * @param fee + * + * @return true if all conditions are met and the user has not cancelled the operation + */ + private boolean warnAndCheckConditionsForSendingBackChange(String sourceAddress, String destinationAddress, String amount, String memo, String fee) + throws WalletCallException, InterruptedException, IOException + { + String balance = this.clientCaller.getBalanceForAddress(sourceAddress); + + // Get a confirmation from the user about the operation - general warning + String userDir = OSUtil.getSettingsDirectory(); + File sendChangeBackNotToBeShownFlagFile = new File(userDir + File.separator + "sendBackChangeWarningNotToBeShown.flag"); + if (!sendChangeBackNotToBeShownFlagFile.exists()) + { + Object[] options = + { + langUtil.getString("send.cash.panel.option.pane.confirm.operation.button.yes"), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.button.no"), + langUtil.getString("send.cash.panel.option.pane.confirm.operation.button.not.again") + }; + int option = JOptionPane.showOptionDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.send.change.back.general.warning"), + langUtil.getString("send.cash.panel.send.change.back.general.warning.title"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.WARNING_MESSAGE, + null, + options, + options[0]); + + if (option == 2) + { + sendChangeBackNotToBeShownFlagFile.createNewFile(); + } + + // on "no" or close ("X") + if (option == 1 || option == -1) + { + return false; + } + } + + // Make sure the confirmed balance for the address is sufficient + if (new BigDecimal(balance).subtract(new BigDecimal(amount)).subtract(new BigDecimal(fee)).compareTo(new BigDecimal("0")) < 0) + { + JOptionPane.showMessageDialog( + SendCashPanel.this.getRootPane().getParent(), + langUtil.getString("send.cash.panel.insufficient.balance", sourceAddress, balance, amount, fee), + langUtil.getString("send.cash.panel.insufficient.balance.title"), + JOptionPane.ERROR_MESSAGE); + + return false; } + + return true; } } diff --git a/src/java/com/vaklinov/zcashui/SingleKeyImportDialog.java b/src/java/com/vaklinov/zcashui/SingleKeyImportDialog.java index aa57e77c..f3b24896 100644 --- a/src/java/com/vaklinov/zcashui/SingleKeyImportDialog.java +++ b/src/java/com/vaklinov/zcashui/SingleKeyImportDialog.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -50,8 +51,6 @@ /** * Dialog to enter a single private key to import - * - * @author Ivan Vaklinov */ public class SingleKeyImportDialog extends JDialog @@ -68,6 +67,8 @@ public class SingleKeyImportDialog protected JProgressBar progress = null; protected ZCashClientCaller caller; + + private LanguageUtil langUtil; JButton okButon; JButton cancelButon; @@ -76,8 +77,8 @@ public SingleKeyImportDialog(JFrame parent, ZCashClientCaller caller) { super(parent); this.caller = caller; - - this.setTitle("Enter private key..."); + langUtil = LanguageUtil.instance(); + this.setTitle(langUtil.getString("single.key.import.dialog.title")); this.setLocation(parent.getLocation().x + 50, parent.getLocation().y + 50); this.setModal(true); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); @@ -88,8 +89,8 @@ public SingleKeyImportDialog(JFrame parent, ZCashClientCaller caller) JPanel tempPanel = new JPanel(new BorderLayout(0, 0)); tempPanel.add(this.upperLabel = new JLabel( - "Please enter a single private key to import." + - ""), BorderLayout.CENTER); + langUtil.getString("single.key.import.dialog.tmp.panel")), + BorderLayout.CENTER); controlsPanel.add(tempPanel); JLabel dividerLabel = new JLabel(" "); @@ -97,7 +98,7 @@ public SingleKeyImportDialog(JFrame parent, ZCashClientCaller caller) controlsPanel.add(dividerLabel); tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - tempPanel.add(keyLabel = new JLabel("Key: ")); + tempPanel.add(keyLabel = new JLabel(langUtil.getString("single.key.import.dialog.tmp.panel.key.label"))); tempPanel.add(keyField = new JTextField(60)); controlsPanel.add(tempPanel); @@ -107,11 +108,8 @@ public SingleKeyImportDialog(JFrame parent, ZCashClientCaller caller) tempPanel = new JPanel(new BorderLayout(0, 0)); tempPanel.add(this.lowerLabel = new JLabel( - "" + - "Warning: Private key import is a slow operation that " + - "requires blockchain rescanning (may take many minutes).
The GUI " + - "will not be usable for other functions during this time"), - BorderLayout.CENTER); + langUtil.getString("single.key.import.dialog.tmp.panel.key.lower.label")), + BorderLayout.CENTER); controlsPanel.add(tempPanel); dividerLabel = new JLabel(" "); @@ -128,10 +126,10 @@ public SingleKeyImportDialog(JFrame parent, ZCashClientCaller caller) // Form buttons JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3)); - okButon = new JButton("Import"); + okButon = new JButton(langUtil.getString("single.key.import.dialog.tmp.panel.ok.button.text")); buttonPanel.add(okButon); buttonPanel.add(new JLabel(" ")); - cancelButon = new JButton("Cancel"); + cancelButon = new JButton(langUtil.getString("single.key.import.dialog.tmp.panel.cancel.button.text")); buttonPanel.add(cancelButon); this.getContentPane().add(buttonPanel, BorderLayout.SOUTH); @@ -173,7 +171,8 @@ protected void processOK() { JOptionPane.showMessageDialog( SingleKeyImportDialog.this.getParent(), - "The key is empty. Please enter it into the text field.", "Empty...", + langUtil.getString("single.key.import.dialog.tmp.panel.process.ok.message"), + langUtil.getString("single.key.import.dialog.tmp.panel.process.ok.title"), JOptionPane.ERROR_MESSAGE); return; } @@ -203,15 +202,13 @@ public void run() if (!Util.stringIsEmpty(address)) { - addition = " It corresponds to address:\n" + address; + addition = langUtil.getString("single.key.import.dialog.tmp.panel.process.ok.addition", address); } JOptionPane.showMessageDialog( SingleKeyImportDialog.this, - "The private key:\n" + - key + "\n" + - "has been imported successfully." + addition, - "Private key imported successfully...", + langUtil.getString("single.key.import.dialog.tmp.panel.success.message", key, addition), + langUtil.getString("single.key.import.dialog.tmp.panel.success.title"), JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { @@ -219,11 +216,9 @@ public void run() JOptionPane.showMessageDialog( SingleKeyImportDialog.this.getRootPane().getParent(), - "An error occurred when importing private key. Error message is:\n" + - e.getClass().getName() + ":\n" + e.getMessage() + "\n\n" + - "Please ensure that zend is running and the key is in the correct \n" + - "form. You may try again later...\n", - "Error in importing private key", JOptionPane.ERROR_MESSAGE); + langUtil.getString("single.key.import.dialog.tmp.panel.error.message", e.getClass().getName(), e.getMessage()), + langUtil.getString("single.key.import.dialog.tmp.panel.error.title"), + JOptionPane.ERROR_MESSAGE); } finally { SingleKeyImportDialog.this.setVisible(false); diff --git a/src/java/com/vaklinov/zcashui/StartupProgressDialog.java b/src/java/com/vaklinov/zcashui/StartupProgressDialog.java index a7133f1c..6bbfaf32 100644 --- a/src/java/com/vaklinov/zcashui/StartupProgressDialog.java +++ b/src/java/com/vaklinov/zcashui/StartupProgressDialog.java @@ -54,15 +54,13 @@ public StartupProgressDialog(ZCashClientCaller clientCaller) URL iconUrl = this.getClass().getClassLoader().getResource("images/ZEN-yellow.orange-logo.png"); imageIcon = new ImageIcon(iconUrl); imageLabel.setIcon(imageIcon); - imageLabel.setBorder(BorderFactory.createEmptyBorder(16, 16, 0, 16)); + imageLabel.setBorder(BorderFactory.createEmptyBorder(16, 40, 8, 40)); Container contentPane = getContentPane(); contentPane.setLayout(borderLayout1); southPanel.setLayout(southPanelLayout); southPanel.setBorder(BorderFactory.createEmptyBorder(0, 16, 16, 16)); contentPane.add(imageLabel, BorderLayout.NORTH); - JLabel zcashWalletLabel = new JLabel( - "" + - "ZENCash Wallet"); + JLabel zcashWalletLabel = new JLabel(LanguageUtil.instance().getString("startup.progress.dialog.label")); zcashWalletLabel.setBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16)); // todo - place in a panel with flow center JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 1, 1)); @@ -71,7 +69,7 @@ public StartupProgressDialog(ZCashClientCaller clientCaller) contentPane.add(southPanel, BorderLayout.SOUTH); progressBar.setIndeterminate(true); southPanel.add(progressBar, BorderLayout.NORTH); - progressLabel.setText("Starting..."); + progressLabel.setText(LanguageUtil.instance().getString("startup.progress.dialog.progressbar.label")); southPanel.add(progressLabel, BorderLayout.SOUTH); pack(); setLocationRelativeTo(null); @@ -82,7 +80,7 @@ public StartupProgressDialog(ZCashClientCaller clientCaller) public void waitForStartup() throws IOException, InterruptedException,WalletCallException,InvocationTargetException { - // special handling of Windows/Mac OS app launch + // special handling of Windows/macOS app launch OS_TYPE os = OSUtil.getOSType(); if ((os == OS_TYPE.WINDOWS) || (os == OS_TYPE.MAC_OS)) { @@ -131,7 +129,11 @@ public void waitForStartup() throws IOException, info = clientCaller.getDaemonRawRuntimeInfo(); } catch (IOException e) { - if (iteration > 4) + // We expect that within 20+ seconds the zend will at least show some signs of life + // like being able to report that it is loading the block index etc. + // So we have 15 iterations of 1.5 sec. of waiting. If after this time zend is not yet + // there - we assume something is wrong and an error is reported. + if (iteration > 15) { throw e; } else @@ -165,7 +167,7 @@ public void run() { long end = System.currentTimeMillis(); Log.info("Waiting for " + ((end - start) / 1000) + " seconds for zend to exit..."); - if (end - start > 10 * 1000) + if (end - start > 15 * 1000) { clientCaller.stopDaemon(); daemonProcess.destroy(); @@ -206,6 +208,7 @@ public void setProgressText(final String text) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { + Log.info("Startup progress info: {0}", text); progressLabel.setText(text); } }); diff --git a/src/java/com/vaklinov/zcashui/StatusUpdateErrorReporter.java b/src/java/com/vaklinov/zcashui/StatusUpdateErrorReporter.java index efed4a3c..cac783c4 100644 --- a/src/java/com/vaklinov/zcashui/StatusUpdateErrorReporter.java +++ b/src/java/com/vaklinov/zcashui/StatusUpdateErrorReporter.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,8 +34,6 @@ /** * Reporter for periodic errors. Will later have options to filter errors etc. - * - * @author Ivan Vaklinov */ public class StatusUpdateErrorReporter { @@ -81,10 +80,8 @@ public void reportError(Exception e, boolean isDueToAutomaticUpdate) JOptionPane.showMessageDialog( parent, - "An unexpected error occurred during the operation of the GUI wallet.\n" + - "Details may be found in the log in directory: " + settingsDirectory + "\n" + - "\n" + - e.getMessage(), - "Error in wallet operation.", JOptionPane.ERROR_MESSAGE); + LanguageUtil.instance().getString("status.update.error.reporter.panel.message",settingsDirectory, e.getMessage()), + LanguageUtil.instance().getString("status.update.error.reporter.panel.title"), + JOptionPane.ERROR_MESSAGE); } } diff --git a/src/java/com/vaklinov/zcashui/TransactionTable.java b/src/java/com/vaklinov/zcashui/TransactionTable.java index 73d88f99..71a3417f 100644 --- a/src/java/com/vaklinov/zcashui/TransactionTable.java +++ b/src/java/com/vaklinov/zcashui/TransactionTable.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -58,11 +59,10 @@ import javax.swing.KeyStroke; import javax.swing.border.EtchedBorder; +//TODO /** * Table to be used for transactions - specifically. - * - * @author Ivan Vaklinov */ public class TransactionTable extends DataTable @@ -73,7 +73,7 @@ public TransactionTable(final Object[][] rowData, final Object[] columnNames, { super(rowData, columnNames); int accelaratorKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - + final LanguageUtil langUtil = LanguageUtil.instance(); JMenuItem showDetails = new JMenuItem("Show details..."); showDetails.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, accelaratorKeyMask)); popupMenu.add(showDetails); @@ -109,7 +109,7 @@ public void actionPerformed(ActionEvent e) }); - JMenuItem showInExplorer = new JMenuItem("Show in block explorer"); + JMenuItem showInExplorer = new JMenuItem(langUtil.getString("transactions.table.show.in.explorer")); showInExplorer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, accelaratorKeyMask)); popupMenu.add(showInExplorer); @@ -146,7 +146,7 @@ public void actionPerformed(ActionEvent e) } }); - JMenuItem showMemoField = new JMenuItem("Get transaction memo"); + JMenuItem showMemoField = new JMenuItem(langUtil.getString("transactions.table.memo.field")); showMemoField.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, accelaratorKeyMask)); popupMenu.add(showMemoField); @@ -163,7 +163,14 @@ public void actionPerformed(ActionEvent e) String txID = TransactionTable.this.getModel().getValueAt(lastRow, 6).toString(); txID = txID.replaceAll("\"", ""); // In case it has quotes + String acc = TransactionTable.this.getModel().getValueAt(lastRow, 5).toString(); + // TODO: better way to remove a label if it preceeds + if (acc.contains(" - ")) + { + acc = acc.substring(acc.lastIndexOf(" - ") + 3); + } + acc = acc.replaceAll("\"", ""); // In case it has quotes boolean isZAddress = Util.isZAddress(acc); @@ -171,10 +178,8 @@ public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog( parent, - "The selected transaction does not have as destination a Z (private) \n" + - "address or it is unkonwn (not listed) and thus no memo information \n" + - "about this transaction is available.", - "Memo information is unavailable", + langUtil.getString("transactions.table.memo.unavailable.text"), + langUtil.getString("transactions.table.memo.unavailable.title"), JOptionPane.ERROR_MESSAGE); return; } @@ -183,7 +188,7 @@ public void actionPerformed(ActionEvent e) Log.info("Transaction ID for Memo field is: " + txID); Log.info("Account for Memo field is: " + acc); parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - // TODO: some day support outgoing Z transactions + // TODO: someday support outgoing Z transactions String MemoField = caller.getMemoField(acc, txID); parent.setCursor(oldCursor); Log.info("Memo field is: " + MemoField); @@ -196,16 +201,15 @@ public void actionPerformed(ActionEvent e) MemoField = Util.blockWrapString(MemoField, 80); JOptionPane.showMessageDialog( parent, - "The memo contained in the transaction is: \n" + MemoField + - "\n\n" + - "(The memo has also been copied to the clipboard.)", - "Memo", JOptionPane.PLAIN_MESSAGE); + langUtil.getString("transactions.table.memo.clipboard.text", MemoField), + langUtil.getString("transactions.table.memo.clipboard.title"), + JOptionPane.PLAIN_MESSAGE); } else { JOptionPane.showMessageDialog( parent, - "The selected transaction does not contain a memo field.", - "Memo field is not available...", + langUtil.getString("transactions.table.memo.field.missing.text"), + langUtil.getString("transactions.table.memo.field.missing.title"), JOptionPane.ERROR_MESSAGE); } } catch (Exception ex) @@ -232,7 +236,8 @@ private static class DetailsDialog public DetailsDialog(JFrame parent, Map details) throws UnsupportedEncodingException { - this.setTitle("Transaction details..."); + LanguageUtil langUtil = LanguageUtil.instance(); + this.setTitle(langUtil.getString("transaction.table.details.dialog.title")); this.setSize(600, 310); this.setLocation(100, 100); this.setLocationRelativeTo(parent); @@ -244,15 +249,12 @@ public DetailsDialog(JFrame parent, Map details) JPanel tempPanel = new JPanel(new BorderLayout(0, 0)); tempPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); JLabel infoLabel = new JLabel( - "" + - "The table shows the information about the transaction with technical details as " + - "they appear at ZENCash network level." + - ""); + langUtil.getString("transaction.table.details.dialog.info.label")); infoLabel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); tempPanel.add(infoLabel, BorderLayout.CENTER); this.getContentPane().add(tempPanel, BorderLayout.NORTH); - String[] columns = new String[] { "Name", "Value" }; + String[] columns = langUtil.getString("transaction.table.details.dialog.column.names").split(":"); String[][] data = new String[details.size()][2]; int i = 0; int maxPreferredWidht = 400; @@ -293,7 +295,7 @@ public boolean equals(Object obj) // Lower close button JPanel closePanel = new JPanel(); closePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3)); - JButton closeButon = new JButton("Close"); + JButton closeButon = new JButton(langUtil.getString("transaction.table.details.dialog.button.close")); closePanel.add(closeButon); this.getContentPane().add(closePanel, BorderLayout.SOUTH); diff --git a/src/java/com/vaklinov/zcashui/TransactionsDetailPanel.java b/src/java/com/vaklinov/zcashui/TransactionsDetailPanel.java new file mode 100644 index 00000000..b844d7c4 --- /dev/null +++ b/src/java/com/vaklinov/zcashui/TransactionsDetailPanel.java @@ -0,0 +1,343 @@ +/************************************************************************************************ + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **********************************************************************************/ +package com.vaklinov.zcashui; + + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; + +import javax.swing.BorderFactory; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.Timer; + +import com.vaklinov.zcashui.OSUtil.OS_TYPE; +import com.vaklinov.zcashui.ZCashClientCaller.WalletCallException; + + +/** + * Transaction details panel (separate UI TAB). + */ +public class TransactionsDetailPanel + extends WalletTabPanel +{ + private JFrame parentFrame; + private JTabbedPane parentTabs; + + private ZCashClientCaller clientCaller; + private StatusUpdateErrorReporter errorReporter; + private ZCashInstallationObserver installationObserver; + + private String OSInfo = null; + + private JTable transactionsTable = null; + private JScrollPane transactionsTablePane = null; + private String[][] lastTransactionsData = null; + private DataGatheringThread transactionGatheringThread = null; + private LanguageUtil langUtil; + + // Storage of labels + private LabelStorage labelStorage; + + public TransactionsDetailPanel(JFrame parentFrame, + JTabbedPane parentTabs, + ZCashInstallationObserver installationObserver, + ZCashClientCaller clientCaller, + StatusUpdateErrorReporter errorReporter, + DataGatheringThread transactionGatheringThread, + LabelStorage labelStorage) + throws IOException, InterruptedException, WalletCallException + { + this.parentFrame = parentFrame; + this.parentTabs = parentTabs; + + this.clientCaller = clientCaller; + this.errorReporter = errorReporter; + this.installationObserver = installationObserver; + this.transactionGatheringThread = transactionGatheringThread; + this.labelStorage = labelStorage; + + this.timers = new ArrayList(); + this.threads = new ArrayList>(); + + langUtil = LanguageUtil.instance(); + // Build content + JPanel dashboard = this; + dashboard.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); + dashboard.setLayout(new BorderLayout(0, 0)); + + // Table of transactions + lastTransactionsData = getTransactionsDataFromWallet(); + dashboard.add(transactionsTablePane = new JScrollPane( + transactionsTable = this.createTransactionsTable(lastTransactionsData)), + BorderLayout.CENTER); + + ActionListener alTransactions = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) + { + try + { + TransactionsDetailPanel.this.updateWalletTransactionsTable(); + } catch (Exception ex) + { + Log.error("Unexpected error: ", ex); + TransactionsDetailPanel.this.errorReporter.reportError(ex); + } + } + }; + Timer t = new Timer(5000, alTransactions); + t.start(); + this.timers.add(t); + } + + + // Called from outside when the user want to zoom on a transaction + public void selectTransactionWithID(String transactionID) + { + int index = -1; + + if (this.lastTransactionsData != null) + { + int i = 0; + for (String[] currentTX : this.lastTransactionsData) + { + if ((currentTX[6] != null) && (currentTX[6].equals(transactionID))) + { + index = i; + break; + } + i++; + } + + this.transactionsTable.clearSelection(); + this.transactionsTable.setRowSelectionInterval(index, index); + + // Switch TABs + this.parentTabs.setSelectedIndex(1); + } + } + + + private void updateWalletTransactionsTable() + throws WalletCallException, IOException, InterruptedException + { + String[][] newTransactionsDataOrig = this.transactionGatheringThread.getLastData(); + + // May be null - not even gathered once + if (newTransactionsDataOrig == null) + { + return; + } + + // Copy the data to a new array + String[][] newTransactionsData = new String[newTransactionsDataOrig.length][]; + // Add wallet labels to the transaction data + for (int i = 0; i < newTransactionsDataOrig.length; i++) + { + newTransactionsData[i] = newTransactionsDataOrig[i].clone(); + String address = newTransactionsData[i][5]; + if ((address != null) && (address.length() > 0)) + { + String label = this.labelStorage.getLabel(address); + if ((label != null) && (label.length() > 0)) + { + address = label + " - " + address; + } + } + newTransactionsData[i][5] = address; + } + + if (Util.arraysAreDifferent(lastTransactionsData, newTransactionsData)) + { + Log.info("Updating table of transactions..."); + this.remove(transactionsTablePane); + this.add(transactionsTablePane = new JScrollPane( + transactionsTable = this.createTransactionsTable(newTransactionsData)), + BorderLayout.CENTER); + } + + lastTransactionsData = newTransactionsData; + + this.validate(); + this.repaint(); + } + + + private JTable createTransactionsTable(String rowData[][]) + throws WalletCallException, IOException, InterruptedException + { + String columnNames[] = langUtil.getString("transactions.detail.panel.column.names").split(":"); + JTable table = new TransactionTable( + rowData, columnNames, this.parentFrame, this.clientCaller, this.installationObserver); + table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); + table.getColumnModel().getColumn(0).setPreferredWidth(190); + table.getColumnModel().getColumn(1).setPreferredWidth(145); + table.getColumnModel().getColumn(2).setPreferredWidth(170); + table.getColumnModel().getColumn(3).setPreferredWidth(210); + table.getColumnModel().getColumn(4).setPreferredWidth(405); + table.getColumnModel().getColumn(5).setPreferredWidth(800); + + return table; + } + + + // TODO: duplication with dashboard ... + private String[][] getTransactionsDataFromWallet() + throws WalletCallException, IOException, InterruptedException + { + // Get available public+private transactions and unify them. + String[][] publicTransactions = this.clientCaller.getWalletPublicTransactions(); + String[][] zReceivedTransactions = this.clientCaller.getWalletZReceivedTransactions(); + + String[][] allTransactions = new String[publicTransactions.length + zReceivedTransactions.length][]; + + int i = 0; + + for (String[] t : publicTransactions) + { + allTransactions[i++] = t; + } + + for (String[] t : zReceivedTransactions) + { + allTransactions[i++] = t; + } + + // Sort transactions by date + Arrays.sort(allTransactions, new Comparator() { + public int compare(String[] o1, String[] o2) + { + Date d1 = new Date(0); + if ((!o1[4].equals("N/A")) && Util.isNumeric(o1[4])) + { + d1 = new Date(Long.valueOf(o1[4]).longValue() * 1000L); + } + + Date d2 = new Date(0); + if (!o2[4].equals("N/A") && Util.isNumeric(o2[4])) + { + d2 = new Date(Long.valueOf(o2[4]).longValue() * 1000L); + } + + if (d1.equals(d2)) + { + return 0; + } else + { + return d2.compareTo(d1); + } + } + }); + + + // Confirmation symbols + String confirmed = "\u2690"; + String notConfirmed = "\u2691"; + + // Windows does not support the flag symbol (Windows 7 by default) + // TODO: isolate OS-specific symbol codes in a separate class + OS_TYPE os = OSUtil.getOSType(); + if (os == OS_TYPE.WINDOWS) + { + confirmed = " \u25B7"; + notConfirmed = " \u25B6"; + } + + DecimalFormat df = new DecimalFormat("########0.00######"); + + // Change the direction and date etc. attributes for presentation purposes + for (String[] trans : allTransactions) + { + // Direction + if (trans[1].equals("receive")) + { + trans[1] = "\u21E8 IN"; + } else if (trans[1].equals("send")) + { + trans[1] = "\u21E6 OUT"; + } else if (trans[1].equals("generate")) + { + trans[1] = "\u2692\u2699 MINED"; + } else if (trans[1].equals("immature")) + { + trans[1] = "\u2696 Immature"; + }; + + // Date + if ((!trans[4].equals("N/A")) && Util.isNumeric(trans[4])) + { + trans[4] = new Date(Long.valueOf(trans[4]).longValue() * 1000L).toLocaleString(); + } + + // Amount + try + { + double amount = Double.valueOf(trans[3]); + if (amount < 0d) + { + amount = -amount; + } + trans[3] = df.format(amount); + } catch (NumberFormatException nfe) + { + Log.error("Error occurred while formatting amount: " + trans[3] + + " - " + nfe.getMessage() + "!"); + } + + // Confirmed? + try + { + boolean isConfirmed = !trans[2].trim().equals("0"); + + trans[2] = isConfirmed ? (langUtil.getString("transactions.detail.panel.yes", confirmed)) + : (langUtil.getString("transactions.detail.panel.no", notConfirmed)); + } catch (NumberFormatException nfe) + { + Log.error("Error occurred while formatting confirmations: " + trans[2] + + " - " + nfe.getMessage() + "!"); + } + } + + + return allTransactions; + } + +} // End class diff --git a/src/java/com/vaklinov/zcashui/Util.java b/src/java/com/vaklinov/zcashui/Util.java index e63d2b59..ccf68017 100644 --- a/src/java/com/vaklinov/zcashui/Util.java +++ b/src/java/com/vaklinov/zcashui/Util.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,7 +31,9 @@ import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.RandomAccessFile; import java.io.Reader; @@ -40,7 +43,9 @@ import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; @@ -48,127 +53,135 @@ /** * Utilities - generally reusable across classes. - * - * @author Ivan Vaklinov */ public class Util { - // Compares two string arrays (two dimensional). - public static boolean arraysAreDifferent(String ar1[][], String ar2[][]) - { - if (ar1 == null) - { - if (ar2 != null) - { - return true; - } - } else if (ar2 == null) - { - return true; - } - - if (ar1.length != ar2.length) - { - return true; - } - - for (int i = 0; i < ar1.length; i++) - { - if (ar1[i].length != ar2[i].length) - { - return true; - } - - for (int j = 0; j < ar1[i].length; j++) - { - String s1 = ar1[i][j]; - String s2 = ar2[i][j]; - - if (s1 == null) - { - if (s2 != null) - { - return true; - } - } else if (s2 == null) - { - return true; - } else - { - if (!s1.equals(s2)) - { - return true; - } - } - } - } - - return false; - } - - - // Turns a 1.0.7+ error message to a an old JSOn style message - // info - new style error message - public static JsonObject getJsonErrorMessage(String info) - throws IOException - { - JsonObject jInfo = new JsonObject(); - - // Error message here comes from ZCash 1.0.7+ and is like: - //zcash-cli getinfo - //error code: -28 - //error message: - //Loading block index... - LineNumberReader lnr = new LineNumberReader(new StringReader(info)); - int errCode = Integer.parseInt(lnr.readLine().substring(11).trim()); - jInfo.set("code", errCode); - lnr.readLine(); - jInfo.set("message", lnr.readLine().trim()); - - return jInfo; - } - - - /** - * Escapes a text value to a form suitable to be displayed in HTML content. Important control - * characters are replaced with entities. - * - * @param inputValue th value to escape - * - * @return the "safe" value to display. - */ - public static String escapeHTMLValue(String inputValue) - { - StringBuilder outputValue = new StringBuilder(); - for (char c : inputValue.toCharArray()) - { - if ((c > 127) || (c == '"') || (c == '<') || (c == '>') || (c == '&')) - { - outputValue.append("&#"); - outputValue.append((int)c); - outputValue.append(';'); - } else - { - outputValue.append(c); - } - } - return outputValue.toString(); - } - - - public static boolean stringIsEmpty(String s) - { - return (s == null) || (s.length() <= 0); - } - - - public static String decodeHexMemo(String memoHex) - throws UnsupportedEncodingException - { + // Compares two string arrays (two dimensional). + public static boolean arraysAreDifferent(String ar1[][], String ar2[][]) + { + if (ar1 == null) + { + if (ar2 != null) + { + return true; + } + } else if (ar2 == null) + { + return true; + } + + if (ar1.length != ar2.length) + { + return true; + } + + for (int i = 0; i < ar1.length; i++) + { + if (ar1[i].length != ar2[i].length) + { + return true; + } + + for (int j = 0; j < ar1[i].length; j++) + { + String s1 = ar1[i][j]; + String s2 = ar2[i][j]; + + if (s1 == null) + { + if (s2 != null) + { + return true; + } + } else if (s2 == null) + { + return true; + } else + { + if (!s1.equals(s2)) + { + return true; + } + } + } + } + + return false; + } + + public static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray(); + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } + + // Turns a 1.0.7+ error message to an old JSON style message + // info - new style error message + public static JsonObject getJsonErrorMessage(String info) + throws IOException + { + JsonObject jInfo = new JsonObject(); + + // Error message here comes from ZCash 1.0.7+ and is like: + //zcash-cli getinfo + //error code: -28 + //error message: + //Loading block index... + LineNumberReader lnr = new LineNumberReader(new StringReader(info)); + int errCode = Integer.parseInt(lnr.readLine().substring(11).trim()); + jInfo.set("code", errCode); + lnr.readLine(); + jInfo.set("message", lnr.readLine().trim()); + + return jInfo; + } + + + /** + * Escapes a text value to a form suitable to be displayed in HTML content. Important control + * characters are replaced with entities. + * + * @param inputValue the value to escape + * + * @return the "safe" value to display. + */ + public static String escapeHTMLValue(String inputValue) + { + StringBuilder outputValue = new StringBuilder(); + for (char c : inputValue.toCharArray()) + { + if ((c > 127) || (c == '"') || (c == '<') || (c == '>') || (c == '&')) + { + outputValue.append("&#"); + outputValue.append((int)c); + outputValue.append(';'); + } else + { + outputValue.append(c); + } + } + return outputValue.toString(); + } + + + public static boolean stringIsEmpty(String s) + { + return (s == null) || (s.length() <= 0); + } + + + public static String decodeHexMemo(String memoHex) + throws UnsupportedEncodingException + { // Skip empty memos if (memoHex.startsWith("f600000000")) { - return null; + return null; } // should be read with UTF-8 @@ -185,123 +198,123 @@ public static String decodeHexMemo(String memoHex) // TODO: may cause problems if UNICODE chars have trailing ZEROS while (count > 0) { - if (bytes[count - 1] == 0) - { - count--; - } else - { - break; - } + if (bytes[count - 1] == 0) + { + count--; + } else + { + break; + } } return new String(bytes, 0, count, "UTF-8"); - } - - - public static String encodeHexString(String str) - throws UnsupportedEncodingException - { - return encodeHexArray(str.getBytes("UTF-8")); - } - - - public static String encodeHexArray(byte array[]) - { - StringBuilder encoded = new StringBuilder(); - for (byte c : array) - { - String hexByte = Integer.toHexString((int)c); - if (hexByte.length() < 2) - { - hexByte = "0" + hexByte; - } else if (hexByte.length() > 2) - { - hexByte = hexByte.substring(hexByte.length() - 2, hexByte.length()); - } - encoded.append(hexByte); - } - - return encoded.toString(); - } - - - /** - * Maintains a set of old copies for a file. - * For a file dir/file, the old versions are dir/file.1, dir/file.2 etc. up to 9. - * - * @param dir base directory - * - * @param file name of the original file - */ - public static void renameFileForMultiVersionBackup(File dir, String file) - { - final int VERSION_COUNT = 9; - - // Delete last one if it exists - File last = new File(dir, file + "." + VERSION_COUNT); - if (last.exists()) - { - last.delete(); - } - - // Iterate and rename - for (int i = VERSION_COUNT - 1; i >= 1; i--) - { - File f = new File(dir, file + "." + i); - int newIndex = i + 1; - if (f.exists()) - { - f.renameTo(new File(dir, file + "." + newIndex)); - } - } - - // Rename last one - File orig = new File(dir, file); - if (orig.exists()) - { - orig.renameTo(new File(dir, file + ".1")); - } - } - - - public static JsonObject parseJsonObject(String json) - throws IOException - { - try - { - return Json.parse(json).asObject(); - } catch (RuntimeException rte) - { - throw new IOException(rte); - } - } - - - public static JsonObject parseJsonObject(Reader r) - throws IOException - { - try - { - return Json.parse(r).asObject(); - } catch (RuntimeException rte) - { - throw new IOException(rte); - } - } + } + + + public static String encodeHexString(String str) + throws UnsupportedEncodingException + { + return encodeHexArray(str.getBytes("UTF-8")); + } + + + public static String encodeHexArray(byte array[]) + { + StringBuilder encoded = new StringBuilder(); + for (byte c : array) + { + String hexByte = Integer.toHexString((int)c); + if (hexByte.length() < 2) + { + hexByte = "0" + hexByte; + } else if (hexByte.length() > 2) + { + hexByte = hexByte.substring(hexByte.length() - 2, hexByte.length()); + } + encoded.append(hexByte); + } + + return encoded.toString(); + } + + + /** + * Maintains a set of old copies for a file. + * For a file dir/file, the old versions are dir/file.1, dir/file.2 etc. up to 9. + * + * @param dir base directory + * + * @param file name of the original file + */ + public static void renameFileForMultiVersionBackup(File dir, String file) + { + final int VERSION_COUNT = 9; + + // Delete last one if it exists + File last = new File(dir, file + "." + VERSION_COUNT); + if (last.exists()) + { + last.delete(); + } + + // Iterate and rename + for (int i = VERSION_COUNT - 1; i >= 1; i--) + { + File f = new File(dir, file + "." + i); + int newIndex = i + 1; + if (f.exists()) + { + f.renameTo(new File(dir, file + "." + newIndex)); + } + } + + // Rename last one + File orig = new File(dir, file); + if (orig.exists()) + { + orig.renameTo(new File(dir, file + ".1")); + } + } + + + public static JsonObject parseJsonObject(String json) + throws IOException + { + try + { + return Json.parse(json).asObject(); + } catch (RuntimeException rte) + { + throw new IOException(rte); + } + } + + + public static JsonObject parseJsonObject(Reader r) + throws IOException + { + try + { + return Json.parse(r).asObject(); + } catch (RuntimeException rte) + { + throw new IOException(rte); + } + } - - public static byte[] calculateSHA256Digest(byte[] input) - throws IOException - { + + public static byte[] calculateSHA256Digest(byte[] input) + throws IOException + { try { - MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); - DigestInputStream dis = new DigestInputStream(new ByteArrayInputStream(input), sha256); + MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); + DigestInputStream dis = new DigestInputStream(new ByteArrayInputStream(input), sha256); byte [] temp = new byte[0x1 << 13]; byte[] digest; while(dis.read(temp) >= 0); { - digest = sha256.digest(); + digest = sha256.digest(); } return digest; @@ -309,139 +322,222 @@ public static byte[] calculateSHA256Digest(byte[] input) { throw new IOException(impossible); } - } - - - public static String convertGroupPhraseToZPrivateKey(String phrase) - throws IOException - { - byte phraseBytes[] = phrase.getBytes("UTF-8"); - byte phraseDigest[] = calculateSHA256Digest(phraseBytes); - - phraseDigest[0] &= (byte)0x0f; - - //System.out.println(encodeHexArray(phraseDigest)); - - byte base58Input[] = new byte[phraseDigest.length + 2]; - base58Input[0] = (byte)0xab; - base58Input[1] = (byte)0x36; - System.arraycopy(phraseDigest, 0, base58Input, 2, phraseDigest.length); - - // Do a double SHA356 to get a checksum for the data to encode - byte shaStage1[] = calculateSHA256Digest(base58Input); - byte checksum[] = calculateSHA256Digest(shaStage1); - - byte base58CheckInput[] = new byte[base58Input.length + 4]; - System.arraycopy(base58Input, 0, base58CheckInput, 0, base58Input.length); - System.arraycopy(checksum, 0, base58CheckInput, base58Input.length, 4); - - // Call BitcoinJ via reflection - and report error if missing - try - { - Class base58Class = Class.forName("org.bitcoinj.core.Base58"); - Method encode = base58Class.getMethod("encode", byte[].class); - return (String)encode.invoke(null, base58CheckInput); - } catch (Exception e) - { - throw new IOException( - "There was a problem invoking the BitcoinJ library to do Base58 encoding. " + - "Make sure the bitcoinj-core-0.14.5.jar is available!", e); - } - } - - - // zc/zt - mainnet and testnet - // TODO: We need a much more precise criterion to distinguish T/Z adresses; - public static boolean isZAddress(String address) - { - return (address != null) && - (address.startsWith("zc") || address.startsWith("zt")) && - (address.length() > 40); - } - - - /** - * Delets a directory and all of its subdirectories. - * - * @param dir directory to delete. - * - * @throws IOException if not successful - */ - public static void deleteDirectory(File dir) - throws IOException - { - for (File f : dir.listFiles()) - { - if (f.isDirectory()) - { - deleteDirectory(f); - } else - { - if (!f.delete()) - { - throw new IOException("Could not delete file: " + f.getAbsolutePath()); - } - } - } - - if (!dir.delete()) - { - throw new IOException("Could not delete directory: " + dir.getAbsolutePath()); - } - } - - - /** - * Wraps an input string in a block form with the specified width. LF is used to end each line. - * - * @param inStr - * @param width - * - * @return input wrapped - */ - public static String blockWrapString(String inStr, int width) - { - StringBuilder block = new StringBuilder(); - - int position = 0; - while (position < inStr.length()) - { - int endPosition = Math.min(position + width, inStr.length()); - block.append(inStr.substring(position, endPosition)); - block.append("\n"); - position += width; - } - - return block.toString(); - } - - - public static byte[] loadFileInMemory(File f) - throws IOException - { - RandomAccessFile oRAF = null; - try - { - oRAF = new RandomAccessFile(f, "r"); - - byte bytes[] = new byte[(int)oRAF.length()]; - oRAF.readFully(bytes); - - return bytes; - } finally - { - if (oRAF != null) - { - oRAF.close(); - } - } - } + } + + + public static String convertGroupPhraseToZPrivateKey(String phrase) + throws IOException + { + byte phraseBytes[] = phrase.getBytes("UTF-8"); + byte phraseDigest[] = calculateSHA256Digest(phraseBytes); + + phraseDigest[0] &= (byte)0x0f; + + //System.out.println(encodeHexArray(phraseDigest)); + + byte base58Input[] = new byte[phraseDigest.length + 2]; + base58Input[0] = (byte)0xab; + base58Input[1] = (byte)0x36; + System.arraycopy(phraseDigest, 0, base58Input, 2, phraseDigest.length); + + // Do a double SHA356 to get a checksum for the data to encode + byte shaStage1[] = calculateSHA256Digest(base58Input); + byte checksum[] = calculateSHA256Digest(shaStage1); + + byte base58CheckInput[] = new byte[base58Input.length + 4]; + System.arraycopy(base58Input, 0, base58CheckInput, 0, base58Input.length); + System.arraycopy(checksum, 0, base58CheckInput, base58Input.length, 4); + + // Call BitcoinJ via reflection - and report error if missing + try + { + Class base58Class = Class.forName("org.bitcoinj.core.Base58"); + Method encode = base58Class.getMethod("encode", byte[].class); + return (String)encode.invoke(null, base58CheckInput); + } catch (Exception e) + { + throw new IOException( + "There was a problem invoking the BitcoinJ library to do Base58 encoding. " + + "Make sure the bitcoinj-core-0.14.5.jar is available!", e); + } + } + + + // zc/zt - mainnet and testnet + // TODO: We need a much more precise criterion to distinguish T/Z addresses; + public static boolean isZAddress(String address) + { + return (address != null) && + (address.startsWith("zc") || address.startsWith("zt")) && + (address.length() > 40); + } + + + /** + * Deletes a directory and all of its subdirectories. + * + * @param dir directory to delete. + * + * @throws IOException if not successful + */ + public static void deleteDirectory(File dir) + throws IOException + { + for (File f : dir.listFiles()) + { + if (f.isDirectory()) + { + deleteDirectory(f); + } else + { + if (!f.delete()) + { + throw new IOException("Could not delete file: " + f.getAbsolutePath()); + } + } + } + + if (!dir.delete()) + { + throw new IOException("Could not delete directory: " + dir.getAbsolutePath()); + } + } + + + /** + * Wraps an input string in a block form with the specified width. LF is used to end each line. + * + * @param inStr + * @param width + * + * @return input wrapped + */ + public static String blockWrapString(String inStr, int width) + { + StringBuilder block = new StringBuilder(); + + int position = 0; + while (position < inStr.length()) + { + int endPosition = Math.min(position + width, inStr.length()); + block.append(inStr.substring(position, endPosition)); + block.append("\n"); + position += width; + } + + return block.toString(); + } + + + public static byte[] loadFileInMemory(File f) + throws IOException + { + RandomAccessFile oRAF = null; + try + { + oRAF = new RandomAccessFile(f, "r"); + + byte bytes[] = new byte[(int)oRAF.length()]; + oRAF.readFully(bytes); + + return bytes; + } finally + { + if (oRAF != null) + { + oRAF.close(); + } + } + } - public static String wifToHex(String wifKey) throws Exception { - byte[] bytes = Base58.decode(wifKey); - String pk = Util.encodeHexArray(bytes); - pk = pk.substring(2, pk.length() - 10); - return pk; - } + public static String wifToHex(String wifKey) throws Exception { + byte[] bytes = Base58.decode(wifKey); + String pk = Util.encodeHexArray(bytes); + pk = pk.substring(2, pk.length() - 10); + return pk; + } + + + /** + * Check if a string is numeric (long int) + * + * @param s string to check + * + * @return true if the string is numeric (log int) + */ + public static boolean isNumeric(String s) + { + if ((s == null) || (s.length() <= 0)) + { + return false; + } + + try + { + Long.parseLong(s); + } catch (Exception e) + { + return false; + } + + return true; + } + + + /** + * Loads the zend parameters from file zend-cmd-options.conf. + * + * @param onlyMeaningfulLines if true, only the essential lines are loaded (not comment/empty ones). + * + * @return an array that represents the custom parameters of zend to use to start it. + * + * @throws IOException + */ + public static List loadZendParameters(boolean onlyMeaningfulLines) + throws IOException + { + String settingsDir = OSUtil.getSettingsDirectory(); + File dir = new File(settingsDir); + File zendOptionsFile = new File(dir, "zend-cmd-options.conf"); + if (!zendOptionsFile.exists()) + { + Log.info("zend command line options configuration file zend-cmd-options.conf " + + " does not exist. This is not expected!"); + return new ArrayList(); + } + + List options = new ArrayList(); + LineNumberReader r = null; + try + { + r = new LineNumberReader(new InputStreamReader(new FileInputStream(zendOptionsFile), "UTF-8")); + String line; + while ((line = r.readLine()) != null) + { + line = line.trim(); + + if (onlyMeaningfulLines && (line.length() <= 0)) + { + continue; + } + + if (onlyMeaningfulLines && line.startsWith("#")) + { + continue; + } + + options.add(line); + } + + } finally + { + if (r != null) + { + r.close(); + } + } + + return options; + } } diff --git a/src/java/com/vaklinov/zcashui/WalletOperations.java b/src/java/com/vaklinov/zcashui/WalletOperations.java index 2f04af5b..21c35e4a 100644 --- a/src/java/com/vaklinov/zcashui/WalletOperations.java +++ b/src/java/com/vaklinov/zcashui/WalletOperations.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -50,12 +51,10 @@ /** * Provides miscellaneous operations for the wallet file. - * - * @author Ivan Vaklinov */ public class WalletOperations { - private ZCashUI parent; + private HorizenUI parent; private JTabbedPane tabs; private DashboardPanel dashboard; private SendCashPanel sendCash; @@ -66,8 +65,10 @@ public class WalletOperations private StatusUpdateErrorReporter errorReporter; private BackupTracker backupTracker; + private LanguageUtil langUtil; + - public WalletOperations(ZCashUI parent, + public WalletOperations(HorizenUI parent, JTabbedPane tabs, DashboardPanel dashboard, AddressesPanel addresses, @@ -90,6 +91,7 @@ public WalletOperations(ZCashUI parent, this.errorReporter = errorReporter; this.backupTracker = backupTracker; + this.langUtil = LanguageUtil.instance(); } @@ -101,10 +103,8 @@ public void encryptWallet() { JOptionPane.showMessageDialog( this.parent, - "The wallet.dat file being used is already encrypted. " + - "This \noperation may be performed only on a wallet that " + - "is not\nyet encrypted!", - "Wallet is already encrypted...", + langUtil.getString("wallet.operations.option.pane.already.encrypted.error.text"), + langUtil.getString("wallet.operations.option.pane.already.encrypted.error.title"), JOptionPane.ERROR_MESSAGE); return; } @@ -136,21 +136,17 @@ public void encryptWallet() JOptionPane.showMessageDialog( this.parent, - "An unexpected error occurred while encrypting the wallet!\n" + - "It is recommended to stop and restart both zend and the GUI wallet! \n" + - "\n" + wce.getMessage().replace(",", ",\n"), - "Error in encrypting wallet...", JOptionPane.ERROR_MESSAGE); + langUtil.getString("wallet.operations.option.pane.encryption.error.text", wce.getMessage().replace(",", ",\n")), + langUtil.getString("wallet.operations.option.pane.encryption.error.title"), + JOptionPane.ERROR_MESSAGE); return; } JOptionPane.showMessageDialog( this.parent, - "The wallet has been encrypted sucessfully and zend has stopped.\n" + - "The GUI wallet will be stopped as well. Please restart both. In\n" + - "addtion the internal wallet keypool has been flushed. You need\n" + - "to make a new backup..." + - "\n", - "Wallet is now encrypted...", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("wallet.operations.option.pane.encryption.success.text"), + langUtil.getString("wallet.operations.option.pane.encryption.success.title"), + JOptionPane.INFORMATION_MESSAGE); this.parent.exitProgram(); @@ -168,7 +164,7 @@ public void backupWallet() this.issueBackupDirectoryWarning(); JFileChooser fileChooser = new JFileChooser(); - fileChooser.setDialogTitle("Backup wallet to file..."); + fileChooser.setDialogTitle(langUtil.getString("wallet.operations.dialog.backup.wallet.title")); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setCurrentDirectory(OSUtil.getUserHomeDirectory()); @@ -199,18 +195,17 @@ public void backupWallet() JOptionPane.showMessageDialog( this.parent, - "An unexpected error occurred while backing up the wallet!" + - "\n" + wce.getMessage().replace(",", ",\n"), - "Error in backing up wallet...", JOptionPane.ERROR_MESSAGE); + langUtil.getString("wallet.operations.option.pane.backup.wallet.error.text", wce.getMessage().replace(",", ",\n")), + langUtil.getString("wallet.operations.option.pane.backup.wallet.error.title"), + JOptionPane.ERROR_MESSAGE); return; } JOptionPane.showMessageDialog( this.parent, - "The wallet has been backed up successfully to file: " + f.getName() + "\n" + - "in the backup directory provided to zend (-exportdir=).\nFull path is: " + - path, - "Wallet is backed up...", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("wallet.operations.option.pane.backup.wallet.success.text", f.getName(), path), + + langUtil.getString("wallet.operations.option.pane.backup.wallet.success.title"), JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { @@ -228,7 +223,7 @@ public void exportWalletPrivateKeys() this.issueBackupDirectoryWarning(); JFileChooser fileChooser = new JFileChooser(); - fileChooser.setDialogTitle("Export wallet private keys to file..."); + fileChooser.setDialogTitle(langUtil.getString("wallet.operations.dialog.export.private.keys.title")); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setCurrentDirectory(OSUtil.getUserHomeDirectory()); @@ -258,21 +253,18 @@ public void exportWalletPrivateKeys() JOptionPane.showMessageDialog( this.parent, - "An unexpected error occurred while exporting wallet private keys!" + - "\n" + wce.getMessage().replace(",", ",\n"), - "Error in exporting wallet private keys...", JOptionPane.ERROR_MESSAGE); + langUtil.getString("wallet.operations.dialog.export.private.keys.error.text", + "\n" + wce.getMessage().replace(",", ",\n")), + langUtil.getString("wallet.operations.dialog.export.private.keys.error.title"), + JOptionPane.ERROR_MESSAGE); return; } JOptionPane.showMessageDialog( - this.parent, - "The wallet private keys have been exported successfully to file:\n" + - f.getName() + "\n" + - "in the backup directory provided to zend (-exportdir=).\nFull path is: " + - path + "\n" + - "You need to protect this file from unauthorized access. Anyone who\n" + - "has access to the private keys can spend the ZENCash balance!", - "Wallet private key export...", JOptionPane.INFORMATION_MESSAGE); + this.parent, + langUtil.getString("wallet.operations.dialog.export.private.keys.success.text", f.getName(), path ), + langUtil.getString("wallet.operations.dialog.export.private.keys.success.title"), + JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { @@ -287,12 +279,8 @@ public void importWalletPrivateKeys() int option = JOptionPane.showConfirmDialog( this.parent, - "Private key import is a potentially slow operation. It may take\n" + - "several minutes during which the GUI will be non-responsive.\n" + - "The data to import must be in the format used by the option:\n" + - "\"Export private keys...\"\n\n" + - "Are you sure you wish to import private keys?", - "Private key import notice...", + langUtil.getString("wallet.operations.dialog.import.private.keys.notice.text"), + langUtil.getString("wallet.operations.dialog.import.private.keys.notice.title"), JOptionPane.YES_NO_OPTION); if (option == JOptionPane.NO_OPTION) { @@ -302,7 +290,7 @@ public void importWalletPrivateKeys() try { JFileChooser fileChooser = new JFileChooser(); - fileChooser.setDialogTitle("Import wallet private keys from file..."); + fileChooser.setDialogTitle(langUtil.getString("wallet.operations.file.chooser.import.private.keys.title")); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); int result = fileChooser.showOpenDialog(this.parent); @@ -329,17 +317,17 @@ public void importWalletPrivateKeys() JOptionPane.showMessageDialog( this.parent, - "An unexpected error occurred while importing wallet private keys!" + - "\n" + wce.getMessage().replace(",", ",\n"), - "Error in importing wallet private keys...", JOptionPane.ERROR_MESSAGE); + langUtil.getString("wallet.operations.dialog.import.private.keys.error.text", wce.getMessage().replace(",", ",\n")), + langUtil.getString("wallet.operations.dialog.import.private.keys.error.title"), + JOptionPane.ERROR_MESSAGE); return; } JOptionPane.showMessageDialog( this.parent, - "Wallet private keys have been imported successfully from location:\n" + - f.getCanonicalPath() + "\n\n", - "Wallet private key import...", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("wallet.operations.dialog.import.private.keys.success.text",f.getCanonicalPath()), + langUtil.getString("wallet.operations.dialog.import.private.keys.success.title"), + JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { @@ -350,14 +338,14 @@ public void importWalletPrivateKeys() public void showPrivateKey() { - if (this.tabs.getSelectedIndex() != 1) + if (this.tabs.getSelectedIndex() != 2) { JOptionPane.showMessageDialog( this.parent, - "Please select an address in the \"Own addresses\" tab " + - "to view its private key", - "Please select an address...", JOptionPane.INFORMATION_MESSAGE); - this.tabs.setSelectedIndex(1); + langUtil.getString("wallet.operations.option.pane.own.address.view.private.key.text"), + langUtil.getString("wallet.operations.option.pane.own.address.view.private.key.title"), + JOptionPane.INFORMATION_MESSAGE); + this.tabs.setSelectedIndex(2); return; } @@ -367,9 +355,9 @@ public void showPrivateKey() { JOptionPane.showMessageDialog( this.parent, - "Please select an address in the table of addresses " + - "to view its private key", - "Please select an address...", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("wallet.operations.option.pane.address.table.view.private.key.text"), + langUtil.getString("wallet.operations.option.pane.address.table.view.private.key.title"), + JOptionPane.INFORMATION_MESSAGE); return; } @@ -403,15 +391,12 @@ public void showPrivateKey() Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); clipboard.setContents(new StringSelection(privateKey), null); - + String adressType = isZAddress ? langUtil.getString("wallet.operations.private.address") + : langUtil.getString("wallet.operations.transparent.address"); JOptionPane.showMessageDialog( this.parent, - (isZAddress ? "Z (Private)" : "T (Transparent)") + " address:\n" + - address + "\n" + - "has private key:\n" + - privateKey + "\n\n" + - "The private key has also been copied to the clipboard.", - "Private key information", JOptionPane.INFORMATION_MESSAGE); + langUtil.getString("wallet.operations.option.pane.address.information.text", adressType, address, privateKey), + langUtil.getString("wallet.operations.option.pane.address.information.title"), JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { this.errorReporter.reportError(ex, false); @@ -432,23 +417,40 @@ public void importSinglePrivateKey() } } - + + /** + * Brings up a GUI dialog box to edit the command line parameters of zend that the GUI starts. + */ + public void editZendOptions() + { + try + { + this.issueZendParametersWarning(); + + ZendParametersEditDialog dialog = new ZendParametersEditDialog(this.parent, errorReporter); + dialog.setVisible(true); + } catch (Exception ex) + { + this.errorReporter.reportError(ex, false); + } + } + /** * export to Arizen wallet */ public void exportToArizenWallet() { - final JDialog dialog = new JDialog(this.parent, "Exporting Arizen wallet"); + final JDialog dialog = new JDialog(this.parent, langUtil.getString("wallet.operations.dialog.export.arizen.title")); final JLabel exportLabel = new JLabel(); final WalletRepo arizenWallet = new ArizenWallet(); try { JFileChooser fileChooser = new JFileChooser(); - fileChooser.setFileFilter(new FileNameExtensionFilter("Arizen wallet file", "uawd")); - fileChooser.setDialogTitle("Export wallet to Arizen wallet unencrypted format..."); + fileChooser.setFileFilter(new FileNameExtensionFilter(langUtil.getString("wallet.operations.dialog.export.arizen.filechooser.filter"), "uawd")); + fileChooser.setDialogTitle(langUtil.getString("wallet.operations.dialog.export.arizen.filechooser.title")); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); fileChooser.setCurrentDirectory(OSUtil.getUserHomeDirectory()); - int result = fileChooser.showDialog(this.parent, "Export"); + int result = fileChooser.showDialog(this.parent, langUtil.getString("wallet.operations.dialog.export.arizen.filechooser.aprove.button")); if (result != JFileChooser.APPROVE_OPTION) { return; @@ -462,8 +464,9 @@ public void exportToArizenWallet() final File f = new File(fullPath); if (f.exists()) { int r = JOptionPane.showConfirmDialog((Component) null, - String.format("The file %s already exists, do you want proceed and delete it?", f.getName()), - "Alert", JOptionPane.YES_NO_OPTION); + langUtil.getString("wallet.operations.dialog.delete.file.confirmation", f.getName()), + langUtil.getString("wallet.operations.dialog.delete.file.confirmation.title"), + JOptionPane.YES_NO_OPTION); if (r == 1) { return; } @@ -479,7 +482,7 @@ public void exportToArizenWallet() JProgressBar progressBar = new JProgressBar(); progressBar.setIndeterminate(true); dialog.add(progressBar, BorderLayout.CENTER); - exportLabel.setText("Exporting wallet..."); + exportLabel.setText(langUtil.getString("wallet.operations.dialog.export.label")); exportLabel.setHorizontalAlignment(JLabel.CENTER); exportLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 16, 0)); @@ -492,7 +495,7 @@ public Boolean doInBackground() { try { arizenWallet.createWallet(f); Thread.sleep(750); - updateProgressText("Reading addresses and private keys..."); + updateProgressText(langUtil.getString("wallet.operations.dialog.export.progress.reading.text")); String[] zaddress = clientCaller.getWalletZAddresses(); String[] taddress = clientCaller.getWalletAllPublicAddresses(); String[] tAddressesWithUnspentOuts = clientCaller.getWalletPublicAddressesWithUnspentOutputs(); @@ -529,12 +532,15 @@ public Boolean doInBackground() { addressPrivateSet.addAll(zMap.values()); Thread.sleep(500); - updateProgressText("Writing addresses and private keys..."); + updateProgressText(langUtil.getString("wallet.operations.dialog.export.progress.writing.text")); arizenWallet.insertAddressBatch(addressPublicSet); - arizenWallet.insertAddressBatch(addressPrivateSet); + if (addressPrivateSet.size() > 0) + { + arizenWallet.insertAddressBatch(addressPrivateSet); + } Thread.sleep(1000); - updateProgressText("Wallet exported"); + updateProgressText(langUtil.getString("wallet.operations.dialog.export.progress.finished.text")); Thread.sleep(750); SwingUtilities.invokeLater(new Runnable() { @@ -542,10 +548,9 @@ public Boolean doInBackground() { public void run() { dialog.dispose(); JOptionPane.showConfirmDialog(parent, - new Object[]{String.format("The Arizen wallet is exported to: %s", strFullpath), - "Using Arizen to import select: Import UNENCRYPTED Arizen wallet", - "The wallet will be imported and encrypted"}, - "Export Arizen wallet", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE); + langUtil.getString("wallet.operations.option.pane.export.success.info.text", strFullpath), + langUtil.getString("wallet.operations.option.pane.export.success.info.title"), + JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE); } }); @@ -588,7 +593,6 @@ public void run() { } - private void issueBackupDirectoryWarning() throws IOException { @@ -601,21 +605,13 @@ private void issueBackupDirectoryWarning() int reply = JOptionPane.showOptionDialog( this.parent, - "For security reasons the wallet may be backed up/private keys exported only if\n" + - "the zend parameter -exportdir= has been set. If you started zend \n" + - "manually, you ought to have provided this parameter. When zend is started \n" + - "automatically by the GUI wallet the directory provided as parameter to -exportdir\n" + - "is the user home directory: " + OSUtil.getUserHomeDirectory().getCanonicalPath() +"\n" + - "Please navigate to the directory provided as -exportdir= and select a\n"+ - "filename in it to backup/export private keys. If you select another directory\n" + - "instead, the destination file will still end up in the directory provided as \n" + - "-exportdir=. If this parameter was not provided to zend, the process\n" + - "will fail with a security check error. The filename needs to consist of only\n" + - "alphanumeric characters (e.g. dot is not allowed).\n", - "Wallet backup directory information", + langUtil.getString("wallet.operations.option.pane.backup.directory.warning.text", + OSUtil.getUserHomeDirectory().getCanonicalPath()), + langUtil.getString("wallet.operations.option.pane.backup.directory.warning.title"), JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, - null, new String[] { "Do not show this again", "OK" }, + null, new String[] { langUtil.getString("wallet.operations.option.pane.backup.directory.warning.message"), + langUtil.getString("wallet.operations.option.pane.backup.directory.warning.message.ok") }, JOptionPane.NO_OPTION); if (reply == JOptionPane.NO_OPTION) @@ -625,4 +621,35 @@ private void issueBackupDirectoryWarning() warningFlagFile.createNewFile(); } + + + private void issueZendParametersWarning() + throws IOException + { + String userDir = OSUtil.getSettingsDirectory(); + File warningFlagFile = new File(userDir + File.separator + "zendParameterWarningShown.flag"); + if (warningFlagFile.exists()) + { + return; + } + + int reply = JOptionPane.showOptionDialog( + this.parent, + langUtil.getString("wallet.operations.zend.parameters.warning.text", + new File(userDir + File.separator + "zend-cmd-options.conf").getCanonicalPath()), + langUtil.getString("wallet.operations.zend.parameters.warning.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE, + null, new String[] { langUtil.getString("wallet.operations.zend.parameters.warning.notagain"), + langUtil.getString("wallet.operations.zend.parameters.warning.oklabel") }, + JOptionPane.NO_OPTION); + + if (reply == JOptionPane.NO_OPTION) + { + return; + } + + warningFlagFile.createNewFile(); + } + } diff --git a/src/java/com/vaklinov/zcashui/WalletTabPanel.java b/src/java/com/vaklinov/zcashui/WalletTabPanel.java index a0962839..e2a9fcdb 100644 --- a/src/java/com/vaklinov/zcashui/WalletTabPanel.java +++ b/src/java/com/vaklinov/zcashui/WalletTabPanel.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,8 +42,6 @@ /** * Base for all panels contained as wallet TABS. - * - * @author Ivan Vaklinov */ public class WalletTabPanel extends JPanel diff --git a/src/java/com/vaklinov/zcashui/ZCashClientCaller.java b/src/java/com/vaklinov/zcashui/ZCashClientCaller.java index 26f536a7..9f843d4d 100644 --- a/src/java/com/vaklinov/zcashui/ZCashClientCaller.java +++ b/src/java/com/vaklinov/zcashui/ZCashClientCaller.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,7 +31,10 @@ import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.StringReader; import java.math.BigDecimal; @@ -39,6 +43,8 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -56,8 +62,6 @@ /** * Calls zcash-cli - * - * @author Ivan Vaklinov */ public class ZCashClientCaller { @@ -97,7 +101,20 @@ public WalletCallException(String message, Throwable cause) // ZCash client program and daemon private File zcashcli, zcashd; + + // Table caching the wallet transaction times - to speed up performance + // TXID -> UNIX time as string + private Map transactionTimes = Collections.synchronizedMap( + new HashMap()); + private long lastTransactionTimesAccess = System.currentTimeMillis(); + + // Table caching the wallet transaction confirmations - to speed up performance + // TXID -> confirmations as string + private Map transactionConfirmations = Collections.synchronizedMap( + new HashMap()); + private long lastTransactionConfirmationsAccess = System.currentTimeMillis(); + public ZCashClientCaller(String installDir) throws IOException @@ -114,7 +131,7 @@ public ZCashClientCaller(String installDir) if ((zcashcli == null) || (!zcashcli.exists())) { throw new IOException( - "The ZENCash installation directory " + installDir + " needs to contain " + + "The Horizen installation directory " + installDir + " needs to contain " + "the command line utilities zend and zen-cli. zen-cli is missing!"); } @@ -127,7 +144,7 @@ public ZCashClientCaller(String installDir) if (zcashd == null || (!zcashd.exists())) { throw new IOException( - "The ZENCash command line utility " + zcashcli.getCanonicalPath() + + "The Horizen command line utility " + zcashcli.getCanonicalPath() + " was found, but zend was not found!"); } } @@ -138,12 +155,30 @@ public synchronized Process startDaemon() { String exportDir = OSUtil.getUserHomeDirectory().getCanonicalPath(); - CommandExecutor starter = new CommandExecutor( - new String[] - { - zcashd.getCanonicalPath(), - "-exportdir=" + exportDir - }); + List zendOptions = Util.loadZendParameters(true); + Log.info("Custom zend options to be used are: {0}", zendOptions.toString()); + + String zendFullCommandLine[] = new String[zendOptions.size() + 1]; + zendFullCommandLine[0] = zcashd.getCanonicalPath(); + + // Transfer the zend parameters, also possibly wrap them + for (int i = 0; i < zendOptions.size(); i++) + { + String option = zendOptions.get(i); + boolean containEq = option.contains("="); + boolean containsSpaces = option.contains(" ") || option.contains("\t"); + + // The options come trimmed, however it is possible that they have weird content and need to be wrapped + // on Windows + if ((!containEq) || (containsSpaces)) + { + option = wrapStringParameter(option); + } + + zendFullCommandLine[i+1] = option; + } + + CommandExecutor starter = new CommandExecutor(zendFullCommandLine); return starter.startChildProcess(); } @@ -234,7 +269,7 @@ public synchronized String[][] getWalletPublicTransactions() } JsonArray jsonTransactions = executeCommandAndGetJsonArray( - "listtransactions", wrapStringParameter(""), "300"); + "listtransactions", wrapStringParameter(""), "2147483647"); String strTransactions[][] = new String[jsonTransactions.size()][]; for (int i = 0; i < jsonTransactions.size(); i++) { @@ -242,13 +277,13 @@ public synchronized String[][] getWalletPublicTransactions() JsonObject trans = jsonTransactions.get(i).asObject(); // Needs to be the same as in getWalletZReceivedTransactions() - // TODO: some day refactor to use object containers + // TODO: someday refactor to use object containers strTransactions[i][0] = "\u2606T (Public)"; strTransactions[i][1] = trans.getString("category", "ERROR!"); strTransactions[i][2] = trans.get("confirmations").toString(); strTransactions[i][3] = trans.get("amount").toString(); strTransactions[i][4] = trans.get("time").toString(); - strTransactions[i][5] = trans.getString("address", notListed + " (Z Address not listed by wallet!)"); + strTransactions[i][5] = trans.getString("address", notListed + " (Z address not listed by wallet!)"); strTransactions[i][6] = trans.get("txid").toString(); } @@ -289,12 +324,44 @@ public synchronized String[][] getWalletZReceivedTransactions() String txID = trans.getString("txid", "ERROR!"); // Needs to be the same as in getWalletPublicTransactions() - // TODO: some day refactor to use object containers + // TODO: someday refactor to use object containers currentTransaction[0] = "\u2605Z (Private)"; currentTransaction[1] = "receive"; - currentTransaction[2] = this.getWalletTransactionConfirmations(txID); + + // Transaction confirmations cached - cleared every 10 min + if ((System.currentTimeMillis() - this.lastTransactionConfirmationsAccess) > (10 * 60 * 1000)) + { + this.lastTransactionConfirmationsAccess = System.currentTimeMillis(); + this.transactionConfirmations.clear(); + } + String confirmations = this.transactionConfirmations.get(txID); + if ((confirmations == null) || confirmations.equals("0")) + { + currentTransaction[2] = this.getWalletTransactionConfirmations(txID); + this.transactionConfirmations.put(txID, currentTransaction[2]); + } else + { + currentTransaction[2] = confirmations; + } + currentTransaction[3] = trans.get("amount").toString(); - currentTransaction[4] = this.getWalletTransactionTime(txID); // TODO: minimize sub-calls + + // Transaction time is cached - cleared every 10 min + if ((System.currentTimeMillis() - this.lastTransactionTimesAccess) > (10 * 60 * 1000)) + { + this.lastTransactionTimesAccess = System.currentTimeMillis(); + this.transactionTimes.clear(); + } + String time = this.transactionTimes.get(txID); + if ((time == null) || (time.equals("-1"))) + { + currentTransaction[4] = this.getWalletTransactionTime(txID); + this.transactionTimes.put(txID, currentTransaction[4]); + } else + { + currentTransaction[4] = time; + } + currentTransaction[5] = zAddress; currentTransaction[6] = trans.get("txid").toString(); @@ -421,7 +488,7 @@ public synchronized String getRawTransaction(String txID) } - // return UNIX time as tring + // return UNIX time as string public synchronized String getWalletTransactionTime(String txID) throws WalletCallException, IOException, InterruptedException { @@ -485,10 +552,15 @@ public synchronized String createNewAddress(boolean isZAddress) } - // Returns OPID + // Returns OPID - this method is a bit old and could be improved, however it is known to work and would better not + // be changed unless there is a bug. public synchronized String sendCash(String from, String to, String amount, String memo, String transactionFee) throws WalletCallException, IOException, InterruptedException { + Log.info("Starting operation send-cash. Parameters are: from address: {0}, to address: {1}, " + + "amount: {2}, memo: {3}, transaction fee: {4}", + from, to, amount, memo, transactionFee); + StringBuilder hexMemo = new StringBuilder(); for (byte c : memo.getBytes("UTF-8")) { @@ -527,7 +599,7 @@ public synchronized String sendCash(String from, String to, String amount, Strin DecimalFormatSymbols decSymbols = new DecimalFormatSymbols(Locale.ROOT); - // Properly format teh transaction fee as a number + // Properly format the transaction fee as a number if ((transactionFee == null) || (transactionFee.trim().length() <= 0)) { transactionFee = "0.0001"; // Default value @@ -580,7 +652,131 @@ public synchronized String sendCash(String from, String to, String amount, Strin throw new WalletCallException("Error response from wallet: " + strResponse); } - Log.info("Sending cash with the following command: " + + Log.info("Sent cash with the following command: " + + sendCashParameters[0] + " " + sendCashParameters[1] + " " + + sendCashParameters[2] + " " + sendCashParameters[3] + " " + + sendCashParameters[4] + " " + sendCashParameters[5] + "." + + " Got result: [" + strResponse + "]"); + + return strResponse.trim(); + } + + + /** + * Sends ZEN from a source address to a destination address. The change is sent back to the source address. + * The amount of change is calculated based on the existing confirmed balance for the address (parameter). + * This may not be 100% accurate if the blockchain is not synchronized. + * + * @param from source address (T/Z) + * @param to destination address (T/Z) + * @param balance current confirmed balance of the source address + * @param amount ZEN amount to send + * @param memo text memo to include in the transaction + * @param transactionFee transaction see to include + * + * @return a zend operation ID for the send operation + * + * @throws WalletCallException + * @throws IOException + * @throws InterruptedException + */ + public synchronized String sendCashWithReturnOfChange(String from, String to, String balance, + String amount, String memo, String transactionFee) + throws WalletCallException, IOException, InterruptedException + { + Log.info("Starting operation send cash with return of change. Parameters are: from address: {0}, to address: {1}, " + + "current balance: {2}, amount: {3}, memo: {4}, transaction fee: {5}", + from, to, balance, amount, memo, transactionFee); + + final DecimalFormatSymbols decSymbols = new DecimalFormatSymbols(Locale.ROOT); + final DecimalFormat sendNumberFormat = new DecimalFormat("########0.00######", decSymbols); + + String hexMemo = Util.encodeHexString(memo); + // Form the main amount to send + JsonObject toDestinationArgument = new JsonObject(); + toDestinationArgument.set("address", to); + if (hexMemo.length() >= 2) + { + toDestinationArgument.set("memo", hexMemo.toString()); + } + String formattedAmountToSend = sendNumberFormat.format(new BigDecimal(amount)); + String formattedTransactionFee = sendNumberFormat.format(new BigDecimal(transactionFee)); + toDestinationArgument.set("amount", formattedAmountToSend); + // Form the return amount - based on the balance + JsonObject backToSourceArgument = new JsonObject(); + backToSourceArgument.set("address", from); + BigDecimal changeToSendBackBD = new BigDecimal(balance). + subtract(new BigDecimal(formattedAmountToSend)).subtract(new BigDecimal(formattedTransactionFee)); + boolean changeIsZero = false; + if (changeToSendBackBD.compareTo(new BigDecimal("0")) < 0) + { + throw new WalletCallException("Error: change was calculated negative"); + } else if (changeToSendBackBD.compareTo(new BigDecimal("0")) == 0) + { + Log.info("Change was calculated exactly zero - will not be sent back!"); + changeIsZero = true; + } + + String formattedChangeToReturn = sendNumberFormat.format(changeToSendBackBD); + backToSourceArgument.set("amount", formattedChangeToReturn); + + // Array of two addresses to send to + JsonArray toMany = new JsonArray(); + toMany.add(toDestinationArgument); + if (!changeIsZero) + { + toMany.add(backToSourceArgument); + } + + String toManyArrayStr = toMany.toString(WriterConfig.MINIMAL); + String[] sendCashParameters = new String[] + { + this.zcashcli.getCanonicalPath(), "z_sendmany", wrapStringParameter(from), + wrapStringParameter(toManyArrayStr), + // Default min confirmations for the input transactions is 1 + "1", + // transaction fee + formattedTransactionFee + }; + + // Safeguard to make sure the monetary amount does not differ after formatting + BigDecimal bdAmout = new BigDecimal(amount); // original amount used for check + JsonArray toManyVerificationArr = Json.parse(toManyArrayStr).asArray(); + BigDecimal bdFinalAmount = + new BigDecimal(toManyVerificationArr.get(0).asObject().getString("amount", "-1")); + BigDecimal amountCheckDifference = bdAmout.subtract(bdFinalAmount).abs(); + if (amountCheckDifference.compareTo(new BigDecimal("0.0")) > 0) // MUST be exact + { + throw new WalletCallException("Error in forming z_sendmany command: Main amount differs after formatting: " + + formattedAmountToSend + " | \n" + toManyArrayStr); + } + // Amount + change + fee = balance // This must also match + BigDecimal bdFinalChange = changeIsZero ? + new BigDecimal("0") : new BigDecimal(toManyVerificationArr.get(1).asObject().getString("amount", "-1")); + amountCheckDifference = bdFinalChange.add(bdFinalAmount).add(new BigDecimal(formattedTransactionFee)). + subtract(new BigDecimal(balance)).abs(); // Original balance used after formatting + if (amountCheckDifference.compareTo(new BigDecimal("0.0")) > 0) // MUST be exact + { + throw new WalletCallException("Error in forming z_sendmany command: Sum differs after formatting: " + + formattedAmountToSend + " | \n" + toManyArrayStr); + } + + Log.info("The following send command (with change return) will be issued: " + + sendCashParameters[0] + " " + sendCashParameters[1] + " " + + sendCashParameters[2] + " " + sendCashParameters[3] + " " + + sendCashParameters[4] + " " + sendCashParameters[5] + "."); + + // Create caller to send cash + CommandExecutor caller = new CommandExecutor(sendCashParameters); + String strResponse = caller.execute(); + + if (strResponse.trim().toLowerCase(Locale.ROOT).startsWith("error:") || + strResponse.trim().toLowerCase(Locale.ROOT).startsWith("error code:")) + { + throw new WalletCallException("Error response from wallet: " + strResponse); + } + + Log.info("Sent cash (with change back) with the following command: " + sendCashParameters[0] + " " + sendCashParameters[1] + " " + sendCashParameters[2] + " " + sendCashParameters[3] + " " + sendCashParameters[4] + " " + sendCashParameters[5] + "." + @@ -830,7 +1026,7 @@ public synchronized boolean isWalletEncrypted() if ((respObject.getDouble("code", -1) == -15) && (respObject.getString("message", "ERR").indexOf("unencrypted wallet") != -1)) { - // Obviously unencrupted + // Obviously unencrypted return false; } else { @@ -842,7 +1038,7 @@ public synchronized boolean isWalletEncrypted() if ((respObject.getDouble("code", -1) == -15) && (respObject.getString("message", "ERR").indexOf("unencrypted wallet") != -1)) { - // Obviously unencrupted + // Obviously unencrypted return false; } else { @@ -1156,6 +1352,5 @@ private void decomposeJSONValue(String name, JsonValue val, Map { map.put(name, val.toString()); } - } - + } } diff --git a/src/java/com/vaklinov/zcashui/ZCashInstallationObserver.java b/src/java/com/vaklinov/zcashui/ZCashInstallationObserver.java index 764ff926..ef14ac99 100644 --- a/src/java/com/vaklinov/zcashui/ZCashInstallationObserver.java +++ b/src/java/com/vaklinov/zcashui/ZCashInstallationObserver.java @@ -1,12 +1,13 @@ /************************************************************************************************ - * _________ _ ____ _ __ __ _ _ _ _ _ ___ - * |__ / ___|__ _ ___| |__ / ___|_ _(_)_ __ __ \ \ / /_ _| | | ___| |_| | | |_ _| - * / / | / _` / __| '_ \\___ \ \ /\ / / | '_ \ / _` \ \ /\ / / _` | | |/ _ \ __| | | || | - * / /| |__| (_| \__ \ | | |___) \ V V /| | | | | (_| |\ V V / (_| | | | __/ |_| |_| || | - * /____\____\__,_|___/_| |_|____/ \_/\_/ |_|_| |_|\__, | \_/\_/ \__,_|_|_|\___|\__|\___/|___| - * |___/ - * - * Copyright (c) 2016 Ivan Vaklinov + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,8 +43,6 @@ /** * Observes the daemon - running etc. - * - * @author Ivan Vaklinov */ public class ZCashInstallationObserver { @@ -75,7 +74,7 @@ public ZCashInstallationObserver(String installDir) if (!dir.exists() || dir.isFile()) { throw new InstallationDetectionException( - "The ZENCash installation directory " + installDir + " does not exist or is not " + + "The Horizen installation directory " + installDir + " does not exist or is not " + "a directory or is otherwise inaccessible to the wallet!"); } @@ -88,14 +87,14 @@ public ZCashInstallationObserver(String installDir) zcashcli = OSUtil.findZCashCommand(OSUtil.getZCashCli()); } - Log.info("Using ZENCash utilities: " + + Log.info("Using Horizen utilities: " + "zend: " + ((zcashd != null) ? zcashd.getCanonicalPath() : "") + ", " + "zen-cli: " + ((zcashcli != null) ? zcashcli.getCanonicalPath() : "")); if ((zcashd == null) || (zcashcli == null) || (!zcashd.exists()) || (!zcashcli.exists())) { throw new InstallationDetectionException( - "The ZENCash GUI Wallet installation directory " + installDir + " needs\nto contain " + + "The Horizen GUI Wallet installation directory " + installDir + " needs\nto contain " + "the command line utilities zend and zen-cli. At least one of them is missing! \n" + "Please place files ZENCashSwingWalletUI.jar, " + OSUtil.getZCashCli() + ", " + OSUtil.getZCashd() + " in the same directory."); @@ -124,7 +123,7 @@ private synchronized DaemonInfo getDaemonInfoForUNIXLikeOS() return getDaemonInfoForUNIXLikeOS("zend"); } - // So far tested on Mac OS X and Linux - expected to work on other UNIXes as well + // So far tested on macOS and Linux - expected to work on other UNIXes as well public static synchronized DaemonInfo getDaemonInfoForUNIXLikeOS(String daemonName) throws IOException, InterruptedException { diff --git a/src/java/com/vaklinov/zcashui/ZendParametersEditDialog.java b/src/java/com/vaklinov/zcashui/ZendParametersEditDialog.java new file mode 100644 index 00000000..014b6068 --- /dev/null +++ b/src/java/com/vaklinov/zcashui/ZendParametersEditDialog.java @@ -0,0 +1,411 @@ +/************************************************************************************************ + * ____________ _ _ _____ _ _____ _ _ _______ __ _ _ _ + * |___ / ____| \ | |/ ____| | | / ____| | | |_ _\ \ / / | | | | | + * / /| |__ | \| | | __ _ ___| |__ | | __| | | | | | \ \ /\ / /_ _| | | ___| |_ + * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| + * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ + * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + **********************************************************************************/ +package com.vaklinov.zcashui; + +import java.awt.BorderLayout; +import java.awt.Desktop; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PrintWriter; +import java.io.StringReader; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + + +/** + * Dialog showing the zend startup options and allowing them to be edited. + */ +public class ZendParametersEditDialog + extends JDialog +{ + protected JFrame parentFrame; + protected StatusUpdateErrorReporter errorReporter; + + protected JLabel infoLabel; + protected JPanel buttonPanel; + + protected JTextArea optionsEditArea; + + private LanguageUtil langUtil; + + public ZendParametersEditDialog(JFrame parentFrame, StatusUpdateErrorReporter errorReporter) + throws IOException + { + this.parentFrame = parentFrame; + this.errorReporter = errorReporter; + + this.langUtil = LanguageUtil.instance(); + + this.setTitle(langUtil.getString("zend.cmd.params.dialog.title")); + this.setModal(true); + this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); + + this.getContentPane().setLayout(new BorderLayout(0, 0)); + + JPanel tempPanel = new JPanel(new BorderLayout(0, 0)); + tempPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + infoLabel = new JLabel(langUtil.getString("zend.cmd.params.dialog.info")); + infoLabel.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + try + { + Desktop.getDesktop().browse(new URI( + "https://github.com/HorizenOfficial/zencash-swing-wallet-ui/blob/feature/zend-cmd-options/docs/zend.pdf")); + } + catch(Exception ex) + { + errorReporter.reportError(ex); + } + } + }); + tempPanel.add(infoLabel, BorderLayout.CENTER); + this.getContentPane().add(tempPanel, BorderLayout.NORTH); + + JPanel detailsPanel = new JPanel(); + detailsPanel.setLayout(new BoxLayout(detailsPanel, BoxLayout.Y_AXIS)); + + // Load the content of the current options file + List zendParams = Util.loadZendParameters(true); + while (zendParams.size() < 6) + { + zendParams.add(""); + } + + StringBuilder editContent = new StringBuilder(); + for (String param : zendParams) + { + editContent.append(param); + editContent.append("\n"); + } + + this.optionsEditArea = new JTextArea(editContent.toString()); + JScrollPane pane = new JScrollPane(this.optionsEditArea); + detailsPanel.add(pane); + + detailsPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + this.getContentPane().add(detailsPanel, BorderLayout.CENTER); + + buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 15, 3)); + JButton closeButon = new JButton(langUtil.getString("zend.cmd.params.dialog.close.button")); + buttonPanel.add(closeButon); + this.getContentPane().add(buttonPanel, BorderLayout.SOUTH); + + closeButon.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + ZendParametersEditDialog.this.setVisible(false); + ZendParametersEditDialog.this.dispose(); + } + }); + + JButton saveButon = new JButton(langUtil.getString("zend.cmd.params.dialog.save.button")); + buttonPanel.add(saveButon); + saveButon.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + try + { + // Process the logic of saving the data + if (ZendParametersEditDialog.this.saveZendParameters()) + { + ZendParametersEditDialog.this.setVisible(false); + ZendParametersEditDialog.this.dispose(); + } + } catch (Exception ex) + { + Log.error("Unexpected error in editing own messaging identity!", ex); + ZendParametersEditDialog.this.errorReporter.reportError(ex, false); + } + } + }); + + this.pack(); + this.setLocation(100, 100); + this.setLocationRelativeTo(parentFrame); + + Dimension currentSize = this.getSize(); + if ((currentSize.width > 1100) || (currentSize.height > 500)) + { + this.setSize(new Dimension(Math.min(currentSize.width, 1100), Math.min(currentSize.height, 500))); + this.validate(); + this.repaint(); + } + } + + + /** + * Handles the saving of the options possibly edited by the user. + * + * @return true if successufl, false if cancelled + * + * @throws IOException + */ + private boolean saveZendParameters() + throws IOException + { + // Get the new zend parameters from the text area + List optionsToSet = new ArrayList(); + // Read current text - meaningful lines + LineNumberReader r = null; + try + { + r = new LineNumberReader(new StringReader(this.optionsEditArea.getText())); + String line; + while ((line = r.readLine()) != null) + { + line = line.trim(); + + if ((line.length() <= 0) || line.startsWith("#")) + { + continue; + } + optionsToSet.add(line); + } + + } finally + { + if (r != null) + { + r.close(); + } + } + + // Check for multiple options on the same line + for (String option : optionsToSet) + { + if (option.contains(" ") && + ((option.indexOf("=") != option.lastIndexOf("=")) || + (option.indexOf("-") != option.lastIndexOf("-")))) + { + // Warn on possible multiple options per line + int answer = JOptionPane.showConfirmDialog( + ZendParametersEditDialog.this, + langUtil.getString("zend.cmd.params.dialog.double.option.warning.text", option), + langUtil.getString("zend.cmd.params.dialog.double.option.warning.title"), + JOptionPane.YES_NO_OPTION); + if (answer == JOptionPane.NO_OPTION) + { + return false; + } + } + } + + // Load the existing file into individual lines (no exceptions). + List zendFullFileLines = Util.loadZendParameters(false); + + // Double iteration to replace the options that have changed + for (String optionToSet : optionsToSet) + { + boolean bFound = false; + + all_file_options_loop: + for (int oo = 0; oo < zendFullFileLines.size(); oo++) + { + String currentOptionToCheck = zendFullFileLines.get(oo); + + if ((currentOptionToCheck.trim().length() <= 0) || + currentOptionToCheck.trim().startsWith("#")) + { + continue all_file_options_loop; + } + + if (getParamName(optionToSet).equals(getParamName(currentOptionToCheck)) && + (!isMultiOccurrenceOption(currentOptionToCheck))) + { + if ((!optionToSet.equals(currentOptionToCheck))) + { + Log.info("Saving user-modified zend option at line {0}: {1}", oo, optionToSet); + zendFullFileLines.set(oo, optionToSet); + } + + bFound = true; + } + + if (optionToSet.equals(currentOptionToCheck) && isMultiOccurrenceOption(currentOptionToCheck)) + { + bFound = true; // Found but not replaced + } + } + + if (!bFound) + { + Log.info("Adding user-created zend option at line {0}: {1}", zendFullFileLines.size(), optionToSet); + zendFullFileLines.add(optionToSet); + } + } + + // Handle options that may be deleted - another double iteration + all_file_options_loop2: + for (int oo = 0; oo < zendFullFileLines.size(); oo++) + { + String currentOptionToCheck = zendFullFileLines.get(oo); + + if ((currentOptionToCheck.trim().length() <= 0) || + currentOptionToCheck.trim().startsWith("#")) + { + continue all_file_options_loop2; + } + + boolean bRemove = true; + + for (String optionToSet : optionsToSet) + { + if (getParamName(optionToSet).equals(getParamName(currentOptionToCheck)) && + (!isMultiOccurrenceOption(currentOptionToCheck))) + { + bRemove = false; + } + + if (optionToSet.equals(currentOptionToCheck) && isMultiOccurrenceOption(currentOptionToCheck)) + { + bRemove = false; + } + } + + if (bRemove) + { + Log.info("Removing user-deleted zend option at line {0}: {1}", oo, currentOptionToCheck); + zendFullFileLines.set(oo, ""); + } + } + + + // Finally save the file + String settingsDir = OSUtil.getSettingsDirectory(); + File dir = new File(settingsDir); + File zendOptionsFile = new File(dir, "zend-cmd-options.conf"); + + Util.renameFileForMultiVersionBackup(dir, zendOptionsFile.getName()); + + PrintWriter configOut = null; + try + { + configOut = new PrintWriter(zendOptionsFile, "UTF-8"); + int emptyLineCount = 0; + for (String line : zendFullFileLines) + { + if (line.trim().length() > 0) + { + emptyLineCount = 0; + } else + { + emptyLineCount++; + } + + if (emptyLineCount <= 2) + { + configOut.println(line); + } + } + } finally + { + Log.info("Successfully created new version of file: {0}", zendOptionsFile.getCanonicalPath()); + configOut.close(); + } + + // Inform the user of successful save - and the need to restart + JOptionPane.showMessageDialog( + ZendParametersEditDialog.this, + langUtil.getString("zend.cmd.params.dialog.success.text", zendOptionsFile.getCanonicalPath()), + langUtil.getString("zend.cmd.params.dialog.success.title"), + JOptionPane.INFORMATION_MESSAGE); + + return true; + } + + + /** + * Distinguishes between single and multi-occurrece options for the purpose + * of replacing them. + * + * @param fullParam fill config line + * + * @return + */ + private boolean isMultiOccurrenceOption(String fullParam) + { + String paramName = this.getParamName(fullParam); + + return paramName.equals("addnode"); // For now only addnode seems to be a multi-occur option + } + + + /** + * Utility: given a full option specification, provides the option name only + * + * @param fullParam must not be null + * + * @return param name (as best as can be identified) + */ + private String getParamName(String fullParam) + { + String param = fullParam.trim(); + while (param.startsWith("-")) + { + param = param.substring(1); + } + + if (param.contains("=")) + { + param = param.substring(0, param.indexOf("=")); + } + + return param; + } +} diff --git a/src/java/com/vaklinov/zcashui/msg/CreateGroupDialog.java b/src/java/com/vaklinov/zcashui/msg/CreateGroupDialog.java index 8220ff80..dfcdcd1d 100644 --- a/src/java/com/vaklinov/zcashui/msg/CreateGroupDialog.java +++ b/src/java/com/vaklinov/zcashui/msg/CreateGroupDialog.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,6 +50,7 @@ import javax.swing.JTextField; import javax.swing.SwingUtilities; +import com.vaklinov.zcashui.LabelStorage; import com.vaklinov.zcashui.Log; import com.vaklinov.zcashui.StatusUpdateErrorReporter; import com.vaklinov.zcashui.Util; @@ -58,8 +60,6 @@ /** * Dialog showing the messaging options and allowing them to be edited. - * - * @author Ivan Vaklinov */ public class CreateGroupDialog extends JDialog @@ -84,9 +84,13 @@ public class CreateGroupDialog JButton okButon; JButton cancelButon; + LabelStorage labelStorage; + protected MessagingIdentity createdGroup = null; - public CreateGroupDialog(MessagingPanel msgPanel, JFrame parentFrame, MessagingStorage storage, StatusUpdateErrorReporter errorReporter, ZCashClientCaller caller) + public CreateGroupDialog(MessagingPanel msgPanel, JFrame parentFrame, MessagingStorage storage, + StatusUpdateErrorReporter errorReporter, ZCashClientCaller caller, + LabelStorage labelStorage) throws IOException { super(parentFrame); @@ -96,6 +100,7 @@ public CreateGroupDialog(MessagingPanel msgPanel, JFrame parentFrame, MessagingS this.storage = storage; this.errorReporter = errorReporter; this.caller = caller; + this.labelStorage = labelStorage; this.setTitle("Add messaging group..."); this.setModal(true); @@ -329,6 +334,12 @@ private void createGroupForKeyPhrase(String keyPhrase) JOptionPane.INFORMATION_MESSAGE); } + // In any case set the label + if (!Util.stringIsEmpty(ZAddress)) + { + this.labelStorage.setLabel(ZAddress, keyPhrase); + } + SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/src/java/com/vaklinov/zcashui/msg/IPFSWrapper.java b/src/java/com/vaklinov/zcashui/msg/IPFSWrapper.java index 19ea7229..e3a1bbb9 100644 --- a/src/java/com/vaklinov/zcashui/msg/IPFSWrapper.java +++ b/src/java/com/vaklinov/zcashui/msg/IPFSWrapper.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -64,8 +65,6 @@ /** * Encapsulates access to IPFS for file sharing. - * - * @author Ivan Vaklinov */ public class IPFSWrapper { @@ -197,7 +196,7 @@ public String shareFileViaIPFS() // true if started OK private boolean ensureIPFSIsRunning() - throws IOException, InterruptedException + throws IOException, InterruptedException, URISyntaxException { // TODO: As of Nov 2017 the IPFS wallet integration is suspended. This method just returns // true. This is to be corrected when IPFS integration resumes. @@ -222,7 +221,7 @@ private boolean ensureIPFSIsRunning() // true if started OK private boolean startIPFS() - throws IOException, InterruptedException + throws IOException, InterruptedException, URISyntaxException { // Warn user if executable and dir are missing! File dir = new File(this.getIPFSDirectory()); @@ -327,7 +326,7 @@ private boolean getUserConsentToStartIPFS() "the details of IPFS at this web site: https://ipfs.io/\n" + "\n" + "The IPFS server needs TCP ports 4001, 5001, 8080 on the system for its own use!\n" + - "The IPFS server will be stopped automatically if you quit the ZENCash wallet. To\n" + + "The IPFS server will be stopped automatically if you quit the Horizen wallet. To\n" + "ensure that your contacts can reach the data you share, you may not quit the\n" + "wallet for as long as you expect your contacts to access the data. The data you\n" + "share over IPFS is public - may be accessed by anyone! The IPFS server startup\n" + @@ -376,14 +375,14 @@ private DaemonInfo getIPFSDaemonInfo() private String getIPFSFullExecutablePath() - throws IOException + throws IOException, URISyntaxException { return this.getIPFSDirectory() + File.separator + this.getIPFSExecutableName(); } private String getIPFSDirectory() - throws IOException + throws IOException, URISyntaxException { String walletBase = OSUtil.getProgramDirectory(); diff --git a/src/java/com/vaklinov/zcashui/msg/IdentityInfoDialog.java b/src/java/com/vaklinov/zcashui/msg/IdentityInfoDialog.java index 4f9fe587..479279a3 100644 --- a/src/java/com/vaklinov/zcashui/msg/IdentityInfoDialog.java +++ b/src/java/com/vaklinov/zcashui/msg/IdentityInfoDialog.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +29,8 @@ **********************************************************************************/ package com.vaklinov.zcashui.msg; +import com.vaklinov.zcashui.LanguageUtil; + import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; @@ -49,8 +52,6 @@ /** * Dialog showing the information about a user's identity - * - * @author Ivan Vaklinov */ public class IdentityInfoDialog extends JDialog @@ -62,6 +63,7 @@ public class IdentityInfoDialog protected JPanel buttonPanel; + protected JTextField nicknameTextField; protected JTextArea sendreceiveaddressTextField; protected JTextField senderidaddressTextField; @@ -76,10 +78,11 @@ public class IdentityInfoDialog public IdentityInfoDialog(JFrame parentFrame, MessagingIdentity identity) { + LanguageUtil langUtil = LanguageUtil.instance(); this.parentFrame = parentFrame; this.identity = identity; - this.setTitle("Contact details for: " + identity.getDiplayString()); + this.setTitle(langUtil.getString("dialog.identity.info.title", identity.getDiplayString())); this.setModal(true); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); @@ -99,7 +102,7 @@ public IdentityInfoDialog(JFrame parentFrame, MessagingIdentity identity) addFormField(detailsPanel, "Nick name:", nicknameTextField = new JTextField(40)); addFormField(detailsPanel, "First name:", firstnameTextField = new JTextField(40)); - addFormField(detailsPanel, "Midle name:", middlenameTextField = new JTextField(40)); + addFormField(detailsPanel, "Middle name:", middlenameTextField = new JTextField(40)); addFormField(detailsPanel, "Surname:", surnameTextField = new JTextField(40)); addFormField(detailsPanel, "E-mail:", emailTextField = new JTextField(40)); @@ -166,7 +169,7 @@ private void addFormField(JPanel detailsPanel, String name, JComponent field) JPanel tempPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 4, 2)); JLabel tempLabel = new JLabel(name, JLabel.RIGHT); // TODO: hard sizing of labels may not scale! - final int width = new JLabel("Sender identiication T address:").getPreferredSize().width + 10; + final int width = new JLabel("Sender identification T address:").getPreferredSize().width + 10; tempLabel.setPreferredSize(new Dimension(width, tempLabel.getPreferredSize().height)); tempPanel.add(tempLabel); tempPanel.add(field); diff --git a/src/java/com/vaklinov/zcashui/msg/JContactListPanel.java b/src/java/com/vaklinov/zcashui/msg/JContactListPanel.java index 235902c4..d19705aa 100644 --- a/src/java/com/vaklinov/zcashui/msg/JContactListPanel.java +++ b/src/java/com/vaklinov/zcashui/msg/JContactListPanel.java @@ -6,7 +6,8 @@ * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| * - * Copyright (c) 2017 Ivan Vaklinov + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -75,8 +76,6 @@ /** * Main panel for messaging - * - * @author Ivan Vaklinov */ public class JContactListPanel extends JPanel @@ -298,8 +297,8 @@ public void sendContactDetailsToSelectedContact() int reply = JOptionPane.showConfirmDialog( this.parentFrame, "The contact: " + id.getDiplayString() + "\n" + - "is anonymous. Sending your contact details to him will reveal your messaging\n" + - "identity! Are you sure you want to send your contact details to him?", + "is anonymous. Sending your contact details to them will reveal your messaging\n" + + "identity! Are you sure you want to send your contact details to them?", "Are you sure you want to send your contact details", JOptionPane.YES_NO_OPTION); diff --git a/src/java/com/vaklinov/zcashui/msg/Message.java b/src/java/com/vaklinov/zcashui/msg/Message.java index 6eecf7a6..0933c793 100644 --- a/src/java/com/vaklinov/zcashui/msg/Message.java +++ b/src/java/com/vaklinov/zcashui/msg/Message.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -48,8 +49,6 @@ /** * Encapsulates a zen message - * - * @author Ivan Vaklinov */ public class Message { @@ -319,7 +318,7 @@ public void setReturnAddress(String returnAddress) /** * Verifies if a message represented as a JSON object is valid according to the * ZEN messaging protocol: - * https://github.com/ZencashOfficial/messaging-protocol/blob/master/README.md + * https://github.com/HorizenOfficial/messaging-protocol/blob/master/README.md * * @param message * diff --git a/src/java/com/vaklinov/zcashui/msg/MessagingIdentity.java b/src/java/com/vaklinov/zcashui/msg/MessagingIdentity.java index f1d11755..5671d78f 100644 --- a/src/java/com/vaklinov/zcashui/msg/MessagingIdentity.java +++ b/src/java/com/vaklinov/zcashui/msg/MessagingIdentity.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -41,18 +42,17 @@ import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.WriterConfig; +import com.vaklinov.zcashui.LanguageUtil; import com.vaklinov.zcashui.Util; /** * Encapsulates a messaging identity. - * - * @author Ivan Vaklinov */ public class MessagingIdentity { // Fields based on the ZEN messaging protocol - // https://github.com/ZencashOfficial/messaging-protocol/blob/master/README.md + // https://github.com/HorizenOfficial/messaging-protocol/blob/master/README.md private String nickname; private String sendreceiveaddress; private String senderidaddress; @@ -68,6 +68,7 @@ public class MessagingIdentity private boolean isAnonymous; // If the remote contact sends messages anonymously private String threadID; // Thread ID for anonymous messages private boolean isGroup; // If it represents a messaging group + private LanguageUtil langUtil; // TODO: automatically cut fields to XXX length to avoid issues with accidental big data @@ -76,7 +77,8 @@ public MessagingIdentity() // By default it is not anonymous - filling the rest is the responsibility of the caller this.isAnonymous = false; this.isGroup = false; - this.threadID = ""; + this.threadID = ""; + langUtil = LanguageUtil.instance(); } diff --git a/src/java/com/vaklinov/zcashui/msg/MessagingOptions.java b/src/java/com/vaklinov/zcashui/msg/MessagingOptions.java index f7a26522..ba864fdf 100644 --- a/src/java/com/vaklinov/zcashui/msg/MessagingOptions.java +++ b/src/java/com/vaklinov/zcashui/msg/MessagingOptions.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,8 +47,6 @@ /** * Encapsulates the messaging options that may be set. - * - * @author Ivan Vaklinov */ public class MessagingOptions { @@ -58,7 +57,7 @@ public class MessagingOptions public MessagingOptions() { - // Default values set if not loade etc. + // Default values set if not loaded etc. this.automaticallyAddUsersIfNotExplicitlyImported = true; this.amountToSend = this.transactionFee = 0.0001d; } diff --git a/src/java/com/vaklinov/zcashui/msg/MessagingOptionsEditDialog.java b/src/java/com/vaklinov/zcashui/msg/MessagingOptionsEditDialog.java index a4bc4f9a..e8e95588 100644 --- a/src/java/com/vaklinov/zcashui/msg/MessagingOptionsEditDialog.java +++ b/src/java/com/vaklinov/zcashui/msg/MessagingOptionsEditDialog.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -58,8 +59,6 @@ /** * Dialog showing the messaging options and allowing them to be edited. - * - * @author Ivan Vaklinov */ public class MessagingOptionsEditDialog extends JDialog @@ -94,7 +93,7 @@ public MessagingOptionsEditDialog(JFrame parentFrame, MessagingStorage storage, tempPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); infoLabel = new JLabel( "" + - "The options below pertain to messaging. It is posisble to set the amount of ZEN
" + + "The options below pertain to messaging. It is possible to set the amount of ZEN
" + "to be sent with every messaging transaction and also the transaction fee. It is
" + "also possible to decide if users are to be automatically added to the contact list.

" + "
"); diff --git a/src/java/com/vaklinov/zcashui/msg/MessagingPanel.java b/src/java/com/vaklinov/zcashui/msg/MessagingPanel.java index b7d5b756..31e700c8 100644 --- a/src/java/com/vaklinov/zcashui/msg/MessagingPanel.java +++ b/src/java/com/vaklinov/zcashui/msg/MessagingPanel.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -79,6 +80,7 @@ import com.eclipsesource.json.JsonValue; import com.eclipsesource.json.WriterConfig; import com.vaklinov.zcashui.DataGatheringThread; +import com.vaklinov.zcashui.LabelStorage; import com.vaklinov.zcashui.Log; import com.vaklinov.zcashui.OSUtil; import com.vaklinov.zcashui.SendCashPanel; @@ -94,8 +96,6 @@ /** * Main panel for messaging - * - * @author Ivan Vaklinov */ public class MessagingPanel extends WalletTabPanel @@ -132,9 +132,12 @@ public class MessagingPanel private IPFSWrapper ipfs; + // Storage of labels + private LabelStorage labelStorage; public MessagingPanel(JFrame parentFrame, SendCashPanel sendCashPanel, JTabbedPane parentTabs, - ZCashClientCaller clientCaller, StatusUpdateErrorReporter errorReporter) + ZCashClientCaller clientCaller, StatusUpdateErrorReporter errorReporter, + LabelStorage labelStorage) throws IOException, InterruptedException, WalletCallException { super(); @@ -142,6 +145,7 @@ public MessagingPanel(JFrame parentFrame, SendCashPanel sendCashPanel, JTabbedPa this.parentFrame = parentFrame; this.sendCashPanel = sendCashPanel; this.parentTabs = parentTabs; + this.labelStorage = labelStorage; this.clientCaller = clientCaller; this.errorReporter = errorReporter; @@ -330,7 +334,7 @@ public void handleURL(URL u) } else { messageStart = - "This user is " + (anonymous ? "" : "not ") + "anonumous; " + + "This user is " + (anonymous ? "" : "not ") + "anonymous; " + (anonymous ? "" : "However ") + "his messaging identity is not known. " + "He is only identified \nby " + (anonymous ? "thread ID" : "a sender ID address:") + "\n" + id + "\n"; @@ -340,7 +344,7 @@ public void handleURL(URL u) MessagingPanel.this.parentFrame, messageStart + "\n" + "If you believe this user is spamming the group conversation, you have the option to\n" + - "ignore all his mesages. \n\n" + + "ignore all his messages. \n\n" + "WARNING: If you choose to ignore this user's messages, you will not be able to see \n"+ "any new messages he sends from this point forward!", "Possibly ignore user messages?", @@ -514,7 +518,7 @@ public void displayMessagesForContact(MessagingIdentity contact) /** - * Called when the TAB is selected - currently shows the welcome mesage + * Called when the TAB is selected - currently shows the welcome message */ public void tabSelected() { @@ -524,15 +528,15 @@ public void tabSelected() { JOptionPane.showMessageDialog( this.parentFrame, - "Welcome to ZENCash messaging. As a start you will need to create a new messaging\n" + - "identity for yourself. As a part of this mesaging identity a pair of T+Z addresses\n" + + "Welcome to Horizen messaging. As a start you will need to create a new messaging\n" + + "identity for yourself. As a part of this messaging identity a pair of T+Z addresses\n" + "will be created. The T address is to be used for identifying you to other users.\n" + "It must never be used for other financial transactions since this might reduce or\n" + "fully compromise your privacy. The Z address is to be used to send and receive\n" + "messages.\n\n" + "When creating a new messaging identity it is only mandatory to specify a nick-name\n" + "for yourself. All other items such as names/addresses etc. are optional. The \n" + - "information in the mesaging identity is meant to be shared with other users so \n" + + "information in the messaging identity is meant to be shared with other users so \n" + "you need to be careful about the details you disclose.\n\n" + "Once your messaging identity has been created you can export it to a file using the\n" + "menu option Messaging >> Export own identity. This file may then be shared with\n" + @@ -542,7 +546,7 @@ public void tabSelected() "Your messaging history will be saved and maintained in directory:\n" + OSUtil.getSettingsDirectory() + File.separator + "messaging" + "\n" + "You need to ensure that no unauthorized users have access to it on this computer.\n\n" + - "(This mesage will be shown only once.)", + "(This message will be shown only once.)", "Welcome to messaging", JOptionPane.INFORMATION_MESSAGE); // Show the GUI dialog to edit an initially empty messaging identity @@ -571,7 +575,7 @@ public void tabSelected() "The Z address used to send/receive messages needs to be supplied with ZEN: \n" + ownIdentity.getSendreceiveaddress() + "\n" + "You will be redirected to the UI tab for sending ZEN to add some balance to it. You need only\n" + - "a small amount e.g. typically 0.1 ZEN is suffucient to send 500 messages. After sending some\n" + + "a small amount e.g. typically 0.1 ZEN is sufficient to send 500 messages. After sending some\n" + "ZEN you need to wait for the transaction to be confirmed (typically takes 2.5 minutes). It is\n" + "recommended to send ZEN to this Z address in two or more separate transactions (though one \n" + "transaction is sufficient).", @@ -579,7 +583,7 @@ public void tabSelected() JOptionPane.INFORMATION_MESSAGE); sendCashPanel.prepareForSending(ownIdentity.getSendreceiveaddress()); - parentTabs.setSelectedIndex(2); + parentTabs.setSelectedIndex(3); } } else { @@ -622,7 +626,7 @@ public void tabSelected() } } catch (Exception ex) { - Log.error("Unexpected error in messagign TAB selection processing", ex); + Log.error("Unexpected error in messaging TAB selection processing", ex); this.errorReporter.reportError(ex, false); } } @@ -682,8 +686,10 @@ public boolean openOwnIdentityDialog() String ZAddress = this.clientCaller.createNewAddress(true); - // TODO: update address book (later on) - + // Update the labels for the two addresses + this.labelStorage.setLabel(TAddress, "Own Messaging ID T address"); + this.labelStorage.setLabel(ZAddress, "Own Messaging ID Z address"); + ownIdentity.setSenderidaddress(TAddress); ownIdentity.setSendreceiveaddress(ZAddress); } finally @@ -775,7 +781,7 @@ public void exportOwnIdentity() JOptionPane.showMessageDialog( this.parentFrame, - "Your messaging identity has been succesfully exported to file: \n" + + "Your messaging identity has been successfully exported to file: \n" + f.getName() + "\n" + "You may give this file to other users to establish contact with them.\n" + "They may in turn import it into their wallet/messenger application.", @@ -852,7 +858,7 @@ public void importContactIdentity() "There is already a contact in your contact list with the same identity. \n\n" + "Existing contact identity: " + mi.getDiplayString() + "\n" + "Contact identity being imported: " + contactIdentity.getDiplayString() + "\n\n" + - "Two identities are consiered the same if their T/Z addresses are the same. \n" + + "Two identities are considered the same if their T/Z addresses are the same. \n" + "Do you want to replace the details of the existing messaging identity, with\n" + "the one being imported?", "The same contact identity is already available", JOptionPane.YES_NO_OPTION); @@ -914,7 +920,7 @@ public void importContactIdentity() "You can now send and receive messages from this contact. Do you wish\n" + "to send a limited sub-set of your contact details to this new contact\n" + "as a special message?\n\n" + - "This will allow him/her to establish contact with you without manaully\n" + + "This will allow him/her to establish contact with you without manually\n" + "importing your messaging identity (the way you imported his identity).", "Successfully imported. Send your identity over?", JOptionPane.YES_NO_OPTION); @@ -972,7 +978,7 @@ public void removeSelectedContact() "" : id.getSendreceiveaddress(); int reply = JOptionPane.showConfirmDialog( this.parentFrame, - "The " + (id.isGroup() ? "messaging group " : "conact ") + id.getDiplayString() + "\n" + + "The " + (id.isGroup() ? "messaging group " : "contact ") + id.getDiplayString() + "\n" + "with messaging identification T address:\n" + contactTAddress + "\n" + "and send/receive Z address:\n" + @@ -980,7 +986,7 @@ public void removeSelectedContact() "will be permanently deleted from your contact list! All incoming messages from\n" + "this contact will subsequently be ignored. Are you sure you want to remove the\n" + "selected contact?", - "Are you sure you wish to remove the contant?", + "Are you sure you wish to remove the contact?", JOptionPane.YES_NO_OPTION); if (reply == JOptionPane.NO_OPTION) @@ -1077,7 +1083,7 @@ private void sendMessage(String textToSend, MessagingIdentity remoteIdentity) "seems to have no valid Z address for sending and receiving messages. \n"; errroMessage += contactIdentity.isAnonymous() ? ("Since the contact is anonymous this means that the contact intentionally did\n" + - "not send his Z address (for replies to be psosible). Message cannot be sent!") + "not send his Z address (for replies to be possible). Message cannot be sent!") : ("Most likely the reason is that this contact's messaging identity is not \n" + "imported yet. Message cannot be sent!"); @@ -1100,7 +1106,7 @@ private void sendMessage(String textToSend, MessagingIdentity remoteIdentity) // Offer the user to send a return address int reply = JOptionPane.showConfirmDialog( this.parentFrame, - "This is the first anomymous message you are sending to contact: \n" + + "This is the first anonymous message you are sending to contact: \n" + contactIdentity.getDiplayString() + "\n" + "Do you wish to send him your send/receive messaging Z address so\n" + "that the contact may be able to answer your anonymous messages?", @@ -1215,8 +1221,8 @@ private void sendMessage(String textToSend, MessagingIdentity remoteIdentity) "The Z address used to send/receive messages has insufficient balance: \n" + ownIdentity.getSendreceiveaddress() + "\n" + "You will be redirected to the UI tab for sending ZEN to add some balance to it. You need only\n" + - "a small amount e.g. typically 0.1 ZEN is suffucient to send 500 messages. After sending some\n" + - "ZEN you need to wait for the transaciton to be confirmed (typically takes 2.5 minutes). It is\n" + + "a small amount e.g. typically 0.1 ZEN is sufficient to send 500 messages. After sending some\n" + + "ZEN you need to wait for the transaction to be confirmed (typically takes 2.5 minutes). It is\n" + "recommended to send ZEN to this Z address in two or more separate transactions (though one \n" + "transaction is sufficient).", "Z address to send/receive messages has insufficient balance...", JOptionPane.ERROR_MESSAGE); @@ -1226,7 +1232,7 @@ private void sendMessage(String textToSend, MessagingIdentity remoteIdentity) this.writeMessageTextArea.setEnabled(true); sendCashPanel.prepareForSending(ownIdentity.getSendreceiveaddress()); - parentTabs.setSelectedIndex(2); + parentTabs.setSelectedIndex(3); return; } @@ -1238,8 +1244,8 @@ private void sendMessage(String textToSend, MessagingIdentity remoteIdentity) this.parentFrame, "The Z address used to send/receive messages has insufficient confirmed balance: \n" + ownIdentity.getSendreceiveaddress() + "\n" + - "This usually means that the previous mesasaging transaction is not yet confirmed. You\n" + - "need to wait for the transaciton to be confirmed (typically takes 2.5 minutes). This\n" + + "This usually means that the previous messaging transaction is not yet confirmed. You\n" + + "need to wait for the transaction to be confirmed (typically takes 2.5 minutes). This\n" + "problem may be avoided if you send ZEN to this Z address in two or more separate \n" + "transactions (when you supply the ZEN balance to be used for messaging).", "Z address to send/receive messages has insufficient confirmed balance...", JOptionPane.ERROR_MESSAGE); @@ -1539,14 +1545,14 @@ private void collectAndStoreNewReceivedMessages(MessagingIdentity groupIdentity) MessagingPanel.this.getRootPane().getParent(), "The messaging identity send/receive address: \n" + ownZAddress + "\n" + - "is not found in the wallet.dat. The reason may be that after a mesaging identity\n" + + "is not found in the wallet.dat. The reason may be that after a messaging identity\n" + "was created the wallet.dat was changed or the ZEN node configuration was changed\n" + "(e.g. mainnet -> testnet). If such a change was made, the messaging identity can no\n" + - "longer be used. To avoid this error mesage, you may rename the directory:\n" + + "longer be used. To avoid this error message, you may rename the directory:\n" + OSUtil.getSettingsDirectory() + File.separator + "messaging" + "\n" + "until the configuration or wallet.dat is restored! Directory may only be renamed when\n" + "the wallet is stopped!", - "Messaging identity address is not found in walet!", JOptionPane.ERROR_MESSAGE); + "Messaging identity address is not found in wallet!", JOptionPane.ERROR_MESSAGE); return; } @@ -1624,7 +1630,7 @@ private void collectAndStoreNewReceivedMessages(MessagingIdentity groupIdentity) { // Warn of unexpected message content Log.warningOneTime( - "Ignoring received mesage with invalid or incomplete content: {0}", + "Ignoring received message with invalid or incomplete content: {0}", jsonMessage.toString()); } } @@ -1855,7 +1861,7 @@ public boolean isZENIdentityMessage(String message) } - // Copies the fields sent over the wire - limited set - some day all fields will be sent + // Copies the fields sent over the wire - limited set - someday all fields will be sent // Sender ID address is assumed to be the same public void updateAndStoreExistingIdentityFromIDMessage(MessagingIdentity existingIdentity, String idMessage) throws IOException @@ -1903,7 +1909,7 @@ public void addMessagingGroup() try { CreateGroupDialog cgd = new CreateGroupDialog( - this, this.parentFrame, this.messagingStorage, this.errorReporter, this.clientCaller); + this, this.parentFrame, this.messagingStorage, this.errorReporter, this.clientCaller, this.labelStorage); cgd.setVisible(true); if (!cgd.isOKPressed()) @@ -1924,7 +1930,7 @@ public void addMessagingGroup() // TODO: code duplication with import if (sendIDChoice == JOptionPane.YES_OPTION) { - // Only a limited set of values is sent over the wire, due tr the limit of 330 + // Only a limited set of values is sent over the wire, due to the limit of 330 // characters. // TODO: use protocol versions with larger messages MessagingIdentity ownIdentity = this.messagingStorage.getOwnIdentity(); JsonObject innerIDObject = new JsonObject(); @@ -1991,7 +1997,7 @@ private Map getKnownSendersForGroup(MessagingIdentity public void sendIdentityMessageTo(MessagingIdentity contactIdentity) throws InterruptedException, IOException, WalletCallException { - // Only a limited set of values is sent over the wire, due tr the limit of 330 + // Only a limited set of values is sent over the wire, due to the limit of 330 // characters. // TODO: use protocol versions with larger messages MessagingIdentity ownIdentity = this.messagingStorage.getOwnIdentity(); JsonObject innerIDObject = new JsonObject(); @@ -2014,7 +2020,7 @@ public void sendIdentityMessageTo(MessagingIdentity contactIdentity) this.parentFrame, "The size of your messaging identity is unfortunately too large to be sent\n" + "as a message. Your contact will have to import your messaging identity\n" + - "manaully from a json file...", + "manually from a json file...", "Messaging identity size is too large!", JOptionPane.ERROR_MESSAGE); return; } diff --git a/src/java/com/vaklinov/zcashui/msg/MessagingStorage.java b/src/java/com/vaklinov/zcashui/msg/MessagingStorage.java index 4f135d00..0f49b8dc 100644 --- a/src/java/com/vaklinov/zcashui/msg/MessagingStorage.java +++ b/src/java/com/vaklinov/zcashui/msg/MessagingStorage.java @@ -5,8 +5,9 @@ * / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| - * - * Copyright (c) 2017 Ivan Vaklinov + * + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -74,8 +75,6 @@ * * The sent/received directories have a substructure of type: * sent/XXXX/message_xxx.json - where XXXX is between 0000 and 9999, xxx is between 000 and 999 - * - * @author Ivan Vaklinov */ public class MessagingStorage { @@ -132,7 +131,7 @@ public void addIgnoredContact(MessagingIdentity contact) } - // If a message is from an igonred contact - returns it, else null + // If a message is from an ignored contact - returns it, else null public MessagingIdentity getIgnoredContactForMessage(Message msg) { MessagingIdentity contact = null; @@ -358,7 +357,7 @@ public boolean accept(File pathname) int contactDirIndex = contactDirs.length; String contactDirName; - // We need to make sure the dir does not exist.. if it does maybe users were removed before etc + // We need to make sure the dir does not exist. If it does maybe users were removed before etc // so we increment! do { @@ -515,9 +514,9 @@ public void updateAnonumousContactIdentityForThreadID(String threadID, Messaging /** * Returns all known messages for a certain contact in ascending date order. - * If identity not found etc. thorws an exception + * If identity not found etc. throws an exception * - * @param conact + * @param contact * * @return all known messages for a certain contact in ascending date order. */ diff --git a/src/java/com/vaklinov/zcashui/msg/OwnIdentityEditDialog.java b/src/java/com/vaklinov/zcashui/msg/OwnIdentityEditDialog.java index 959a8d1f..0f360d2f 100644 --- a/src/java/com/vaklinov/zcashui/msg/OwnIdentityEditDialog.java +++ b/src/java/com/vaklinov/zcashui/msg/OwnIdentityEditDialog.java @@ -6,7 +6,8 @@ * / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ * /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| * - * Copyright (c) 2017 Ivan Vaklinov + * Copyright (c) 2023 Horizen Foundation + * Copyright (c) 2016-2021 Zen Blockchain Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -42,8 +43,6 @@ /** * Dialog used to edit one's own identity - * - * @author Ivan Vaklinov */ public class OwnIdentityEditDialog extends IdentityInfoDialog diff --git a/src/resources/images/ZEN-yellow.orange-logo-small.png b/src/resources/images/ZEN-yellow.orange-logo-small.png index 421d16dc..4df16c04 100644 Binary files a/src/resources/images/ZEN-yellow.orange-logo-small.png and b/src/resources/images/ZEN-yellow.orange-logo-small.png differ diff --git a/src/resources/images/ZEN-yellow.orange-logo.png b/src/resources/images/ZEN-yellow.orange-logo.png index 8f550a04..a839a749 100644 Binary files a/src/resources/images/ZEN-yellow.orange-logo.png and b/src/resources/images/ZEN-yellow.orange-logo.png differ diff --git a/src/resources/images/connect0_16.png b/src/resources/images/connect0_16.png new file mode 100644 index 00000000..a397e7e6 Binary files /dev/null and b/src/resources/images/connect0_16.png differ diff --git a/src/resources/images/connect1_16.png b/src/resources/images/connect1_16.png new file mode 100644 index 00000000..199fb44c Binary files /dev/null and b/src/resources/images/connect1_16.png differ diff --git a/src/resources/images/connect2_16.png b/src/resources/images/connect2_16.png new file mode 100644 index 00000000..2a85ba50 Binary files /dev/null and b/src/resources/images/connect2_16.png differ diff --git a/src/resources/images/connect3_16.png b/src/resources/images/connect3_16.png new file mode 100644 index 00000000..d4b35ecc Binary files /dev/null and b/src/resources/images/connect3_16.png differ diff --git a/src/resources/images/connect4_16.png b/src/resources/images/connect4_16.png new file mode 100644 index 00000000..0376443b Binary files /dev/null and b/src/resources/images/connect4_16.png differ diff --git a/src/resources/images/german.png b/src/resources/images/german.png new file mode 100644 index 00000000..e44a1714 Binary files /dev/null and b/src/resources/images/german.png differ diff --git a/src/resources/images/italian.png b/src/resources/images/italian.png new file mode 100644 index 00000000..7fd8c56e Binary files /dev/null and b/src/resources/images/italian.png differ diff --git a/src/resources/images/lock_closed_s.png b/src/resources/images/lock_closed_s.png new file mode 100644 index 00000000..64bc3de4 Binary files /dev/null and b/src/resources/images/lock_closed_s.png differ diff --git a/src/resources/images/lock_opengreen_s.png b/src/resources/images/lock_opengreen_s.png new file mode 100644 index 00000000..2025486c Binary files /dev/null and b/src/resources/images/lock_opengreen_s.png differ diff --git a/src/resources/images/messaging.png b/src/resources/images/messaging.png index a0108e55..d87e3d6b 100644 Binary files a/src/resources/images/messaging.png and b/src/resources/images/messaging.png differ diff --git a/src/resources/images/tr_confirmed.png b/src/resources/images/tr_confirmed.png new file mode 100644 index 00000000..8a804b05 Binary files /dev/null and b/src/resources/images/tr_confirmed.png differ diff --git a/src/resources/images/tr_unconfirmed.png b/src/resources/images/tr_unconfirmed.png new file mode 100644 index 00000000..9f0aa5db Binary files /dev/null and b/src/resources/images/tr_unconfirmed.png differ diff --git a/src/resources/images/transactions.png b/src/resources/images/transactions.png new file mode 100644 index 00000000..a0108e55 Binary files /dev/null and b/src/resources/images/transactions.png differ diff --git a/src/resources/images/tx_inout.png b/src/resources/images/tx_inout.png new file mode 100644 index 00000000..360a841a Binary files /dev/null and b/src/resources/images/tx_inout.png differ diff --git a/src/resources/images/tx_input.png b/src/resources/images/tx_input.png new file mode 100644 index 00000000..c66f011a Binary files /dev/null and b/src/resources/images/tx_input.png differ diff --git a/src/resources/images/tx_mined.png b/src/resources/images/tx_mined.png new file mode 100644 index 00000000..4cb575a1 Binary files /dev/null and b/src/resources/images/tx_mined.png differ diff --git a/src/resources/images/tx_output.png b/src/resources/images/tx_output.png new file mode 100644 index 00000000..134f745f Binary files /dev/null and b/src/resources/images/tx_output.png differ diff --git a/src/resources/images/uk.png b/src/resources/images/uk.png new file mode 100644 index 00000000..91a812b6 Binary files /dev/null and b/src/resources/images/uk.png differ diff --git a/src/resources/keys/sapling-output.params b/src/resources/keys/sapling-output.params new file mode 100644 index 00000000..01760fa4 Binary files /dev/null and b/src/resources/keys/sapling-output.params differ diff --git a/src/resources/messages/zencash_en.properties b/src/resources/messages/zencash_en.properties new file mode 100644 index 00000000..79813474 --- /dev/null +++ b/src/resources/messages/zencash_en.properties @@ -0,0 +1,543 @@ +main.frame.title=Horizen Desktop GUI Wallet 1.0.12 +main.frame.progressbar=Starting GUI wallet... +main.frame.title.testnet=\u0020[using TESTNET] +main.frame.tab.overview.title=Overview\u0020 +main.frame.tab.transactions.title=Transactions\u0020 +main.frame.tab.own.address.title=Own addresses\u0020 +main.frame.tab.send.cash.title=Send cash\u0020 +main.frame.tab.address.book.title=Address book\u0020 +main.frame.tab.messaging.title=Messaging\u0020 +main.frame.disclaimer.text=The Horizen GUI Wallet is currently considered experimental. Use of this software\n\ + comes at your own risk! Be sure to read the list of known issues and limitations\n\ + at this page: https://github.com/HorizenOfficial/zencash-swing-wallet-ui\n\n\ + The Horizen Desktop GUI Wallet is not compatible with applications that modify\n\ + the ZEN wallet.dat file. The wallet should not be used with such applications\n\ + on the same PC. For instance some distributed exchange applications are known to\n\ + create watch-only addresses in the wallet.dat file that cause the GUI wallet to\n\ + display a wrong balance and/or display addresses that do not belong to the wallet.\n\n\ + Encryption of the wallet.dat file is not yet supported for Horizen. Using the wallet\n\ + on a system infected with malware may result in wallet data/funds being stolen. The\n\ + wallet.dat needs to be backed up regularly (not just once - e.g. after every 30-40\n\ + outgoing transactions) and it must also be backed up after creating a new Z address.\n\n\ + THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\ + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n\ + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n\ + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n\ + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n\ + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n\ + THE SOFTWARE.\n\n\ + (This message will be shown only once, per release) +main.frame.disclaimer.button.agree=I agree +main.frame.disclaimer.button.disagree=I do not agree! >> Exit +main.frame.disclaimer.title=Disclaimer +main.frame.option.pane.installation.error.text=This program was started in directory: {0} \n {1} \n \ + See the console/logfile output for more detailed error information! +main.frame.option.pane.installation.error.title=Installation error +main.frame.option.pane.wallet.communication.error.text=It appears that zend has been started but is not ready to accept wallet\n \ + connections. It is still loading the wallet and blockchain. Please try to \n \ + start the GUI wallet later... +main.frame.option.pane.wallet.communication.error.title=Wallet communication error +main.frame.option.pane.wallet.communication.error.2.text=There was a problem communicating with the Horizen daemon/wallet. \n \ + Please ensure that the Horizen server zend is started (e.g. via \n \ + command \"zend --daemon\"). Error message is: \n {0} \ + See the console/logfile output for more detailed error information! +main.frame.option.pane.wallet.communication.error.2.title=Wallet communication error +main.frame.option.pane.wallet.critical.error.text="A general unexpected critical error has occurred: \n {0} \n \ + See the console/logfile output for more detailed error information! +main.frame.option.pane.wallet.critical.error.title=Error +main.frame.option.pane.wallet.critical.error.2.text="A general unexpected critical/unrecoverable error has occurred: \n {0} \n \ + See the console/logfile output for more detailed error information! +main.frame.option.pane.wallet.critical.error.2.title=Error + + + +menu.label.main=Main +menu.label.wallet=Wallet +menu.label.messaging=Messaging +menu.label.about=About... +menu.label.quit=Quit... +menu.label.backup=Backup... +menu.label.encrypt=Encrypt... +menu.label.export.private.keys=Export private keys... +menu.label.import.private.keys=Import private keys... +menu.label.show.private.key=Show private key... +menu.label.import.one.private.key=Import one private key... +menu.label.export.to.arizen=Export to Arizen wallet... +menu.label.own.identity=Own identity... +menu.label.export.own.identity=Export own identity... +menu.label.add.messaging.group=Add messaging group... +menu.label.import.contact.identity=Import contact identity... +menu.label.remove.contact=Remove contact... +menu.label.options=Options... +menu.label.share.file=Share file via: +menu.label.ipfs=IPFS + + +menu.label.language=Language +menu.label.language.italian=Italian +menu.label.language.german=German +menu.label.language.english=English + + + +dialog.identity.info.title=Contact details for {0} + +dialog.message.language.prefs.update.title=Information +dialog.message.language.prefs.update=Your preference was saved, it will be active the next time you launch the application! + +dialog.about.title=About... +dialog.about.tab.title=About +dialog.about.licence=
\
+		     \u0020Copyright (c) 2018 Zel Technologies GmbH \n \
+             Copyright (c) 2018 Zel Foundation LLC \n \
+             Copyright (c) 2016-2021 Zen Blockchain Foundation \n \
+             Copyright (c) 2023 Horizen Foundation \n \
+			 \n \
+			 Permission is hereby granted, free of charge, to any person obtaining a copy\n \
+			 of this software and associated documentation files (the \Software\), to deal\n \
+			 in the Software without restriction, including without limitation the rights\n \
+			 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n \
+			 copies of the Software, and to permit persons to whom the Software is\n \
+			 furnished to do so, subject to the following conditions:\n \
+			 \n \
+			 The above copyright notice and this permission notice shall be included in\n \
+			 all copies or substantial portions of the Software.\n \
+			 \n \
+			 THE SOFTWARE IS PROVIDED \AS IS\, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n \
+			 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n \
+			 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n \
+			 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n \
+			 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n \
+			 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n \
+			 THE SOFTWARE.		\n \
+			
+dialog.about.front.text=Horizen Swing Wallet UI\ +

Copyright (c) 2023 The Horizen Foundation

\ +

Copyright (c) 2016-2021 Zen Blockchain Foundation

This program is \ + intended to make it easy to work with the Horizen client tools by providing
a \ + Graphical User Interface (GUI) that acts as a wrapper and presents the information in a \ +
user-friendly manner.

Acknowledgements: This program includes software for \ + JSON processing
(https://github.com/ralfstx/minimal-json) that is Copyright (c) 2015, \ + 2016 EclipseSource.
Additional libraries used are BitcoinJ (https://bitcoinj.github.io/) \ + and SQLite JDBC
(https://github.com/xerial/sqlite-jdbc) both under Apache License \ + Version 2.0.
Contains images/artwork from the Bitcoin project \ + (https://github.com/bitcoin/bitcoin).

+ +dialog.about.tab.title.licence=License +dialog.about.button.close.text=Close + + +panel.address.book.new.contact.button.text=New contact... +panel.address.book.send.zen.button.text=Send ZEN +panel.address.book.copy.clipboard.button.text=Copy address to clipboard +panel.address.book.delete.contact.button.text=Delete contact +panel.address.book.error.corrupted=Address Book is corrupted! +panel.address.book.option.pane.new.contact.msg=Please enter the name of the contact: +panel.address.book.option.pane.new.contact.title=Add new contact step 1 +panel.address.book.option.pane.new.contact.address=Please enter the t-address or z-address of {0} +panel.address.book.option.pane.new.contact.address.title=Add new contact step 2 +panel.address.book.menuitem.sendcash.text=Send ZEN to {0} +panel.address.book.menuitem.copy.address.text=Copy address to clipboard +panel.address.book.menuitem.delete.entry.text=Delete {0} from contacts +panel.address.book.button.sendcash.text=Send ZEN to {0} +panel.address.book.button.delete.contact.text=Delete contact {0} +panel.address.book.table.name=name +panel.address.book.table.address=address + + +panel.address.button.new.address=New T (Transparent) address +panel.address.button.new.z.address=New Z (Private) address +panel.address.button.refresh=Refresh +panel.address.label.warning= \ + * If the balance of an address is flagged as not confirmed, the address is currently taking \ + part in a transaction. The shown balance then is the expected value it will have when \ + the transaction is confirmed. \ + The average confirmation time is 2.5 min. \ + +panel.address.message.backup=\n\nIt is necessary to back up the wallet after creating a new Z address. The wallet needs\n\ + to be backed up to a safe location that can survive any data loss on the PC where the wallet\n\ + is currently located. Not backing up the wallet may result in loss of funds in case of data\n\ + loss on the current PC. To back up the wallet, use menu option: Wallet >> Backup\n +panel.address.option.pane.text=A new {0} address has been created successfully:\n\ + {1} {2} +panel.address.option.pane.title=Address created. +panel.address.table.create.address.header=Label:Balance:Confirmed?:Address +panel.address.option.pane.validation.error.text=An invalid or watch-only address exists in the wallet: \n \ + {0} \n\n \ + The GUI wallet software cannot operate properly with addresses that are invalid or\n \ + exist in the wallet as watch-only addresses. Do NOT use this address as a destination\n \ + address for payment operations! +panel.address.option.pane.validation.error.title=Error: invalid or watch-only address exists! +panel.address.option.pane.yes=Yes\u0020{0} +panel.address.option.pane.no=No\u0020\u0020{0} +panel.address.label.input.text=Please enter a label for the newly created address: +panel.address.label.input.title=Label of the address... +table.address.option.obtain.private.key.label=Obtain private key... +table.address.option.pane.text.private=Z (Private) +table.address.option.pane.text.transparent=T (Transparent) +table.address.option.pane.text.rest=address:\n{0} \nhas private key:\n{1}\n\n\ + The private key has also been copied to the clipboard. +table.address.option.pane.title=Private key information +table.address.option.pane.error.text=Error in obtaining private key: \n {0} \n\n +table.address.option.pane.error.title=Error in obtaining private key! +table.address.show.in.explorer=Show in block explorer +table.address.show.in.explorer.zaddress.message=The address:\n\ +{0}\n\ +is a Z (private) address. Its transactions and balance are not openly viewable on the blockchain. +table.address.show.in.explorer.zaddress.title=Z address is not viewable + +backup.tracker.option.pane.text=It appears that you have not backed up your wallet recently. It is recommended to\n\ + back up the wallet after every 50 outgoing transactions and after creating a new\n\ + Z address. The wallet needs to be backed up to a safe location that can survive any\n\ + data loss on the PC where the wallet is currently located. Not backing up the wallet\n\ + may result in loss of funds in case of data loss on the current PC. To back up the\n\ + wallet, use menu option: Wallet >> Backup\n\n +backup.tracker.option.pane.title=Wallet backup is recommended... + +panel.dashboard.main.label=\u0020Horizen Wallet\u0020 +panel.dashboard.transactions.label=Latest transactions: +panel.dashboard.deamon.status.text=zend status: {0} \ + runtimeInfo {1}
Wallet: {2} {3}
\ +
\ + Installation: {4}, \ + Blockchain: {5}
System: {6}
+panel.dashboard.deamon.status.running=RUNNING +panel.dashboard.deamon.status.not.running=NOT RUNNING +panel.dashboard.network.blockchain.label=Blockchain synchronized: \ + {0}%
Up to: \ + {1}


\ + Network peers: {2} connections\u0020\u0020 + +panel.dashboard.deamon.info.virtual=, Virtual: {0} MB +panel.dashboard.deamon.info.cpu=, CPU: {0} % +panel.dashboard.transactions.info=Type: {0}\u0020Direction: {1},  \ + Confirmed: {2}
Amount: {3} ZEN,  \ + Date: {4}
Destination: {5}
+panel.dashboard.transactions.in=IN +panel.dashboard.transactions.out=OUT +panel.dashboard.transactions.private=PrivatE +panel.dashboard.marketcap.column.exchange.info=Exchange Information +panel.dashboard.marketcap.column.exchange.value=Values +panel.dashboard.marketcap.price.usd=Current price in USD: +panel.dashboard.marketcap.price.btc=Current price in BTC: +panel.dashboard.marketcap.capitalisation=ZEN capitalization (USD): +panel.dashboard.marketcap.daily.change=Daily change (USD price): +panel.dashboard.marketcap.weekly.change=Weekly change (USD price): +panel.dashboard.marketcap.usd.balance.string=
\ +              \ + {1} USD +panel.dashboard.marketcap.usd.balance.text=Balance:
\ +
\ + Transparent: {1} ZEN
\ + Private (Z): {3} ZEN
\ +
Total (Z+T): {5} ZEN \ + {6}
+ +panel.dashboard.synchronisation.warning= \ + WARNING: The blockchain is not 100% synchronized. The visible
\ + transactions and wallet balance reflect an old state of the
\ + wallet as of {0} !
+panel.dashboard.tooltip=Powered by Horizen + +panel.dashboard.deamon.status.walletencrypted.text=({0}) +panel.dashboard.deamon.status.encrypted=encrypted +panel.dashboard.deamon.status.not=not\u0020 +panel.dashboard.deamon.runtime.info=Resident: {0} MB {1} {2} +panel.dashboard.balance.tooltip=Unconfirmed (unspendable) balance is being shown due to an
\ + ongoing transaction! Actual confirmed (spendable) balance is:
\ +
Transparent: {0} ZEN
\ + Private ( Z ): {1} ZEN
\ + Total ( ZT ): {2} ZEN +panel.dashboard.table.transactions.confirmed.yes=Yes\u0020 +panel.dashboard.table.transactions.confirmed.no=No\u0020 + +data.table.option.pane.export.error.text=An unexpected error occurred when exporting data to CSV file.\n \n {0} +data.table.option.pane.export.error.title=Error in CSV export +data.table.option.pane.export.success.text=The data has been exported successfully as CSV to location: {0} +data.table.option.pane.export.success.title=Export successful... +data.table.file.chooser.export.dialog.title=Export data to CSV file... +data.table.menu.item.export=Export data to CSV... +data.table.menu.item.copy=Copy value + +dialog.password.title=Password... +dialog.password.temp.panel.upper.label.text=The wallet is encrypted and protected with a password. \ + Please enter the password to unlock it temporarily during \ + the operation +dialog.password.temp.panel.password.label.text=Password:\u0020 +dialog.password.temp.panel.lower.label.text= \ + WARNING: Never enter your password on a public/shared \ + computer or one that you suspect has been infected with malware! \ + +dialog.password.buton.ok.text=OK +dialog.password.buton.cancel.text=Cancel +dialog.password.option.pane.process.text=The password is empty. Please enter it into the text field. +dialog.password.option.pane.process.title=Empty... +dialog.password.encryption.upper.label.text=The wallet.dat file will be encrypted with a password. If the operation is successful, \ + zend will automatically stop and will need to be restarted. The GUI wallet will also be stopped \ + and will need to be restarted. Please enter the password: +dialog.password.encryption.confirmation.label.text=Confirmation:\u0020 +dialog.password.encryption.option.pane.mismatch.text=The password and the confirmation do not match! +dialog.password.encryption.option.pane.mismatch.title=Password mismatch... + +proving.key.fetcher.option.pane.message=The Horizen wallet cannot proceed without keys. +proving.key.fetcher.option.pane.verify.message=The wallet needs to download the Z cryptographic proving key (approx. 900 MB) and Sprout Groth parameter (700MB) and Sapling Spend parameter (50MB).\n\ + This will be done only once. Please be patient... Press OK to continue +proving.key.fetcher.option.pane.verify.progress.text=Downloading Sapling and Sprout parameters... +proving.key.fetcher.option.pane.verify.progress.monitor.text=Downloading proving key +proving.key.fetcher.option.pane.verify.key.text=Verifying downloaded proving key... +proving.key.fetcher.option.pane.verify.key.failed.text=Failed to download proving key properly. Cannot continue! +sprout.groth.fetcher.option.pane.verify.progress.monitor.text=Downloading Sprout Groth parameter +sprout.groth.fetcher.option.pane.verify.key.text=Verifying downloaded Sprout Groth parameter... +sprout.groth.fetcher.option.pane.verify.key.failed.text=Failed to download Sprout Groth parameter properly. Cannot continue! +sapling.spend.fetcher.option.pane.verify.progress.monitor.text=Downloading Sapling Spend parameter +sapling.spend.fetcher.option.pane.verify.key.text=Verifying downloaded Sapling Spend parameter... +sapling.spend.fetcher.option.pane.verify.key.failed.text=Failed to download Sapling Spend parameter properly. Cannot continue! + +send.cash.panel.label=Send cash from:\u0020\u0020\u0020\u0020\u0020\u0020\u0020 +send.cash.panel.label.info= \ + * Only addresses with a confirmed balance are shown as sources for sending! +send.cash.panel.label.destination.address=Destination address: +send.cash.panel.label.memo=Memo (optional):\u0020\u0020\u0020\u0020\u0020 +send.cash.panel.label.memo.info= \ + * Memo may be specified only if the destination is a Z (Private) address! +send.cash.panel.label.amount=Amount to send: +send.cash.panel.label.fee=Transaction fee: +send.cash.panel.button.send=Send +send.cash.panel.label.send.warning= \ + * When sending cash from a T (Transparent) address, the remaining unspent balance is sent to another \ + auto-generated T address. When sending from a Z (Private) address, the remaining unspent balance remains with \ + the Z address. In both cases the original sending address cannot be used for sending again until the \ + transaction is confirmed. The address is temporarily removed from the list! Freshly mined coins may only \ + be sent to a Z (Private) address. \ + +send.cash.panel.label.last.operation.status=Last operation status:\u0020 +send.cash.panel.label.last.operation.progress=Progress:\u0020 +send.cash.panel.option.pane.error.text=An unexpected error occurred when sending cash!\n \ + Please ensure that the Horizen daemon is running and\n \ + parameters are correct. You may try again later...\n {0} +send.cash.panel.option.pane.error.title=Error in sending cash +send.cash.panel.menu.item.paste=Paste address +send.cash.panel.option.pane.no.funds.text=There are no addresses with a positive balance to send\n cash from! +send.cash.panel.option.pane.no.funds.title=No funds available +send.cash.panel.option.pane.select.source.text=Please select a source address with a current positive\n balance to send cash from! +send.cash.panel.option.pane.select.source.title=Please select source address +send.cash.panel.option.pane.error.source.address.invalid=Source address is invalid; it is too short or missing. +send.cash.panel.option.pane.error.source.address.too.long=Source address is invalid; it is too long. +send.cash.panel.option.pane.error.destination.address.invalid=Destination address is invalid; it is missing. +send.cash.panel.option.pane.error.destination.address.too.short=Destination address is invalid; it is too short. +send.cash.panel.option.pane.error.destination.address.too.long=Destination address is invalid; it is too long. +send.cash.panel.option.pane.error.destination.address.has.spaces=Destination address is invalid; it has leading or trailing white-space characters. +send.cash.panel.option.pane.error.destination.address.incorrect.text=The destination address to send ZEN to: \n {0} \n\ + does not appear to be a valid ZEN address. ZEN addresses start with zc, zn or zs! +send.cash.panel.option.pane.error.destination.address.incorrect.title=Destination address is incorrect... +send.cash.panel.option.pane.error.destination.address.notz.text=The destination address to send ZEN to: \n {0} \n\ + does not appear to be a Z address. However a text memo is specified to be sent. A text memo may\nbe included in a \ + transaction only if the destination is a Z address. Are you sure you want to proceed? +send.cash.panel.option.pane.error.destination.address.notz.title=Destination address is not a Z address... +send.cash.panel.option.pane.confirm.operation.text=Please confirm that you wish to send {0} ZEN, from address:\n\ + {1}\n\ + to address:\n\ + {2}\n\ + with transaction fee: {3} ZEN +send.cash.panel.option.pane.confirm.operation.text.with.memo=Please confirm that you wish to send {0} ZEN, from address:\n\ + {1}\n\ + to address:\n\ + {2}\n\ + with transaction fee: {3} ZEN, and text memo:\n\ + {4}\n +send.cash.panel.option.pane.confirm.operation.title=Confirm sending cash... +send.cash.panel.option.pane.confirm.operation.button.yes=Yes (I confirm) +send.cash.panel.option.pane.confirm.operation.button.no=No +send.cash.panel.option.pane.confirm.operation.button.not.again=Yes, do not show this message again +send.cash.panel.option.pane.error.destination.amount.fractional.digits=The amount to send specified: {0} has more than 8 fractional decimal digits.\n\ +It cannot be accurately represented in a ZEN transaction and will be rounded off. The actual amount\n\ +sent will thus differ from what is specified. Are you sure you want to proceed? +send.cash.panel.option.pane.error.destination.fee.fractional.digits=The transaction fee to send specified: {0} has more than 8 fractional decimal digits.\n\ +It cannot be accurately represented in a ZEN transaction and will be rounded off. The actual amount\n\ +sent will thus differ from what is specified. Are you sure you want to proceed? +send.cash.panel.option.pane.error.destination.fractional.digits.title=Fractional part exceeds allowed range +send.cash.panel.option.pane.error.amount.invalid=Amount to send is invalid; it is missing. +send.cash.panel.option.pane.error.amount.not.number=Amount to send is invalid; it is not a number. +send.cash.panel.option.pane.error.amount.negative=Amount to send is invalid; it is negative. +send.cash.panel.option.pane.error.fee.invalid=Transaction fee is invalid; it is missing. +send.cash.panel.option.pane.error.fee.not.number=Transaction fee is invalid; it is not a number. +send.cash.panel.option.pane.error.fee.negative=Transaction fee is invalid; it is negative. +send.cash.panel.option.pane.error.incorrect.sending.parameters=Sending parameters are incorrect +send.cash.panel.operation.status.progress.label=IN PROGRESS +send.cash.panel.operation.status.success.label=SUCCESSFUL +send.cash.panel.operation.complete.report=OK:Copy transaction ID:View on the blockchain +send.cash.panel.operation.complete.report.success.text=Successfully sent {0} ZEN from address: \n{1}\nto address: \n{2}\n\nTransaction ID: {3} +send.cash.panel.operation.complete.report.success.title=Cash sent successfully +send.cash.panel.operation.status.error.label=ERROR: {0} +send.cash.panel.option.pane.error.report.text=An error occurred when sending cash. Error message is:\n {0}\n\n \ + Please ensure that sending parameters are correct. You may try again later...\n +send.cash.panel.option.pane.error.report.title=Error in sending cash +send.cash.panel.checkbox.send.change.back=Send remaining balance back to source address (explicitly) +send.cash.panel.insufficient.balance=The address: {0}\n\ +has a confirmed balance of {1} ZEN that is not sufficient to cover\n\ +the amount to send {2} ZEN and the transaction fee: {3} ZEN! +send.cash.panel.insufficient.balance.title=Insufficient balance available +send.cash.panel.send.change.back.general.warning=\ +The option has been set to send the remaining balance (change) after the send\n\ +operation back to the source address. This can only work correctly if the source\n\ +address has no pending/unconfirmed balance and the blockchain is currently fully\n\ +synchronized. Otherwise the change to send back may not be calculated correctly.\n\ +Are you sure you want to proceed? +send.cash.panel.send.change.back.general.warning.title=Confirm sending back change... + +single.key.import.dialog.title=Enter private key... +single.key.import.dialog.tmp.panel=Please enter a single private key to import. +single.key.import.dialog.tmp.panel.key.label=Key: +single.key.import.dialog.tmp.panel.key.lower.label= Warning: \ + Private key import is a slow operation that \ + requires blockchain rescanning (may take many minutes).
The GUI \ + will not be usable for other functions during this time +single.key.import.dialog.tmp.panel.ok.button.text=Import +single.key.import.dialog.tmp.panel.cancel.button.text=Cancel +single.key.import.dialog.tmp.panel.process.ok.message=The key is empty. Please enter it into the text field. +single.key.import.dialog.tmp.panel.process.ok.title=Empty... +single.key.import.dialog.tmp.panel.process.ok.addition= It corresponds to address:\ {0} +single.key.import.dialog.tmp.panel.success.message=The private key: {0} \n has been imported successfully. {1} +single.key.import.dialog.tmp.panel.success.title=Private key imported successfully... +single.key.import.dialog.tmp.panel.error.message=An error occurred when importing private key. Error message is: \n\ + {0} :\n {1} \n\n\ + Please ensure that zend is running and the key is in the correct \n\ + form. You may try again later...\n +single.key.import.dialog.tmp.panel.error.title=Error in importing private key + +startup.progress.dialog.label=Horizen Wallet +startup.progress.dialog.progressbar.label=Starting... + +status.update.error.reporter.panel.message=An unexpected error occurred during the operation of the GUI wallet.\n\ + Details may be found in the log in directory: {0} \n\n {1} +status.update.error.reporter.panel.title=Error in wallet operation. + +transactions.detail.panel.yes=Yes {0} +transactions.detail.panel.no=No\u0020\u0020{0} +transactions.detail.panel.column.names=Type:Direction:Confirmed?:Amount:Date:Destination Address + +transactions.table.show.in.explorer=Show in block explorer +transactions.table.memo.field=Get transaction memo +transactions.table.memo.unavailable.text=The selected transaction does not have as destination a Z (private) \n\ + address or it is unknown (not listed) and thus no memo information \n\ + about this transaction is available. +transactions.table.memo.unavailable.title=Memo information is unavailable +transactions.table.memo.clipboard.text=The memo contained in the transaction is: \n{0}\n\n\ + (The memo has also been copied to the clipboard.) +transactions.table.memo.clipboard.title=Memo +transactions.table.memo.field.missing.text=The selected transaction does not contain a memo field. +transactions.table.memo.field.missing.title=Memo field is not available... +transaction.table.details.dialog.title=Transaction details... +transaction.table.details.dialog.info.label= \ + The table shows the information about the transaction with technical details as \ + they appear at Horizen network level. +transaction.table.details.dialog.column.names=Name:Value +transaction.table.details.dialog.button.close=Close + +wallet.operations.option.pane.already.encrypted.error.text=The wallet.dat file being used is already encrypted. \ + This \noperation may be performed only on a wallet that \ + is not\nyet encrypted! +wallet.operations.option.pane.already.encrypted.error.title=Wallet is already encrypted... +wallet.operations.option.pane.encryption.error.text=An unexpected error occurred while encrypting the wallet!\n \ + It is recommended to stop and restart both zend and the GUI wallet! \n \n {0} +wallet.operations.option.pane.encryption.error.title=Error in encrypting wallet... +wallet.operations.option.pane.encryption.success.text=The wallet has been encrypted successfully and zend has stopped.\n\ + The GUI wallet will be stopped as well. Please restart both. In\n \ + addition the internal wallet keypool has been flushed. You need\n to make a new backup...\n +wallet.operations.option.pane.encryption.success.title=Wallet is now encrypted... +wallet.operations.dialog.backup.wallet.title=Backup wallet to file... +wallet.operations.option.pane.backup.wallet.error.text=An unexpected error occurred while backing up the wallet!\n{0}\n +wallet.operations.option.pane.backup.wallet.error.title=Error in backing up wallet... +wallet.operations.option.pane.backup.wallet.success.text=The wallet has been backed up successfully to file: {0} \n\ + in the backup directory provided to zend (-exportdir=).\nFull path is: {1} +wallet.operations.option.pane.backup.wallet.success.title=Wallet is backed up... +wallet.operations.dialog.export.private.keys.title=Export wallet private keys to file... +wallet.operations.dialog.export.private.keys.error.text=An unexpected error occurred while exporting wallet private keys! \n {0} +wallet.operations.dialog.export.private.keys.error.title=Error in exporting wallet private keys... +wallet.operations.dialog.export.private.keys.success.text=The wallet private keys have been exported successfully to file:\n {0} \ + \n in the backup directory provided to zend (-exportdir=).\nFull path is: \ + {1} \n You need to protect this file from unauthorized access. Anyone who\n has access to the private keys \ + can spend the Horizen balance! +wallet.operations.dialog.export.private.keys.success.title=Wallet private key export... +wallet.operations.dialog.import.private.keys.notice.text=Private key import is a potentially slow operation. It may take\n\ + several minutes during which the GUI will be non-responsive.\n\ + The data to import must be in the format used by the option:\n\ + \"Export private keys...\"\n\n\ + Are you sure you wish to import private keys? +wallet.operations.dialog.import.private.keys.notice.title=Private key import notice... +wallet.operations.file.chooser.import.private.keys.title=Import wallet private keys from file... +wallet.operations.dialog.import.private.keys.error.text=An unexpected error occurred while importing wallet private keys! \n {0} +wallet.operations.dialog.import.private.keys.error.title=Error in importing wallet private keys... +wallet.operations.dialog.import.private.keys.success.text=Wallet private keys have been imported successfully from location:\n {0} \n\n +wallet.operations.dialog.import.private.keys.success.title=Wallet private key import... +wallet.operations.option.pane.own.address.view.private.key.text=Please select an address in the \"Own addresses\" tab to view its private key +wallet.operations.option.pane.own.address.view.private.key.title=Please select an address... +wallet.operations.option.pane.address.table.view.private.key.text=Please select an address in the \"Own addresses\" tab to view its private key +wallet.operations.option.pane.address.table.view.private.key.title=Please select an address... +wallet.operations.private.address=Z (Private) +wallet.operations.transparent.address=T (Transparent) +wallet.operations.option.pane.address.information.text={0} address:\n{1}\nhas private key:\n{2} \n\n\ + The private key has also been copied to the clipboard. +wallet.operations.option.pane.address.information.title=Private key information +wallet.operations.dialog.export.arizen.title=Exporting Arizen wallet +wallet.operations.dialog.export.arizen.filechooser.filter=Arizen wallet file +wallet.operations.dialog.export.arizen.filechooser.title=Export wallet to Arizen wallet unencrypted format... +wallet.operations.dialog.export.arizen.filechooser.aprove.button=Export +wallet.operations.dialog.delete.file.confirmation=The file {0} already exists. Do you want to proceed and overwrite it? +wallet.operations.dialog.delete.file.confirmation.title=Alert +wallet.operations.dialog.export.label=Exporting wallet... +wallet.operations.dialog.export.progress.reading.text=Reading addresses and private keys... +wallet.operations.dialog.export.progress.writing.text=Writing addresses and private keys... +wallet.operations.dialog.export.progress.finished.text=Wallet exported +wallet.operations.option.pane.export.success.info.text=The Arizen wallet is exported to: {0}\nUsing Arizen to import select: Import UNENCRYPTED Arizen wallet.\n\ + The wallet will be imported and encrypted +wallet.operations.option.pane.export.success.info.title=Export Arizen wallet +wallet.operations.option.pane.backup.directory.warning.text=For security reasons the wallet may be backed up/private keys exported only if\n\ + the zend parameter -exportdir= has been set. If you started zend \n\ + manually, you ought to have provided this parameter. When zend is started \n\ + automatically by the GUI wallet the directory provided as parameter to -exportdir\n\ + is the user home directory: {0}\n\n\ + Please navigate to the directory provided as -exportdir= and select a\n\ + filename in it to backup/export private keys. If you select another directory\n\ + instead, the destination file will still end up in the directory provided as \n\ + -exportdir=. If this parameter was not provided to zend, the process\n\ + will fail with a security check error. The filename needs to consist of only\n\ + alphanumeric characters (e.g. dot is not allowed).\n +wallet.operations.option.pane.backup.directory.warning.title=Wallet backup directory information +wallet.operations.option.pane.backup.directory.warning.message=Do not show this again +wallet.operations.option.pane.backup.directory.warning.message.ok=OK + +# Options pertaining to editing Zend command line parameters +wallet.menu.edit.zend.params=Edit zend parameters... +wallet.operations.zend.parameters.warning.title=Warning +wallet.operations.zend.parameters.warning.text=The zend node is automatically started by the wallet. Editing the parameters used to\n\ + start zend should be done with care - typically by experienced users only. Any incorrect\n\ + setting of these parameters may prevent the wallet from starting properly!\n\ + \n\ + In case of emergencies, the parameters may also be edited using a text editor\n\ + in configuration file:\n\ + {0}\n +wallet.operations.zend.parameters.warning.notagain=Do not show this again +wallet.operations.zend.parameters.warning.oklabel=OK + +zend.cmd.params.dialog.title=Edit zend command line parameters... +zend.cmd.params.dialog.info=\ + The parameters below are used to start zend when the GUI wallet is started. The required format when editing them
\ + is to have one parameter on a single text line. For more information on the possible parameters that may be set, one
\ + may check the \ + \ + zend documentation. Any changes made here will only take effect on the next restart of the \ + wallet.
\ +
+zend.cmd.params.dialog.close.button=Close +zend.cmd.params.dialog.save.button=Save & close +zend.cmd.params.dialog.double.option.warning.text=It appears that the following line has more than one zend parameter on it:\n\n\ + {0}\n\n\ + Please note that only one zend parameter may be specified per line, or\n\ + else the parameters may not be passed correctly!\n\n\ + Are you sure you wish to save the parameters to the configuration file? +zend.cmd.params.dialog.double.option.warning.title=Multiple parameters found on one line! +zend.cmd.params.dialog.success.text=The modified parameters for starting zend have been successfully saved in configuration file:\n\ + {0}\n\ + The parameters will take effect on the next start of the GUI wallet. +zend.cmd.params.dialog.success.title=Parameters saved successfully diff --git a/src/resources/messages/zencash_it.properties b/src/resources/messages/zencash_it.properties new file mode 100644 index 00000000..990bbfad --- /dev/null +++ b/src/resources/messages/zencash_it.properties @@ -0,0 +1,548 @@ +main.frame.title=Horizen Desktop GUI Wallet 1.0.12 +main.frame.progressbar=Avviando la GUI... +main.frame.title.testnet=\u0020[usando TESTNET] +main.frame.tab.overview.title=Anteprima\u0020 +main.frame.tab.transactions.title=Transazioni\u0020 +main.frame.tab.own.address.title=Indirizzi propri\u0020 +main.frame.tab.send.cash.title=Invia denaro\u0020 +main.frame.tab.address.book.title=Rubrica\u0020 +main.frame.tab.messaging.title=Messaggi\u0020 +main.frame.disclaimer.text=Il ZENCash GUI Wallet � attualmente considerato esperimentale.\n\ + Uttilizzate questo software al proprio risico! Accertarsi di leggere la lista dei \n\ + problemi e delle limitazioni conosciute su questa pagina: \n\ + https://github.com/HorizenOfficial/zencash-swing-wallet-ui\n\n\ + Il ZENCash Desktop GUI Wallet non � compattibile con applicazioni che modificano\n\ + il file wallet.dat. Il wallet non dovrebbe essere usato con queste applicazioni\n\ + nello stesso PC. Si s� per esempio che certe applicazioni di scambio distribuite\n\ + creano indirizzi di sola lettura nel file wallet.dat che fanno che il GUI wallet\n\ + visualizzi un saldo sbagliato e/o visualizzi indirizzi che non appartengono al wallet.\n\n\ + Criptare wallet.dat file non � ancora suportato dal ZENCash. Uttilizare il wallet\n\ + in un sistema infetto puo risultare nella perdita dei fondi/dati.\n\ + � fortemente consigliato di fare regolarmente una backup della wallet.dat \n\ + (non solo una volta - e.g. dopo 30-40 transazioni in uscita) ma anche dopo la creazione \ + di un indirizzo Z(Privato) nuovo.\n\n\ + IL SOFTWARE VIENE FORNITO "COS� COM'�", SENZA GARANZIE DI ALCUN TIPO,\n \ + ESPLICITE O IMPLICITE, IVI INCLUSE, IN VIA ESEMPLIFICATIVA,\n \ + LE GARANZIE DI COMMERCIABILIT�, IDONEIT� A UN FINE PARTICOLARE E NON VIOLAZIONE DEI\n \ + DIRITTI ALTRUI. IN NESSUN CASO GLI AUTORI O I TITOLARI DEL COPYRIGHT SARANNO\n \ + RESPONSABILI PER QUALSIASI RECLAMO, DANNO O ALTRO TIPO DI RESPONSABILIT�,\n \ + A SEGUITO DI AZIONE CONTRATTUALE, ILLECITO O ALTRO, DERIVANTE DA O IN CONNESSIONE AL\n \ + SOFTWARE, AL SUO UTILIZZO O AD ALTRE OPERAZIONI CON LO STESSO.\n\n\ + (Questo messaggio verr� visualizzato solamente una volta per rilascio) +main.frame.disclaimer.button.agree=Accetto +main.frame.disclaimer.button.disagree=Non accetto! >> Uscire +main.frame.disclaimer.title=Dichiarazione di non responsabilit� +main.frame.option.pane.installation.error.text=Questo programma � stato avviato nella cartella: {0} \n {1} \n \ + Guardare l'output della console/logfile per maggori dettagli sul'errore! \ +main.frame.option.pane.installation.error.title=Errore d'installazione +main.frame.option.pane.wallet.communication.error.text=Sembra che Zend sia stato avviato ma non ancora\n \ + pronto per accettare connessioni. Sta ancora caricando la wallet de il blockchain. Provare per favore \n \ + di avviare la GUI wallet pi� tardi... +main.frame.option.pane.wallet.communication.error.title=Errore di communicazione +main.frame.option.pane.wallet.communication.error.2.text=� successo un errore di communicazione con ZENCash daemon/wallet. \n \ + Assicurarsi per favore che ZENCash server zend sia stato avviato (e.g. via \n \ + command \"zend --daemon\"). Messaggio di errore: \n {0} \ + Guardare l'output della console/logfile per maggori dettagli sul'errore! +main.frame.option.pane.wallet.communication.error.2.title=Errore di communicazione +main.frame.option.pane.wallet.critical.error.text=� successo un errore generico inaspettato: \n {0} \n \ + Guardare l'output della console/logfile per maggori dettagli sul'errore! +main.frame.option.pane.wallet.critical.error.title=Errore +main.frame.option.pane.wallet.critical.error.2.text=� successo un errore generico inaspettato:: \n {0} \n \ + Guardare l'output della console/logfile per maggori dettagli sul'errore! +main.frame.option.pane.wallet.critical.error.2.title=Errore + + + +menu.label.main=Principale +menu.label.wallet=Wallet +menu.label.messaging=Messaggi +menu.label.about=About... +menu.label.quit=Chiudere... +menu.label.backup=Backup... +menu.label.encrypt=Cifrare... +menu.label.export.private.keys=Esportare chiavi private... +menu.label.import.private.keys=Importare chiavi private... +menu.label.show.private.key=Mostrare chiavi private... +menu.label.import.one.private.key=Importare una chiave privata... +menu.label.export.to.arizen=Esportare ad Arizen wallet... +menu.label.own.identity=Identit� propria... +menu.label.export.own.identity=Esportare Identit� propria... +menu.label.add.messaging.group=Aggiungere gruppo di messaggistica... +menu.label.import.contact.identity=Importare contatto... +menu.label.remove.contact=Rimuovere contatto... +menu.label.options=Opzioni... +menu.label.share.file=Condividere file via: +menu.label.ipfs=IPFS + + +menu.label.language=Lingua +menu.label.language.italian=Italiano +menu.label.language.german=Tedesco +menu.label.language.english=Inglese + + + +dialog.identity.info.title=Dettagli contatto per {0} + +dialog.message.language.prefs.update.title=Informazione +dialog.message.language.prefs.update=La vostra preferenza � stata salvata, sar� attiva la prossima volta che avviate l'applicazione! + +dialog.about.title=About... +dialog.about.tab.title=About +dialog.about.licence=
\
+             \u0020Copyright (c) 2023 Horizen Foundation \n \
+		     Copyright (c) 2016-2021 Zen Blockchain Foundation \n \
+			 \n \
+			 Con la presente si concede, a chiunque ottenga una copia di questo software\n \
+             e dei file di documentazione associati (il "Software"), l'autorizzazione\n \
+             a usare gratuitamente il Software senza alcuna limitazione, compresi i diritti di usare,\n \
+             copiare, modificare, unire, pubblicare, distribuire, cedere in sottolicenza e/o vendere\n \
+             copie del Software, nonch� di permettere ai soggetti cui il Software � fornito\n \
+             di fare altrettanto, alle seguenti condizioni:\n \
+             L'avviso di copyright indicato sopra e questo avviso di autorizzazione devono essere\n\
+             inclusi in ogni copia o parte sostanziale del Software.\n \
+             IL SOFTWARE VIENE FORNITO "COS� COM'�", SENZA GARANZIE DI ALCUN TIPO,\n \
+             ESPLICITE O IMPLICITE, IVI INCLUSE, IN VIA ESEMPLIFICATIVA,\n \
+             LE GARANZIE DI COMMERCIABILIT�, IDONEIT� A UN FINE PARTICOLARE E NON VIOLAZIONE DEI\n \
+             DIRITTI ALTRUI. IN NESSUN CASO GLI AUTORI O I TITOLARI DEL COPYRIGHT SARANNO\n \
+             RESPONSABILI PER QUALSIASI RECLAMO, DANNO O ALTRO TIPO DI RESPONSABILIT�,\n \
+             A SEGUITO DI AZIONE CONTRATTUALE, ILLECITO O ALTRO, DERIVANTE DA O IN CONNESSIONE AL\n \
+             SOFTWARE, AL SUO UTILIZZO O AD ALTRE OPERAZIONI CON LO STESSO.		\n \
+			
+dialog.about.front.text=ZENCash Swing Wallet UI\ +

Copyright (c) 2023 The Horizen Foundation

\ +

Copyright (c) 2016-2021 Zen Blockchain Foundation

Questo programma \ + intende semplificare il lavoro con il cliente ZENCash mettendo a disposizione
\ + un Interfacia Grafica Utente (GUI) che aggisce da wrapper e visualizza le informazioni \ +
in una maniera user-friendly.

Riconoscimenti: Questo programma contiene software per \ + manipolazione JSON
(https://github.com/ralfstx/minimal-json) Copyright (c) 2015, \ + 2016 EclipseSource.
Librerie addizionali sono BitcoinJ (https://bitcoinj.github.io/) \ + e SQLite JDBC
(https://github.com/xerial/sqlite-jdbc) entrambe sotto licenza Apache \ + Versione 2.0.
contiene imagini/artwork dal progetto Bitcoin \ + (https://github.com/bitcoin/bitcoin).

+ +dialog.about.tab.title.licence=Licenza +dialog.about.button.close.text=Chiudere + + +panel.address.book.new.contact.button.text=Nuovo Contatto... +panel.address.book.send.zen.button.text=Inviare ZEN +panel.address.book.copy.clipboard.button.text=Copiare indirizzo negli appunti +panel.address.book.delete.contact.button.text=Cancellare contatto +panel.address.book.error.corrupted=La rubrica � corrotta! +panel.address.book.option.pane.new.contact.msg=Inserire il nome del contatto per favore: +panel.address.book.option.pane.new.contact.title=Aggiungere nuovo contatto passo 1 +panel.address.book.option.pane.new.contact.address=Inserire per favore il t-indirizzo oppure il z-indirizzo di {0} +panel.address.book.option.pane.new.contact.address.title=Aggiungere nuovo contatto passo 2 +panel.address.book.menuitem.sendcash.text=Inviare ZEN a {0} +panel.address.book.menuitem.copy.address.text=Copiare indirizzo negli appunti +panel.address.book.menuitem.delete.entry.text=Cancellare {0} dai contatti +panel.address.book.button.sendcash.text=Inviare ZEN a {0} +panel.address.book.button.delete.contact.text=Cancellare contatto {0} +panel.address.book.table.name=nome +panel.address.book.table.address=indirizzo + + +panel.address.button.new.address=Nuovo indirizzo T (Transparente) +panel.address.button.new.z.address=Nuovo indirizzo Z (Privato) +panel.address.button.refresh=Aggiornare +panel.address.label.warning= \ + * Se il saldo dell'indirizzo � contrasegnato come non confermato, l'indirizzo sta partecipando \ + in una transazione. The shown balance then is the expected value it will have when \ + in una transazione. Il saldo mostrato � il valore che avvr� una volta la transazione \ + sar� confermata. \ + Il tempo medio di attesa � di circa 2.5 min. \ + +panel.address.message.backup=\n\n� neccessario fare un backup della wallet dopo aver creato un nuovo indirizzo Z. Il backup bisogna\n\ + salvarlo in un posto sicuro dove potr� sopravire una perdita di dati del PC dove si trova il wallet.\n\ + I'assenza di un backup pu� risultare in perdita di fondi in caso di perdita di dati del PC corrente.\n\ + Per fare un backup, usare l'opzione: Wallet >> Backup\n +panel.address.option.pane.text=Un indirizzo nuovo {0} � stato creato con successo!:\n\ + {1} {2} +panel.address.option.pane.title=Indirizzo creato. +panel.address.table.create.address.header=Etichetta:Saldo:Confermato?:Indirizzo +panel.address.option.pane.validation.error.text=Esiste un indirizzo non valido o di sola lettura nel wallet: \n \ + {0} \n\n \ + Il software non pu� funzionare correttamente con indirizzi non validi oppure di sola lettura.\n \ + Non uttilizare questi ultimi come indirizzi di destinazione per operazioni di pagamento!\n +panel.address.option.pane.validation.error.title=Errore: � presente un indirizzo non valido o di sola lettura nel wallet! +panel.address.option.pane.yes=Si\u0020{0} +panel.address.option.pane.no=No\u0020\u0020{0} +panel.address.label.input.text=Inserisca per favore un ettichetta per l'indirizzo appena creato: +panel.address.label.input.title=Ettichetta dell'indirizzo... +table.address.option.obtain.private.key.label=Ottenere una chiave privata... +table.address.option.pane.text.private=Z (Privato) +table.address.option.pane.text.transparent=T (Transparente) +table.address.option.pane.text.rest=indirizzo:\n {0} \nha come chiave privata:\n {1} \n\n\ + La chiave privata � stata copiata anche negli appunti. +table.address.option.pane.title=Informazione sulla chiave privata +table.address.option.pane.error.text=Errore creando chiave privata: \n {0} \n\n +table.address.option.pane.error.title=Errore creando chiave privata! +table.address.show.in.explorer=Mostrare nel block explorer +table.address.show.in.explorer.zaddress.message=L'indirizzo:\n\ + {0} \n\ + � un indirizzo Z (privato). Il suo saldo e le transazioni non sono publicamente visibili nel blockchain. +table.address.show.in.explorer.zaddress.title=Z indirizzi non sono visibili + +backup.tracker.option.pane.text=Sembra che lei non abbia fatto recentemente un backup del wallet. � consigliato\n\ + fare una backup ogni 50 transazioni in uscita e dopo aver creato un indirizzo nuovo Z.\n\ + L'assenza di un backup pu� risultare in perdita di fondi in caso di perdita di dati del PC corrente.\n\ + Per fare un backup, usare l'opzione: Wallet >> Backup\n\n +backup.tracker.option.pane.title=E consigliato fare un backup del wallet... + +panel.dashboard.main.label=\u0020ZENCash Wallet\u0020 +panel.dashboard.transactions.label=Ultime transazioni: +panel.dashboard.deamon.status.text=zend stato: {0} \ + Info tempo di esecuzione {1}
Wallet: {2} {3}
\ +
\ + Installazione: {4} , \ + Blockchain: {5}
System: {6}
+panel.dashboard.deamon.status.running=AVVIATO +panel.dashboard.deamon.status.not.running=NOT AVVIATO +panel.dashboard.network.blockchain.label=Blockchain sincronizzato: \ + {0}%
Fino a: \ + {1}


\ + Peer di rete: {2} connessioni\u0020\u0020 + +panel.dashboard.deamon.info.virtual=, Virtuali: {0} MB +panel.dashboard.deamon.info.cpu=, CPU: {0} % +panel.dashboard.transactions.info=Tipo: {0} \u0020Direzione: {1},  \ + Confermato: {2}
Valore: {3} ZEN,  \ + Data: {4}
Destinazione: {5}
+panel.dashboard.transactions.in=IN +panel.dashboard.transactions.out=OUT +panel.dashboard.transactions.private=Privata +panel.dashboard.marketcap.column.exchange.info=Informazioni sullo Scambio +panel.dashboard.marketcap.column.exchange.value=Valori +panel.dashboard.marketcap.price.usd=Prezzo corrente in USD: +panel.dashboard.marketcap.price.btc=Prezzo corrente in BTC: +panel.dashboard.marketcap.capitalisation=ZEN capitalizzazione (USD): +panel.dashboard.marketcap.daily.change=Cambio giornaliero (USD): +panel.dashboard.marketcap.weekly.change=Cambio settimanale (USD): +panel.dashboard.marketcap.usd.balance.string=
\ +              \ + {1} USD +panel.dashboard.marketcap.usd.balance.text=Saldo:
\ +
\ + Transparente:{1} ZEN
\ + Privato (Z) :{3} ZEN
\ +
Totale (Z+T):{5} ZEN \ + {6}
+ +panel.dashboard.synchronisation.warning= \ + ATTENZIONE: iL blockchain non � 100% sinchronizzato. Le transazioni
\ + visibili e il saldo riflettono uno stato che risale al
\ + {0} !
+panel.dashboard.tooltip=Powered by ZENCash + +panel.dashboard.deamon.status.walletencrypted.text=({0}) +panel.dashboard.deamon.status.encrypted=criptata +panel.dashboard.deamon.status.not=non\u0020 +panel.dashboard.deamon.runtime.info=Residenti: {0} MB {1} {2} +panel.dashboard.balance.tooltip=Saldo non confermato (non spendibile) balance viene visualizzato a causa
\ + di una transazione in corso! Saldo confermato (spendibile) �:
\ +
Transparente: {0} ZEN
\ + Privata ( Z ): {1} ZEN
\ + Totale ( ZT ): {2} ZEN +panel.dashboard.table.transactions.confirmed.yes=Si\u0020 +panel.dashboard.table.transactions.confirmed.no=No\u0020 + +data.table.option.pane.export.error.text=� successo un errore inaspetto durante l'esportazione in CSV\n \n {0} +data.table.option.pane.export.error.title=Errore in esportazione CSV +data.table.option.pane.export.success.text=I dati sono stati esportati con successo nella posizione: {0} +data.table.option.pane.export.success.title=Esportato con successo... +data.table.file.chooser.export.dialog.title=Esportare i dati in un file CSV... +data.table.menu.item.export=Esportare dati in CSV... +data.table.menu.item.copy=Copiare valore + +dialog.password.title=Password... +dialog.password.temp.panel.upper.label.text=IL wallet � criptato e protetto da password. \ + Inserisca per favor la password per sbloccarlo temporaneamente \ + durante l'operazione +dialog.password.temp.panel.password.label.text=Password:\u0020 +dialog.password.temp.panel.lower.label.text= \ + ATTENZIONE: Non inserire mail la password in un compiuter publico/condiviso \ + oppure possibilmente infetto! \ + +dialog.password.buton.ok.text=OK +dialog.password.buton.cancel.text=Anulla +dialog.password.option.pane.process.text=La password � vuota. Inserisca per favore una password. +dialog.password.option.pane.process.title=Vuoto... +dialog.password.encryption.upper.label.text=IL file wallet.dat verra protetto da password. Nel caso l'operazione abbi successo, \ + zend si fermer� automaticamente e sar� necessario riavviarlo. Il GUI wallet verr� anche fermato \ + e sar� necessario riavviarlo. Inserisca per favore una password: +dialog.password.encryption.confirmation.label.text=Confirmation:\u0020 +dialog.password.encryption.option.pane.mismatch.text=La password non coincide con la conferma! +dialog.password.encryption.option.pane.mismatch.title=Password non coincidono... + +proving.key.fetcher.option.pane.message=Il ZENCash wallet non può procedere senza una chiave di verifica. +proving.key.fetcher.option.pane.verify.message=Il wallet necessita scaricare la chiave Z crittografica di verifica (circa. 900 MB) i Sprout Groth crittografica di verifica (700MB) i Sapling Spend (50MB) .\n\ + Questo verra fatto solo una volta. Abbia pazienza per favore... Premere OK per continuare +proving.key.fetcher.option.pane.verify.progress.text=Scaricando la chiave di verifica... +proving.key.fetcher.option.pane.verify.progress.monitor.text=Scaricando la chiave di verifica +proving.key.fetcher.option.pane.verify.key.text=Verificando la chiave di verifica... +proving.key.fetcher.option.pane.verify.key.failed.text=Scaricamento chiave di verifica falito. Non si puo continuare! +sprout.groth.fetcher.option.pane.verify.progress.monitor.text=Downloading Sprout Groth parameter +sprout.groth.fetcher.option.pane.verify.key.text=Verifying downloaded Sprout Groth parameter... +sprout.groth.fetcher.option.pane.verify.key.failed.text=Failed to download Sprout Groth parameter properly. Cannot continue! +sapling.spend.fetcher.option.pane.verify.progress.monitor.text=Downloading Sapling Spend parameter +sapling.spend.fetcher.option.pane.verify.key.text=Verifying downloaded Sapling Spend parameter... +sapling.spend.fetcher.option.pane.verify.key.failed.text=Failed to download Sapling Spend parameter properly. Cannot continue! + +send.cash.panel.label=Inviare denaro da:\u0020\u0020\u0020\u0020\u0020\u0020\u0020 +send.cash.panel.label.info= \ + * Solamente indirizzi con saldo confermato vengono visualizzati come indirizzo sorgente per l'invio! +send.cash.panel.label.destination.address=Indirizzo di destinazione: +send.cash.panel.label.memo=Memo (opzionale):\u0020\u0020\u0020\u0020\u0020 +send.cash.panel.label.memo.info= \ + * Memo puo essere specificato solo per indirizzi Z (Privato)! +send.cash.panel.label.amount=Valore da inviare: +send.cash.panel.label.fee=Tariffa transazione: +send.cash.panel.button.send=Inviare +send.cash.panel.label.send.warning= \ + * Quando si invia denaro da un indirizzo (Transparent), il saldo rimanente viene inviato ad un altro \ + indirizo T auto-generato. Quando si invia denaro da un indirizzo Z (Privato), il saldo rimanente rimane \ + nel indirizzo Z. In entrambi i casi l'indirizzo di partenza non pu� essere usato fino alla conferma della \ + transazione. The address is temporarily removed from the list! Freshly mined coins may only \ + transazione. L'indirizzo viene temporaneamente rimosso dalla lista! Monete appena scavate possono essere mandate \ + solo ad indirizzi Z (Privati). \ + +send.cash.panel.label.last.operation.status=Stato del ultima operazione:\u0020 +send.cash.panel.label.last.operation.progress=Progresso:\u0020 +send.cash.panel.option.pane.error.text=� successo un errore inaspettato durante l'invio di denaro!\n \ + Accertarsi per favore che ZENCash daemon sia avviato e che\n \ + i parametri siano corretti. Potete riprovare pi� tardi...\n {0} +send.cash.panel.option.pane.error.title=Errore inviando denaro +send.cash.panel.menu.item.paste=Incollare l'indirizzo +send.cash.panel.option.pane.no.funds.text=Non ci sono indirizzi con saldo positivo\n da dove si possa inviare denaro! +send.cash.panel.option.pane.no.funds.title=Fondi insufficenti +send.cash.panel.option.pane.select.source.text=Selezionare per favore un indirizzo con saldo positivo per l'invio di denaro! +send.cash.panel.option.pane.select.source.title=Selezionare per favore l'indirizzo sorgente +send.cash.panel.option.pane.error.source.address.invalid=Indirizzo sorgente non valido; � troppo corto o assente. +send.cash.panel.option.pane.error.source.address.too.long=Indirizzo sorgente non valido; troppo lungo. +send.cash.panel.option.pane.error.destination.address.invalid=Indirizzo di destinazione non invalido; vuoto. +send.cash.panel.option.pane.error.destination.address.too.short=Indirizzo di destinazione non invalido; troppo corto. +send.cash.panel.option.pane.error.destination.address.too.long=Indirizzo di destinazione non invalido; troppo lungo. +send.cash.panel.option.pane.error.destination.address.has.spaces=Indirizzo di destinazione non invalido; contiene spazi bianchi iniziali o finali. +send.cash.panel.option.pane.error.destination.address.incorrect.text=L'indirizzo di destinazione: \n {0} \n\ + non sembra di essere un indirizzo ZEN valido. Indirizzi ZEN cominciano per zc, zn ooure zs! +send.cash.panel.option.pane.error.destination.address.incorrect.title=Indirizzo di destinazione non invalido... +send.cash.panel.option.pane.error.destination.address.notz.text=L'indirizzo di destinazione: \n {0} \n\ + non sembra di essere un indirizzo ZEN valido. Comunque � stato specificato un memo per l'invio. Un memo testuale\n\ + essere inclusa nella transazione solo nel caso l'indirizzo di destinazione sia un inirizzo Z \ + Siete sicuri di voler procedere? +send.cash.panel.option.pane.error.destination.address.notz.title=Indirizzo di destinazione non � Z (Privato)... +send.cash.panel.option.pane.confirm.operation.text=Confermare per favore che lei intenda inviare {0} ZEN, dall'indirizzo:\n\ + {1} \n\ + all'indirizzo:\n\ + {2} \n\ + con tariffa di transazione: {3} ZEN +send.cash.panel.option.pane.confirm.operation.text.with.memo=Confermare per favore che intende inviare {0} ZEN, dall'indirizzo:\n\ + {1} \n\ + all'indirizzo:\n\ + {2} \n\ + con tariffa di transazione: {3} ZEN, ed un memo testuale:\n\ + {4} \n +send.cash.panel.option.pane.confirm.operation.title=Confermare l'invio di denaro... +send.cash.panel.option.pane.confirm.operation.button.yes=Si (Confermo) +send.cash.panel.option.pane.confirm.operation.button.no=No +send.cash.panel.option.pane.confirm.operation.button.not.again=Si, non visualizzarlo ancora +send.cash.panel.option.pane.error.destination.amount.fractional.digits=Il valore specificato per l'invio: {0} ha pi� di 8 cifre decimali.\n\ + Non pu� essere rapresentato precisamente in una transazione ZEN e verr� arrotondato. Il valore attuale inviato\n\ + sara diverso. Siete sicuri di voler procedere? +send.cash.panel.option.pane.error.destination.fee.fractional.digits=La tariffa specificata per l'invio: {0} ha pi� di 8 cifre decimali.\n\ + Non pu� essere rapresentato precisamente in una transazione ZEN e verr� arrotondato. Il valore attuale inviato\n\ + sara diverso. Siete sicuri di voler procedere? +send.cash.panel.option.pane.error.destination.fractional.digits.title=La parte frazionaria eccede l'intervallo accettato +send.cash.panel.option.pane.error.amount.invalid=Il valore da inviare non � valido; � assente. +send.cash.panel.option.pane.error.amount.not.number=Il valore da inviare non � valido; non � un numero. +send.cash.panel.option.pane.error.amount.negative=Il valore da inviare non � valido; � negativo. +send.cash.panel.option.pane.error.fee.invalid=Tariffa di transazione non valida; assente. +send.cash.panel.option.pane.error.fee.not.number=Tariffa di transazione non valida; non � un numero. +send.cash.panel.option.pane.error.fee.negative=Tariffa di transazione non valida; � negativa. +send.cash.panel.option.pane.error.incorrect.sending.parameters=I parametri per l'invio non sono corretti +send.cash.panel.operation.status.progress.label=IN CORSO +send.cash.panel.operation.status.success.label=SUCCESSO +send.cash.panel.operation.complete.report=OK:Copiare ID transazione:Vedere nel blockchain +send.cash.panel.operation.complete.report.success.text=Inviati con successo {0} ZEN dall'indirizzo: \n {1} \n all'indirizzo: \n {2} \n\n ID Transazione: {3} +send.cash.panel.operation.complete.report.success.title=Denaro inviato con successo +send.cash.panel.operation.status.error.label=ERRORE: {0} +send.cash.panel.option.pane.error.report.text=� successo un errore nel invio. Messaggio di errore:\n {0} \n\n \ + Accertarsi per favore che i parametri siano corretti. Potete provare pi� tardi...\n +send.cash.panel.option.pane.error.report.title=Errore durante l'invio +send.cash.panel.checkbox.send.change.back=Inviare il saldo rimanente all'indirizzo sorgente (esplicitamente) +send.cash.panel.insufficient.balance=L'indirizzo: {0} \n\ + ha un saldo confermato di {1} ZEN che non � sufficente per coprire\n\ + il valore da inviare {2} ZEN e la tariffa di transazzione: {3} ZEN! +send.cash.panel.insufficient.balance.title=Fondi insuficenti +send.cash.panel.send.change.back.general.warning=\ + � stato selezionato l'opzione di inviare il saldo rimanente all'indirizzo sorgente\n\ + dopo l'invio. Questo puo funzionare correttamente quando l'indirizzo sorgente\n\ + non contiene un saldo non confermato/in attesa ed il blockchain e completamente\n\ + sincronizzato. Otherwise the change to send back may not be calculated correctly.\n\ + sincronizzato. Altrimenti il saldo rimanente non verr� calcolato correttamente.\n\ + Siete sicuri di voler procedere? +send.cash.panel.send.change.back.general.warning.title=Confermare l'invio del saldo rimanente indietro... + +single.key.import.dialog.title=Inserire chiave privata... +single.key.import.dialog.tmp.panel=Inserisca per favore una sola chiave privata da imporare. +single.key.import.dialog.tmp.panel.key.label=Chiave: +single.key.import.dialog.tmp.panel.key.lower.label= Attenzione: \ + L'importazione di una chiave privata � un operazione lenta che \ + necessita la rilettura del blockchain (pu� durare molti minuti).
Il GUI \ + non sara uttilizabile nelfratempo per altre operazioni +single.key.import.dialog.tmp.panel.ok.button.text=Importare +single.key.import.dialog.tmp.panel.cancel.button.text=Annulla +single.key.import.dialog.tmp.panel.process.ok.message=La chiave � vuota. Inserisca per favore la chiave. +single.key.import.dialog.tmp.panel.process.ok.title=Vuota... +single.key.import.dialog.tmp.panel.process.ok.addition= Corrisponde al indirizzo:\ {0} +single.key.import.dialog.tmp.panel.success.message=La chiave privata: {0} \n � stata importata con successo. {1} +single.key.import.dialog.tmp.panel.success.title=Chiave privata importata con successo... +single.key.import.dialog.tmp.panel.error.message=� successo un errore importando la chiave privata. Messaggio di errore: \n\ + {0} :\n {1} \n\n\ + Accertarsi per favore che zend sia avviato e che la chiave sia nella forma corretta \n\ + Potete provare pi� tardi...\n +single.key.import.dialog.tmp.panel.error.title=Errore importando la chiave privata + +startup.progress.dialog.label=ZENCash Wallet +startup.progress.dialog.progressbar.label=Avviando... + +status.update.error.reporter.panel.message=Errore inaspettato durante l'operazione del GUI wallet.\n\ + Dettagli si possono trovare nel log nella cartella: {0} \n\n {1} +status.update.error.reporter.panel.title=Errore durante l'operazione del wallet. + +transactions.detail.panel.yes=Si {0} +transactions.detail.panel.no=No\u0020\u0020{0} +transactions.detail.panel.column.names=Tipo:Direzione:Confermato?:Valore:Data:Indirizzo di destinazione + +transactions.table.show.in.explorer=Mostrare nel block explorer +transactions.table.memo.field=Prendere memo della transazione +transactions.table.memo.unavailable.text=La transazione selezionata non ha come destinazione un indirizzo Z (Privato) \n\ + oppure � sconoscuto (not mostrato) perci� non esistono \n\ + informazioni sul memo della transaziione. +transactions.table.memo.unavailable.title=Informazione sul Memo non presente +transactions.table.memo.clipboard.text=Il memo contenuto nella transazioine �: \n {0} \n\n\ + (Il Memo � stato copiato anche negli apunti.) +transactions.table.memo.clipboard.title=Memo +transactions.table.memo.field.missing.text=La transazione selezionata non contiene un campo memo. +transactions.table.memo.field.missing.title=Il campo Memo non � presente... +transaction.table.details.dialog.title=Detagli Transactione... +transaction.table.details.dialog.info.label= \ + La tabella mostra informazioni di transazioni con dettalgli tecnici \ + man mano che arrivano ne livello di rete ZENCash. +transaction.table.details.dialog.column.names=Nome:Valore +transaction.table.details.dialog.button.close=Chiudi + +wallet.operations.option.pane.already.encrypted.error.text=Il file wallet.dat usato � gi� criptato. \n\ + Questa operazione pu� essere eseguita solamente su un wallet che\n\ + non � stato \nancora criptato! +wallet.operations.option.pane.already.encrypted.error.title=Wallet � gia criptato... +wallet.operations.option.pane.encryption.error.text=Errore inaspettato nel criptare il wallet!\n \ + � consigliato riavviare sia zend che GUI wallet! \n \n {0} +wallet.operations.option.pane.encryption.error.title=Errore criptand il wallet... +wallet.operations.option.pane.encryption.success.text=Il Wallet � stato criptato con successo e zend � stato fermato.\n\ + Anche il GUI wallet verr� fermato. Riavviare entrami per favore.\n \ + addition the internal wallet keypool has been flushed. You need\n to make a new backup...\n + In pi� il pool di chiavi interni � stato scaricato. Dovete\n fare un nuovo backup...\n +wallet.operations.option.pane.encryption.success.title=Wallet � adesso criptato... +wallet.operations.dialog.backup.wallet.title=Backup wallet in un file... +wallet.operations.option.pane.backup.wallet.error.text=Errore inaspettato durante il backup del wallet!\n {0} \n +wallet.operations.option.pane.backup.wallet.error.title=Errore di backup... +wallet.operations.option.pane.backup.wallet.success.text=Backup eseguito con successo nel file: {0} \n\ + nella cartella di backup fornito a zend (-exportdir=).\nPath completo: {1} +wallet.operations.option.pane.backup.wallet.success.title=Backup completato... +wallet.operations.dialog.export.private.keys.title=Esportare le chiavi private del wallet... +wallet.operations.dialog.export.private.keys.error.text=Errore inaspettato durante l'esportazione delle chiavi private! \n {0} +wallet.operations.dialog.export.private.keys.error.title=Errore esportando le chiavi private... +wallet.operations.dialog.export.private.keys.success.text=Le chiavi private sono state esportate con successo nel file:\n {0} \ + \n nella cartella di backup fornito a zend (-exportdir=).\nPath completo: \ + {1} \n Dovete protegere questo file da accessi non autorizzati. Chiunque ne prende posesso\n ha accesso alle chiavi private \ + e puo spendere il saldo in ZENCash! +wallet.operations.dialog.export.private.keys.success.title=Esportazione chiavi private... +wallet.operations.dialog.import.private.keys.notice.text=L'importazione delle chiavi private � un operazione lenta. Pu� durare\n\ + diversi minuti durante i quali il GUI pu� non rispondere.\n\ + I dati da importare devono esser nel formato usato dall'opzione:\n\ + \"Esportare chiavi private...\"\n\n\ + Siete sicuri di voler importare le chiavi private? +wallet.operations.dialog.import.private.keys.notice.title=Avviso d'importazione chiave privata... +wallet.operations.file.chooser.import.private.keys.title=Importare chiavi private da file... +wallet.operations.dialog.import.private.keys.error.text=Errore inaspettato durante l'importazione delle chiavi private! \n {0} +wallet.operations.dialog.import.private.keys.error.title=Errore importando le chiavi private... +wallet.operations.dialog.import.private.keys.success.text=Le chiavi private sono state importate con successo dalla posizione:\n {0} \n\n +wallet.operations.dialog.import.private.keys.success.title=Importazione chiavi private... +wallet.operations.option.pane.own.address.view.private.key.text=Selezionare un indirizzo per favore dal tab \"Indirizzi propri\" per vedere la chiave privata +wallet.operations.option.pane.own.address.view.private.key.title=Selezionare un indirizzo per favore... +wallet.operations.option.pane.address.table.view.private.key.text=Selezionare un indirizzo per favore dal tab \"Indirizzi propri\" per vedere la chiave privata +wallet.operations.option.pane.address.table.view.private.key.title=Selezionare un indirizzo per favore... +wallet.operations.private.address=Z (Privato) +wallet.operations.transparent.address=T (Transparente) +wallet.operations.option.pane.address.information.text=indirizzo {0} :\n {1} \nha chiave privata:\n {2} \n\n\ + La chiave privata � stata copiato anche negli apunti. +wallet.operations.option.pane.address.information.title=Informazione sulla chiave privata +wallet.operations.dialog.export.arizen.title=Esportando Arizen wallet +wallet.operations.dialog.export.arizen.filechooser.filter=File del Arizen wallet +wallet.operations.dialog.export.arizen.filechooser.title=Esportare wallet ad Arizen wallet in formato non criptato... +wallet.operations.dialog.export.arizen.filechooser.aprove.button=Esportare +wallet.operations.dialog.delete.file.confirmation=Il file {0} esiste gi�. Volete procedere a sovrascriverlo? +wallet.operations.dialog.delete.file.confirmation.title=Avviso +wallet.operations.dialog.export.label=Esportando wallet... +wallet.operations.dialog.export.progress.reading.text=Leggendo inidrizzo e chiave privata... +wallet.operations.dialog.export.progress.writing.text=Scrivendo inidrizzo e chiave privata... +wallet.operations.dialog.export.progress.finished.text=Wallet esportato +wallet.operations.option.pane.export.success.info.text=L'Arizen wallet � stato esportato in: {0} \nUsando Arizen per importare selezionare: Importare Arizen wallet NON CRIPTATO.\n\ + Il wallet verr� importato e criptato. +wallet.operations.option.pane.export.success.info.title=Esportare Arizen wallet +wallet.operations.option.pane.backup.directory.warning.text=Per motivi di sicurezza il wallet pu� essere archiviato/chiavi private esportate solamente se\n\ + il parametro zend -exportdir= � stato impostato. Se avete avviato zend\n\ + manualmente, dovete aver fornito questo parametro. Quando zend viene \n\ + avviato automaticamente dal GUI wallet la cartella fornita come parametro al -exportdir\n\ + � la home directory del utente: {0} \n\n\ + Navigare per favore nella cartella fornita come -exportdir= e selezionare\n\ + da un file dove archiviare/esportare le chiavi private. Se selezionate un altra cartella \n\ + invece, la cartella di destinazione finir� comunque nella cartella fornita come + -exportdir=. \ + Se questo parametro non � stato formito a zend, il processo\n\ + fallir� con un errore di sicurezza. Il nome del file deve essere fatto solo di\n\ + caratteri alfanumerici(e.g. un punto non � permessp).\n +wallet.operations.option.pane.backup.directory.warning.title=Informazioni sulla cartella di backup +wallet.operations.option.pane.backup.directory.warning.message=Non visualizarlo pi� +wallet.operations.option.pane.backup.directory.warning.message.ok=OK + + +# Options pertaining to editing Zend command line parameters +# TODO: Needs to be translated into Italian +wallet.menu.edit.zend.params=Edit zend parameters... +wallet.operations.zend.parameters.warning.title=Warning +wallet.operations.zend.parameters.warning.text=The zend node is automatically started by the wallet. Editing the parameters used to\n\ + start zend should be done with care - typically by experienced users only. Any incorrect\n\ + setting of these parameters may prevent the wallet from starting properly!\n\ + \n\ + In case of emergencies, the parameters may also be edited using a text editor\n\ + in configuration file:\n\ + {0}\n +wallet.operations.zend.parameters.warning.notagain=Do not show this again +wallet.operations.zend.parameters.warning.oklabel=OK + +zend.cmd.params.dialog.title=Edit zend command line parameters... +zend.cmd.params.dialog.info=\ + The parameters below are used to start zend when the GUI wallet is started. The required format when editing them
\ + is to have one parameter on a single text line. For more information on the possible parameters that may be set, one
\ + may check the \ + \ + zend documentation. Any changes made here will only take effect on the next restart of the \ + wallet.
\ +
+zend.cmd.params.dialog.close.button=Close +zend.cmd.params.dialog.save.button=Save & close +zend.cmd.params.dialog.double.option.warning.text=It appears that the following line has more than one zend parameter on it:\n\n\ + {0}\n\n\ + Please note that only one zend parameter may be specified per line, or\n\ + else the parameters may not be passed correctly!\n\n\ + Are you sure you wish to save the parameters to the configuration file? +zend.cmd.params.dialog.double.option.warning.title=Multiple parameters found on one line! +zend.cmd.params.dialog.success.text=The modified parameters for starting zend have been successfully saved in configuration file:\n\ + {0}\n\ + The parameters will take effect on the next start of the GUI wallet. +zend.cmd.params.dialog.success.title=Parameters saved successfully + + diff --git a/src/resources/ubuntu-package/ZEN-icon.png b/src/resources/ubuntu-package/ZEN-icon.png deleted file mode 100644 index 24df0fbc..00000000 Binary files a/src/resources/ubuntu-package/ZEN-icon.png and /dev/null differ diff --git a/zencash-wallet-swing/pom.xml b/zencash-wallet-swing/pom.xml new file mode 100644 index 00000000..23ccc083 --- /dev/null +++ b/zencash-wallet-swing/pom.xml @@ -0,0 +1,181 @@ + + + 4.0.0 + + + com.zencash + HorizenSwingWalletUI + 1.0.12-SNAPSHOT + + + zencash-wallet-swing + jar + + + com.vaklinov.zcashui.HorizenUI + ZENCashSwingWalletUI + + + + + junit + junit + test + + + + + org.bitcoinj + bitcoinj-core + + + + org.xerial + sqlite-jdbc + + + + com.eclipsesource.minimal-json + minimal-json + + + + + ../src/java + + + ../src/resources + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + ${main.class} + + + + + + maven-resources-plugin + + + copy-deb-resources + process-resources + copy-resources + + true + ${basedir}/target/deb + + + src/deb/resources + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + ${basedir}/target/deb/jars + true + junit + + + + + + org.vafer + jdeb + + + package + + jdeb + + + true + true + + USER + true + ${basedir}/src/deb/control + + + ${project.build.directory}/${project.build.finalName}.jar + ${application.finalName}.jar + file + + perm + /usr/lib/zencash-gui-wallet + 755 + + + + ${project.build.directory}/deb/jars + directory + + perm + /usr/lib/zencash-gui-wallet + 755 + + + + ${project.build.directory}/deb/licences + directory + + perm + /usr/lib/zencash-gui-wallet + 755 + + + + ${project.build.directory}/deb/zencash-desktop-gui-wallet + file + + perm + /usr/bin + 755 + + + + ${project.build.directory}/deb/ZENCashWallet.desktop + file + + perm + /usr/share/applications + 755 + + + + ${project.build.directory}/deb/ZEN-icon.png + file + + perm + /usr/lib/zencash-gui-wallet + 755 + + + + + + + + + + diff --git a/src/resources/ubuntu-package/control b/zencash-wallet-swing/src/deb/control/control similarity index 53% rename from src/resources/ubuntu-package/control rename to zencash-wallet-swing/src/deb/control/control index 0db510bc..f9af573d 100644 --- a/src/resources/ubuntu-package/control +++ b/zencash-wallet-swing/src/deb/control/control @@ -1,8 +1,8 @@ Package: zencash-desktop-gui-wallet -Version: 0.75.9 +Version: 1.0.12 Section: misc Priority: low Architecture: all -Description: ZENCash Desktop GUI Wallet -Maintainer: ivan@vaklinov.com +Description: Horizen Desktop GUI Wallet +Maintainer: infrastructure@horizen.io Depends: default-jdk, zen diff --git a/zencash-wallet-swing/src/deb/resources/ZEN-icon.png b/zencash-wallet-swing/src/deb/resources/ZEN-icon.png new file mode 100644 index 00000000..1b49aaf6 Binary files /dev/null and b/zencash-wallet-swing/src/deb/resources/ZEN-icon.png differ diff --git a/src/resources/ubuntu-package/ZENCashWallet.desktop b/zencash-wallet-swing/src/deb/resources/ZENCashWallet.desktop similarity index 72% rename from src/resources/ubuntu-package/ZENCashWallet.desktop rename to zencash-wallet-swing/src/deb/resources/ZENCashWallet.desktop index bae048a4..cf19b2cc 100644 --- a/src/resources/ubuntu-package/ZENCashWallet.desktop +++ b/zencash-wallet-swing/src/deb/resources/ZENCashWallet.desktop @@ -1,8 +1,8 @@ [Desktop Entry] Version=1.0 -Name=ZENCash Wallet -Comment=ZENCash Desktop GUI Wallet (full node) -GenericName=ZENCash Wallet +Name=Horizen Wallet +Comment=Horizen Desktop GUI Wallet (full node) +GenericName=Horizen Wallet Keywords=ZENCash;Crypto-currency;ZEN; Exec=zencash-desktop-gui-wallet Terminal=false diff --git a/zencash-wallet-swing/src/deb/resources/licences/bitcoinj-core-0.14.5_LICENSE.txt b/zencash-wallet-swing/src/deb/resources/licences/bitcoinj-core-0.14.5_LICENSE.txt new file mode 100644 index 00000000..f4f87bd4 --- /dev/null +++ b/zencash-wallet-swing/src/deb/resources/licences/bitcoinj-core-0.14.5_LICENSE.txt @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + \ No newline at end of file diff --git a/zencash-wallet-swing/src/deb/resources/licences/jdeb-1.5.license.txt b/zencash-wallet-swing/src/deb/resources/licences/jdeb-1.5.license.txt new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/zencash-wallet-swing/src/deb/resources/licences/jdeb-1.5.license.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/zencash-wallet-swing/src/deb/resources/licences/minimal-json.info.txt b/zencash-wallet-swing/src/deb/resources/licences/minimal-json.info.txt new file mode 100644 index 00000000..3361ffff --- /dev/null +++ b/zencash-wallet-swing/src/deb/resources/licences/minimal-json.info.txt @@ -0,0 +1,2 @@ +JSON Parser code taken from: +https://github.com/ralfstx/minimal-json diff --git a/zencash-wallet-swing/src/deb/resources/licences/sqlite-jdbc-3.21.0_LICENSE.txt b/zencash-wallet-swing/src/deb/resources/licences/sqlite-jdbc-3.21.0_LICENSE.txt new file mode 100644 index 00000000..99e5a8d0 --- /dev/null +++ b/zencash-wallet-swing/src/deb/resources/licences/sqlite-jdbc-3.21.0_LICENSE.txt @@ -0,0 +1,229 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + LICENSE.zentus + + +Copyright (c) 2006, David Crawshaw. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/src/resources/ubuntu-package/zencash-desktop-gui-wallet b/zencash-wallet-swing/src/deb/resources/zencash-desktop-gui-wallet similarity index 88% rename from src/resources/ubuntu-package/zencash-desktop-gui-wallet rename to zencash-wallet-swing/src/deb/resources/zencash-desktop-gui-wallet index 966c70b1..06df0799 100644 --- a/src/resources/ubuntu-package/zencash-desktop-gui-wallet +++ b/zencash-wallet-swing/src/deb/resources/zencash-desktop-gui-wallet @@ -6,8 +6,9 @@ # / / | __| | . ` | | / _` / __| '_ \| | |_ | | | | | | \ \/ \/ / _` | | |/ _ \ __| # / /__| |____| |\ | |___| (_| \__ \ | | | |__| | |__| |_| |_ \ /\ / (_| | | | __/ |_ # /_____|______|_| \_|\_____\__,_|___/_| |_|\_____|\____/|_____| \/ \/ \__,_|_|_|\___|\__| -# -# Copyright (c) 2017 Ivan Vaklinov +# +# Copyright (c) 2023 The Horizen Foundation +# Copyright (c) 2016-2021 Zen Blockchain Foundation # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -28,4 +29,6 @@ # THE SOFTWARE. # -java -jar /usr/lib/zencash-gui-wallet/ZENCashSwingWalletUI.jar +jvm="java" + +${jvm} -jar /usr/lib/zencash-gui-wallet/ZENCashSwingWalletUI.jar diff --git a/zencash-wallet-swing/src/icons/ZEN.ico b/zencash-wallet-swing/src/icons/ZEN.ico new file mode 100644 index 00000000..fe5abd32 Binary files /dev/null and b/zencash-wallet-swing/src/icons/ZEN.ico differ diff --git a/zencash-wallet-swing/src/icons/ZENCashWallet.icns b/zencash-wallet-swing/src/icons/ZENCashWallet.icns new file mode 100644 index 00000000..bd526e66 Binary files /dev/null and b/zencash-wallet-swing/src/icons/ZENCashWallet.icns differ diff --git a/zencash-wallet-swing/src/icons/ZENCashWallet.iconset/icon_128x128.png b/zencash-wallet-swing/src/icons/ZENCashWallet.iconset/icon_128x128.png new file mode 100644 index 00000000..1b49aaf6 Binary files /dev/null and b/zencash-wallet-swing/src/icons/ZENCashWallet.iconset/icon_128x128.png differ diff --git a/src/java/com/vaklinov/zcashtest/Test1.java b/zencash-wallet-swing/src/test/java/com/vaklinov/zcashtest/Test1.java similarity index 97% rename from src/java/com/vaklinov/zcashtest/Test1.java rename to zencash-wallet-swing/src/test/java/com/vaklinov/zcashtest/Test1.java index 6d0b17c0..4203354f 100644 --- a/src/java/com/vaklinov/zcashtest/Test1.java +++ b/zencash-wallet-swing/src/test/java/com/vaklinov/zcashtest/Test1.java @@ -35,7 +35,7 @@ public static void main(String[] args) //System.out.println(hexify("\n")); - String phrase = "Z pigs likes to snooze. ZZZZ"; + String phrase = "Z pigs like to snooze. ZZZZ"; System.out.println(phrase + "|=> " + Util.convertGroupPhraseToZPrivateKey(phrase)); phrase = "ABCD"; System.out.println(phrase + "|=> " + Util.convertGroupPhraseToZPrivateKey(phrase));