fix packageInstallers for all platforms
3
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
bin/
|
||||
*/docs
|
||||
*/log
|
||||
*/bin
|
||||
*/out
|
||||
.idea
|
||||
!.idea/copyright/bisq_Affero_GPLv3.xml
|
||||
@ -34,3 +34,4 @@ deploy
|
||||
/monitor/monitor-tor/*
|
||||
.java-version
|
||||
.localnet
|
||||
.vscode
|
116
build.gradle
@ -1,3 +1,5 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
@ -331,7 +333,6 @@ configure(project(':p2p')) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
configure(project(':core')) {
|
||||
dependencies {
|
||||
implementation project(':proto')
|
||||
@ -406,12 +407,113 @@ configure(project(':core')) {
|
||||
systemProperty 'jdk.attach.allowAttachSelf', true
|
||||
}
|
||||
|
||||
task havenoDeps(type: Exec) {
|
||||
workingDir '..'
|
||||
commandLine './scripts/haveno_deps.sh'
|
||||
task havenoDeps {
|
||||
doLast {
|
||||
// get monero binaries download url
|
||||
Map moneroBinaries = [
|
||||
'linux' : 'https://github.com/haveno-dex/monero/releases/download/testing8/monero-bins-haveno-linux.tar.gz',
|
||||
'linux-sha256' : 'a222bdae08e5464d1b751e6301144a904578bef37c75444c46aef762299c0b92',
|
||||
'mac' : 'https://github.com/haveno-dex/monero/releases/download/testing8/monero-bins-haveno-mac.tar.gz',
|
||||
'mac-sha256' : 'fbebd9eb40550cd992bf9e1f946741d5adc564c428b9d4c78981363235c4be89',
|
||||
'windows' : 'https://github.com/haveno-dex/monero/releases/download/testing8/monero-bins-haveno-windows.zip',
|
||||
'windows-sha256': 'c9e6150ba9cb8b35b7c63ac8786610e3c37725a973e35c09e6fbbfe20430302a'
|
||||
]
|
||||
|
||||
String osKey
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
osKey = 'windows'
|
||||
} else if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
osKey = 'mac'
|
||||
} else {
|
||||
osKey = 'linux'
|
||||
}
|
||||
|
||||
String moneroDownloadUrl = moneroBinaries[osKey]
|
||||
String moneroSHA256Hash = moneroBinaries[osKey + '-sha256']
|
||||
String moneroArchiveFileName = moneroDownloadUrl.tokenize('/').last()
|
||||
String localnetDirName = '.localnet'
|
||||
File localnetDir = new File(project.rootDir, localnetDirName)
|
||||
localnetDir.mkdirs()
|
||||
File moneroArchiveFile = new File(localnetDir, moneroArchiveFileName)
|
||||
ext.downloadAndVerifyDependencies(moneroDownloadUrl, moneroSHA256Hash, moneroArchiveFile)
|
||||
|
||||
// extract if dependencies are missing or if archive was updated
|
||||
File monerodFile
|
||||
File moneroRpcFile
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
monerodFile = new File(localnetDir, 'monerod.exe')
|
||||
moneroRpcFile = new File(localnetDir, 'monero-wallet-rpc.exe')
|
||||
} else {
|
||||
monerodFile = new File(localnetDir, 'monerod')
|
||||
moneroRpcFile = new File(localnetDir, 'monero-wallet-rpc')
|
||||
}
|
||||
if (ext.dependencyDownloadedAndVerified || !monerodFile.exists() || !moneroRpcFile.exists()) {
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
ext.extractArchiveZip(moneroArchiveFile, localnetDir)
|
||||
} else {
|
||||
ext.extractArchiveTarGz(moneroArchiveFile, localnetDir)
|
||||
}
|
||||
|
||||
// add the current platform's monero dependencies into the resources folder for installation
|
||||
copy {
|
||||
from "${monerodFile}"
|
||||
into "${project(':core').projectDir}/src/main/resources/bin"
|
||||
}
|
||||
copy {
|
||||
from "${moneroRpcFile}"
|
||||
into "${project(':core').projectDir}/src/main/resources/bin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ext.extractArchiveTarGz = { File tarGzFile, File destinationDir ->
|
||||
println "Extracting tar.gz ${tarGzFile}"
|
||||
// Gradle's tar extraction preserves permissions (crucial for jpackage to function correctly)
|
||||
copy {
|
||||
from tarTree(resources.gzip(tarGzFile))
|
||||
into destinationDir
|
||||
}
|
||||
println "Extracted to ${destinationDir}"
|
||||
}
|
||||
|
||||
ext.extractArchiveZip = { File zipFile, File destinationDir ->
|
||||
println "Extracting zip ${zipFile}..."
|
||||
ant.unzip(src: zipFile, dest: destinationDir)
|
||||
println "Extracted to ${destinationDir}"
|
||||
}
|
||||
|
||||
ext.downloadAndVerifyDependencies = { String archiveURL, String archiveSHA256, File destinationArchiveFile ->
|
||||
ext.dependencyDownloadedAndVerified = false
|
||||
// if archive exists, check to see if its already up to date
|
||||
if (destinationArchiveFile.exists()) {
|
||||
println "Verifying existing archive ${destinationArchiveFile}"
|
||||
ant.archiveHash = archiveSHA256
|
||||
ant.checksum(file: destinationArchiveFile, algorithm: 'SHA-256', property: '${archiveHash}', verifyProperty: 'existingHashMatches')
|
||||
if (ant.properties['existingHashMatches'] != 'true') {
|
||||
println "Existing archive does not match hash ${archiveSHA256}"
|
||||
} else {
|
||||
println "Existing archive matches hash"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
println "Downloading ${archiveURL}"
|
||||
ant.get(src: archiveURL, dest: destinationArchiveFile)
|
||||
println 'Download saved to ' + destinationArchiveFile
|
||||
|
||||
println 'Verifying checksum for downloaded binary ...'
|
||||
ant.archiveHash = archiveSHA256
|
||||
// use a different verifyProperty name from existing verification or it will always fail
|
||||
ant.checksum(file: destinationArchiveFile, algorithm: 'SHA-256', property: '${archiveHash}', verifyProperty: 'downloadedHashMatches')
|
||||
if (ant.properties['downloadedHashMatches'] != 'true') {
|
||||
ant.fail('Checksum mismatch: Downloaded archive has a different checksum than expected')
|
||||
}
|
||||
println 'Checksum verified'
|
||||
ext.dependencyDownloadedAndVerified = true
|
||||
}
|
||||
}
|
||||
if (osdetector.os != 'windows') processResources.dependsOn havenoDeps // before both test and build
|
||||
else println "Haveno dependencies must be downloaded manually on Windows"
|
||||
|
||||
processResources.dependsOn havenoDeps // before both test and build
|
||||
}
|
||||
|
||||
configure(project(':cli')) {
|
||||
@ -457,7 +559,7 @@ configure(project(':desktop')) {
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply from: 'package/package.gradle'
|
||||
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
version = '1.0.0-SNAPSHOT'
|
||||
|
||||
jar.manifest.attributes(
|
||||
"Implementation-Title": project.name,
|
||||
|
@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
public class Version {
|
||||
// The application versions
|
||||
// We use semantic versioning with major, minor and patch
|
||||
public static final String VERSION = "0.0.3";
|
||||
public static final String VERSION = "1.0.0";
|
||||
|
||||
/**
|
||||
* Holds a list of the tagged resource files for optimizing the getData requests.
|
||||
|
@ -21,6 +21,7 @@ import bisq.core.user.Preferences;
|
||||
import bisq.core.xmr.MoneroNodeSettings;
|
||||
import bisq.common.config.BaseCurrencyNetwork;
|
||||
import bisq.common.config.Config;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -43,8 +44,10 @@ import monero.daemon.MoneroDaemonRpc;
|
||||
public class CoreMoneroNodeService {
|
||||
|
||||
private static final String MONERO_NETWORK_TYPE = Config.baseCurrencyNetwork().getNetwork().toLowerCase();
|
||||
private static final String MONEROD_PATH = System.getProperty("user.dir") + File.separator + ".localnet" + File.separator + "monerod";
|
||||
private static final String MONEROD_DATADIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1" : null;
|
||||
public static final String MONEROD_DIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath();
|
||||
public static final String MONEROD_NAME = Utilities.isWindows() ? "monerod.exe" : "monerod";
|
||||
public static final String MONEROD_PATH = MONEROD_DIR + File.separator + MONEROD_NAME;
|
||||
private static final String MONEROD_DATADIR = MONEROD_DIR + File.separator + Config.baseCurrencyNetwork().toString().toLowerCase() + File.separator + "node1";
|
||||
|
||||
private final Preferences preferences;
|
||||
private final List<MoneroNodeServiceListener> listeners = new ArrayList<>();
|
||||
|
@ -23,6 +23,7 @@ import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.alert.Alert;
|
||||
import bisq.core.alert.AlertManager;
|
||||
import bisq.core.alert.PrivateNotificationPayload;
|
||||
import bisq.core.api.CoreMoneroNodeService;
|
||||
import bisq.core.btc.model.AddressEntry;
|
||||
import bisq.core.btc.nodes.LocalBitcoinNode;
|
||||
import bisq.core.btc.setup.WalletsSetup;
|
||||
@ -54,6 +55,7 @@ import bisq.common.app.Log;
|
||||
import bisq.common.app.Version;
|
||||
import bisq.common.config.BaseCurrencyNetwork;
|
||||
import bisq.common.config.Config;
|
||||
import bisq.common.file.FileUtil;
|
||||
import bisq.common.util.InvalidVersionException;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
@ -297,6 +299,7 @@ public class HavenoSetup {
|
||||
}
|
||||
|
||||
private void step3() {
|
||||
maybeInstallDependencies();
|
||||
startP2pNetworkAndWallet(this::step4);
|
||||
}
|
||||
|
||||
@ -342,6 +345,29 @@ public class HavenoSetup {
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeInstallDependencies() {
|
||||
try {
|
||||
File monerodFile = new File(CoreMoneroNodeService.MONEROD_PATH);
|
||||
if (!monerodFile.exists()) {
|
||||
log.info("Installing monerod");
|
||||
monerodFile.getParentFile().mkdirs();
|
||||
FileUtil.resourceToFile("bin/" + CoreMoneroNodeService.MONEROD_NAME, monerodFile);
|
||||
monerodFile.setExecutable(true);
|
||||
}
|
||||
|
||||
File moneroWalletFile = new File(XmrWalletService.MONERO_WALLET_RPC_PATH);
|
||||
if (!moneroWalletFile.exists()) {
|
||||
log.info("Installing monero-wallet-rpc");
|
||||
moneroWalletFile.getParentFile().mkdirs();
|
||||
FileUtil.resourceToFile("bin/" + XmrWalletService.MONERO_WALLET_RPC_NAME, moneroWalletFile);
|
||||
moneroWalletFile.setExecutable(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void readMapsFromResources(Runnable completeHandler) {
|
||||
String postFix = "_" + config.baseCurrencyNetwork.name();
|
||||
p2PService.getP2PDataStorage().readFromResources(postFix, completeHandler);
|
||||
|
@ -3,8 +3,10 @@ package bisq.core.btc.wallet;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.config.BaseCurrencyNetwork;
|
||||
import bisq.common.config.Config;
|
||||
import bisq.common.file.FileUtil;
|
||||
import bisq.common.util.Utilities;
|
||||
import bisq.core.api.AccountServiceListener;
|
||||
import bisq.core.api.CoreAccountService;
|
||||
import bisq.core.api.CoreMoneroConnectionsService;
|
||||
@ -74,8 +76,9 @@ public class XmrWalletService {
|
||||
public static final int NUM_BLOCKS_UNLOCK = 10;
|
||||
private static final MoneroNetworkType MONERO_NETWORK_TYPE = getMoneroNetworkType();
|
||||
private static final MoneroWalletRpcManager MONERO_WALLET_RPC_MANAGER = new MoneroWalletRpcManager();
|
||||
private static final String MONERO_WALLET_RPC_DIR = System.getProperty("user.dir") + File.separator + ".localnet"; // .localnet contains monero-wallet-rpc and wallet files
|
||||
private static final String MONERO_WALLET_RPC_PATH = MONERO_WALLET_RPC_DIR + File.separator + "monero-wallet-rpc";
|
||||
public static final String MONERO_WALLET_RPC_DIR = Config.baseCurrencyNetwork() == BaseCurrencyNetwork.XMR_LOCAL ? System.getProperty("user.dir") + File.separator + ".localnet" : Config.appDataDir().getAbsolutePath(); // .localnet contains monero-wallet-rpc and wallet files
|
||||
public static final String MONERO_WALLET_RPC_NAME = Utilities.isWindows() ? "monero-wallet-rpc.exe" : "monero-wallet-rpc";
|
||||
public static final String MONERO_WALLET_RPC_PATH = MONERO_WALLET_RPC_DIR + File.separator + MONERO_WALLET_RPC_NAME;
|
||||
private static final String MONERO_WALLET_RPC_USERNAME = "haveno_user";
|
||||
private static final String MONERO_WALLET_RPC_DEFAULT_PASSWORD = "password"; // only used if account password is null
|
||||
private static final String MONERO_WALLET_NAME = "haveno_XMR";
|
||||
@ -147,12 +150,12 @@ public class XmrWalletService {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// TODO (woodser): need trade manager to get trade ids to change all wallet passwords?
|
||||
public void setTradeManager(TradeManager tradeManager) {
|
||||
this.tradeManager = tradeManager;
|
||||
}
|
||||
|
||||
|
||||
public MoneroWallet getWallet() {
|
||||
State state = walletsSetup.getWalletConfig().state();
|
||||
checkState(state == State.STARTING || state == State.RUNNING, "Cannot call until startup is complete, but state is: " + state);
|
||||
@ -166,15 +169,15 @@ public class XmrWalletService {
|
||||
public boolean isWalletEncrypted() {
|
||||
return accountService.getPassword() != null;
|
||||
}
|
||||
|
||||
|
||||
public MoneroDaemonRpc getDaemon() {
|
||||
return connectionsService.getDaemon();
|
||||
}
|
||||
|
||||
|
||||
public CoreMoneroConnectionsService getConnectionsService() {
|
||||
return connectionsService;
|
||||
}
|
||||
|
||||
|
||||
public String getWalletPassword() {
|
||||
return accountService.getPassword() == null ? MONERO_WALLET_RPC_DEFAULT_PASSWORD : accountService.getPassword();
|
||||
}
|
||||
@ -234,12 +237,12 @@ public class XmrWalletService {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the reserve tx and freeze its inputs. The deposit amount is returned
|
||||
* to the sender's payout address. Additional funds are reserved to allow
|
||||
* fluctuations in the mining fee.
|
||||
*
|
||||
*
|
||||
* @param tradeFee is the trade fee
|
||||
* @param depositAmount the amount needed for the trade minus the trade fee
|
||||
* @return a transaction to reserve a trade
|
||||
@ -271,10 +274,10 @@ public class XmrWalletService {
|
||||
return reserveTx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the multisig deposit tx and freeze its inputs.
|
||||
*
|
||||
*
|
||||
* @return MoneroTxWallet the multisig deposit tx
|
||||
*/
|
||||
public MoneroTxWallet createDepositTx(Trade trade) {
|
||||
@ -304,7 +307,7 @@ public class XmrWalletService {
|
||||
* Verify a reserve or deposit transaction used during trading.
|
||||
* Checks double spends, deposit amount and destination, trade fee, and mining fee.
|
||||
* The transaction is submitted but not relayed to the pool then flushed.
|
||||
*
|
||||
*
|
||||
* @param depositAddress is the expected destination address for the deposit amount
|
||||
* @param depositAmount is the expected amount deposited to multisig
|
||||
* @param tradeFee is the expected fee for trading
|
||||
@ -437,7 +440,7 @@ public class XmrWalletService {
|
||||
setWalletDaemonConnections(newConnection);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private boolean walletExists(String walletName) {
|
||||
String path = walletDir.toString() + File.separator + walletName;
|
||||
return new File(path + ".keys").exists();
|
||||
@ -526,7 +529,7 @@ public class XmrWalletService {
|
||||
log.info("Syncing wallet " + config.getPath());
|
||||
walletRpc.sync();
|
||||
log.info("Done syncing wallet " + config.getPath());
|
||||
|
||||
|
||||
// start syncing wallet in background
|
||||
new Thread(() -> {
|
||||
log.info("Syncing wallet " + config.getPath() + " in background");
|
||||
@ -549,8 +552,16 @@ public class XmrWalletService {
|
||||
|
||||
// build command to start monero-wallet-rpc
|
||||
List<String> cmd = new ArrayList<>(Arrays.asList( // modifiable list
|
||||
MONERO_WALLET_RPC_PATH, "--" + MONERO_NETWORK_TYPE.toString().toLowerCase(), "--rpc-login",
|
||||
MONERO_WALLET_RPC_USERNAME + ":" + getWalletPassword(), "--wallet-dir", walletDir.toString()));
|
||||
MONERO_WALLET_RPC_PATH,
|
||||
"--rpc-login",
|
||||
MONERO_WALLET_RPC_USERNAME + ":" + getWalletPassword(),
|
||||
"--wallet-dir", walletDir.toString()));
|
||||
|
||||
// omit --mainnet flag since it does not exist
|
||||
if (MONERO_NETWORK_TYPE != MoneroNetworkType.MAINNET) {
|
||||
cmd.add("--" + MONERO_NETWORK_TYPE.toString().toLowerCase());
|
||||
}
|
||||
|
||||
MoneroRpcConnection connection = withConnection ? connectionsService.getConnection() : null;
|
||||
if (connection != null) {
|
||||
cmd.add("--daemon-address");
|
||||
@ -694,7 +705,7 @@ public class XmrWalletService {
|
||||
multisigWallets.clear();
|
||||
walletListeners.clear();
|
||||
}
|
||||
|
||||
|
||||
private void backupWallet(String walletName) {
|
||||
FileUtil.rollingBackup(walletDir, walletName, 20);
|
||||
FileUtil.rollingBackup(walletDir, walletName + ".keys", 20);
|
||||
@ -706,7 +717,7 @@ public class XmrWalletService {
|
||||
FileUtil.deleteRollingBackup(walletDir, walletName + ".keys");
|
||||
FileUtil.deleteRollingBackup(walletDir, walletName + ".address.txt");
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------- LEGACY APP -------------------------------
|
||||
|
||||
public XmrAddressEntry getNewAddressEntry() {
|
||||
@ -903,11 +914,11 @@ public class XmrWalletService {
|
||||
available = Stream.concat(available, getAddressEntries(XmrAddressEntry.Context.OFFER_FUNDING).stream());
|
||||
return available.filter(addressEntry -> getBalanceForSubaddress(addressEntry.getSubaddressIndex()).isPositive());
|
||||
}
|
||||
|
||||
|
||||
public void addWalletListener(MoneroWalletListenerI listener) {
|
||||
walletListeners.add(listener);
|
||||
}
|
||||
|
||||
|
||||
public void removeWalletListener(MoneroWalletListenerI listener) {
|
||||
if (!walletListeners.contains(listener)) throw new RuntimeException("Listener is not registered with wallet");
|
||||
walletListeners.remove(listener);
|
||||
@ -933,8 +944,7 @@ public class XmrWalletService {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Util
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
public static MoneroNetworkType getMoneroNetworkType() {
|
||||
switch (Config.baseCurrencyNetwork()) {
|
||||
case XMR_LOCAL:
|
||||
@ -953,16 +963,16 @@ public class XmrWalletService {
|
||||
for (MoneroTxWallet tx : txs) sb.append('\n' + tx.toString());
|
||||
log.info("\n" + tracePrefix + ":" + sb.toString());
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------- HELPERS -------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Processes internally before notifying external listeners.
|
||||
*
|
||||
*
|
||||
* TODO: no longer neccessary to execute on user thread?
|
||||
*/
|
||||
private class XmrWalletListener extends MoneroWalletListener {
|
||||
|
||||
|
||||
@Override
|
||||
public void onSyncProgress(long height, long startHeight, long endHeight, double percentDone, String message) {
|
||||
UserThread.execute(new Runnable() {
|
||||
|
BIN
desktop/package/Haveno.zip
Normal file
51
desktop/package/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# Package Installers
|
||||
|
||||
Run `./gradlew packageInstallers` on the corresponding platform. Wix must be installed for Windows packaging.
|
||||
|
||||
## Icons
|
||||
|
||||
Icons (Haveno.zip) were obtained from https://github.com/haveno-dex/haveno-meta/issues/1#issuecomment-819741689.
|
||||
|
||||
### Linux
|
||||
|
||||
The linux package requires the correct packaging tools installed. You may run into the following errors:
|
||||
|
||||
```
|
||||
Error: Invalid or unsupported type: [deb]
|
||||
```
|
||||
```
|
||||
Error: Invalid or unsupported type: [rpm]
|
||||
```
|
||||
|
||||
On Ubuntu, resolve by running `sudo apt install rpm`. For deb, ensure dpkg is installed.
|
||||
|
||||
```
|
||||
Exception in thread "main" java.io.IOException: Failed to rename /tmp/Bisq-stripped15820156885694375398.tmp to /storage/src/haveno/desktop/build/libs/fatJar/desktop-1.0.0-SNAPSHOT-all.jar
|
||||
at bisq.tools.Utils.renameFile(Utils.java:36)
|
||||
at io.github.zlika.reproducible.StipZipFile.strip(StipZipFile.java:35)
|
||||
at bisq.tools.DeterministicBuildTool.main(DeterministicBuildTool.java:24)
|
||||
|
||||
```
|
||||
|
||||
This may happen if the source folder is on a different hard drive than the system `tmp` folder. The tools-1.0.jar calls renameTo to rename the deterministic jar back to the fat jar location. You can temporarily change your temp directory on linux:
|
||||
|
||||
```
|
||||
export _JAVA_OPTIONS="-Djava.io.tmpdir=/storage/tmp"
|
||||
```
|
||||
|
||||
### MacOs
|
||||
|
||||
Svg was converted into a 1024x1024 pixel PNG using https://webkul.github.io/myscale/, then converted to icns for macosx
|
||||
here https://cloudconvert.com/png-to-icns
|
||||
|
||||
#### Known Issues
|
||||
|
||||
Signing is not implemented.
|
||||
|
||||
### Windows
|
||||
|
||||
Pngs were resized and pasted into the WixUi images using paint. [CloudConvert](https://cloudconvert.com) was used to convert the Haveno png icon to ico.
|
||||
|
||||
#### Known Issues
|
||||
|
||||
The installer's final step "Launch Haveno" has a different background color. The setup executable does not have an icon.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 20 KiB |
@ -1,41 +0,0 @@
|
||||
tell application "Finder"
|
||||
tell disk "Bisq"
|
||||
open
|
||||
set current view of container window to icon view
|
||||
set toolbar visible of container window to false
|
||||
set statusbar visible of container window to false
|
||||
set pathbar visible of container window to false
|
||||
|
||||
-- size of window should match size of background (1034x641)
|
||||
set the bounds of container window to {400, 100, 1434, 741}
|
||||
|
||||
set theViewOptions to the icon view options of container window
|
||||
set arrangement of theViewOptions to not arranged
|
||||
set icon size of theViewOptions to 128
|
||||
set background picture of theViewOptions to file ".background:background.tiff"
|
||||
|
||||
-- Create alias for install location
|
||||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||
|
||||
set allTheFiles to the name of every item of container window
|
||||
repeat with theFile in allTheFiles
|
||||
set theFilePath to POSIX Path of theFile
|
||||
if theFilePath is "/Bisq.app"
|
||||
-- Position application location
|
||||
set position of item theFile of container window to {345, 343}
|
||||
else if theFilePath is "/Applications"
|
||||
-- Position install location
|
||||
set position of item theFile of container window to {677, 343}
|
||||
else
|
||||
-- Move all other files far enough to be not visible if user has "show hidden files" option set
|
||||
set position of item theFile of container window to {1000, 0}
|
||||
end
|
||||
end repeat
|
||||
|
||||
close
|
||||
open
|
||||
update without registering applications
|
||||
delay 5
|
||||
end tell
|
||||
end tell
|
||||
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 755 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 287 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
desktop/package/macosx/Haveno-volume.icns
Normal file
BIN
desktop/package/macosx/Haveno.icns
Normal file
@ -5,28 +5,28 @@
|
||||
<!-- See: https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -->
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.1</string>
|
||||
<string>1.0.0</string>
|
||||
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.1</string>
|
||||
<string>1.0.0</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Bisq</string>
|
||||
<string>Haveno</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>Bisq</string>
|
||||
<string>Haveno</string>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.bisq.CAT</string>
|
||||
<string>io.haveno.CAT</string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Bisq.icns</string>
|
||||
<string>Haveno.icns</string>
|
||||
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.finance</string>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2013-2021 - The Bisq developers</string>
|
||||
<string>Copyright © 2022 - The Haveno developers</string>
|
||||
|
||||
<!-- Only supported in older OSX versions.
|
||||
See: https://github.com/bitcoin/bitcoin/issues/11896#issuecomment-352148399-->
|
||||
|
@ -1,6 +1,5 @@
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
task jpackageSanityChecks {
|
||||
description 'Interactive sanity checks on the version of the code that will be packaged'
|
||||
@ -128,7 +127,7 @@ task retrieveAndExtractJavaBinaries {
|
||||
|
||||
// Find jpackage in the newly extracted JDK
|
||||
// Don't rely on hardcoded paths to reach it, because the path depends on the version and platform
|
||||
jdkForJpackageDir.traverse(type: FILES, nameFilter: jpackageBinaryFileName) {
|
||||
jdkForJpackageDir.traverse(type: groovy.io.FileType.FILES, nameFilter: jpackageBinaryFileName) {
|
||||
println 'Using jpackage binary from ' + it
|
||||
ext.jpackageFilePath = it.path
|
||||
}
|
||||
@ -168,8 +167,9 @@ task retrieveAndExtractJavaBinaries {
|
||||
task packageInstallers {
|
||||
description 'Call jpackage to prepare platform-specific binaries for this platform'
|
||||
dependsOn 'retrieveAndExtractJavaBinaries'
|
||||
// Clean all previous artefacts and create a fresh shadowJar for the installers
|
||||
// Clean all previous artifacts and create a fresh shadowJar for the installers
|
||||
dependsOn rootProject.clean
|
||||
dependsOn ':core:havenoDeps'
|
||||
dependsOn ':desktop:shadowJar'
|
||||
|
||||
doLast {
|
||||
@ -225,8 +225,8 @@ task packageInstallers {
|
||||
destfile: "${binariesFolderPath}/jar-lib-for-raspberry-pi-${appVersion}.zip")
|
||||
}
|
||||
|
||||
String appDescription = 'A decentralized bitcoin exchange network.'
|
||||
String appCopyright = '© 2021 Haveno'
|
||||
String appDescription = 'A decentralized monero exchange network.'
|
||||
String appCopyright = '© 2022 Haveno'
|
||||
String appNameAndVendor = 'Haveno'
|
||||
|
||||
String commonOpts = new String(
|
||||
@ -247,14 +247,14 @@ task packageInstallers {
|
||||
" --main-class bisq.desktop.app.HavenoAppMain" +
|
||||
" --java-options -Xss1280k" +
|
||||
" --java-options -XX:MaxRAM=4g" +
|
||||
" --java-options -Djava.net.preferIPv4Stack=true"
|
||||
" --java-options -Djava.net.preferIPv4Stack=true" +
|
||||
" --arguments --baseCurrencyNetwork=XMR_STAGENET"
|
||||
// Warning: this will cause guice reflection exceptions and lead to issues with the guice internal cache
|
||||
// resulting in the UI not loading
|
||||
// " --java-options -Djdk.module.illegalAccess=deny" +
|
||||
)
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
// TODO Found no benefit in using --resource-dir "..package/windows", it has the same outcome as opts below
|
||||
String windowsOpts = new String(
|
||||
" --icon \"${project(':desktop').projectDir}/package/windows/Haveno.ico\"" +
|
||||
" --resource-dir \"${project(':desktop').projectDir}/package/windows\"" +
|
||||
@ -277,10 +277,9 @@ task packageInstallers {
|
||||
} else {
|
||||
String linuxOpts = new String(
|
||||
" --icon ${project(':desktop').projectDir}/package/linux/icon.png" +
|
||||
|
||||
// This defines the first part of the resulting packages (the application name)
|
||||
// deb requires lowercase letters, therefore the application name is written in lowercase
|
||||
" --linux-package-name bisq" +
|
||||
" --linux-package-name haveno" +
|
||||
|
||||
// This represents the linux package version (revision)
|
||||
// By convention, this is part of the deb/rpm package names, in addition to the software version
|
||||
@ -292,7 +291,7 @@ task packageInstallers {
|
||||
|
||||
// Package deb
|
||||
executeCmd(jPackageFilePath + commonOpts + linuxOpts +
|
||||
" --linux-deb-maintainer noreply@bisq.network" +
|
||||
" --linux-deb-maintainer noreply@haveno.exchange" +
|
||||
" --type deb")
|
||||
|
||||
// Clean jpackage temp folder, needs to be empty for the next packaging step (rpm)
|
||||
@ -305,19 +304,22 @@ task packageInstallers {
|
||||
" --type rpm")
|
||||
}
|
||||
|
||||
// Env variable can be set by calling "export BISQ_SHARED_FOLDER='Some value'"
|
||||
// Env variable can be set by calling "export HAVENO_SHARED_FOLDER='Some value'"
|
||||
// This is to copy the final binary/ies to a shared folder for further processing if a VM is used.
|
||||
String envVariableSharedFolder = "$System.env.BISQ_SHARED_FOLDER"
|
||||
println "Environment variable BISQ_SHARED_FOLDER is: ${envVariableSharedFolder}"
|
||||
ant.input(message: "Copy the created binary to a shared folder? (y=yes, n=no)",
|
||||
addproperty: "copy-to-shared-folder",
|
||||
validargs: "y,n")
|
||||
if (ant.properties['copy-to-shared-folder'] == 'y') {
|
||||
copy {
|
||||
from binariesFolderPath
|
||||
into envVariableSharedFolder
|
||||
String envVariableSharedFolder = "$System.env.HAVENO_SHARED_FOLDER"
|
||||
println "Environment variable HAVENO_SHARED_FOLDER is: ${envVariableSharedFolder}"
|
||||
|
||||
if (envVariableSharedFolder != "null") {
|
||||
ant.input(message: "Copy the created binary to a shared folder? (y=yes, n=no)",
|
||||
addproperty: "copy-to-shared-folder",
|
||||
validargs: "y,n")
|
||||
if (ant.properties['copy-to-shared-folder'] == 'y') {
|
||||
copy {
|
||||
from binariesFolderPath
|
||||
into envVariableSharedFolder
|
||||
}
|
||||
executeCmd("open " + envVariableSharedFolder)
|
||||
}
|
||||
executeCmd("open " + envVariableSharedFolder)
|
||||
}
|
||||
|
||||
println "The binaries are ready:"
|
||||
|
Before Width: | Height: | Size: 55 KiB |
BIN
desktop/package/windows/Haveno.ico
Normal file
After Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 601 KiB After Width: | Height: | Size: 451 KiB |
@ -1,131 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Hashes and tag of our Monero testing binaries at https://github.com/haveno-dex/monero/releases
|
||||
MONERO_HASH_MAC="fbebd9eb40550cd992bf9e1f946741d5adc564c428b9d4c78981363235c4be89"
|
||||
MONERO_HASH_LINUX="a222bdae08e5464d1b751e6301144a904578bef37c75444c46aef762299c0b92"
|
||||
MONERO_TAG="testing8"
|
||||
# Hashes and version of bitcoin core: https://bitcoin.org/bin/
|
||||
#BTC_HASH_MAC="1ea5cedb64318e9868a66d3ab65de14516f9ada53143e460d50af428b5aec3c7"
|
||||
#BTC_HASH_LINUX="366eb44a7a0aa5bd342deea215ec19a184a11f2ca22220304ebb20b9c8917e2b"
|
||||
#BTC_VERSION=0.21.1
|
||||
|
||||
is_mac() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
is_linux() {
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
dw_source() {
|
||||
if command -v wget &> /dev/null; then
|
||||
downloader="wget"
|
||||
elif command -v curl &> /dev/null; then
|
||||
downloader="curl -L -O"
|
||||
else
|
||||
echo "! curl or wget are not installed. Please install one of the two"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${downloader} "$1"
|
||||
}
|
||||
|
||||
# Verify Monero hash
|
||||
check_monero() {
|
||||
if is_mac; then
|
||||
shasum -a 256 -c <<< ''"${MONERO_HASH_MAC}"' *monero-bins-haveno-'"${platform}"'.tar.gz' || return 1
|
||||
else
|
||||
echo "${MONERO_HASH_LINUX} monero-bins-haveno-${platform}.tar.gz" | sha256sum -c || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Verify hashes of bitcoind and bitcoin-cli
|
||||
check_bitcoin() {
|
||||
if is_mac; then
|
||||
shasum -a 256 -c <<< ''"${BTC_HASH_MAC}"' *bitcoin-'"${BTC_VERSION}"'-'"${btc_platform}"'.tar.gz' || exit 1
|
||||
else
|
||||
echo "${BTC_HASH_LINUX} bitcoin-${BTC_VERSION}-${btc_platform}.tar.gz" | sha256sum -c || exit 1
|
||||
fi
|
||||
|
||||
echo "-> Bitcoin binaries downloaded and verified"
|
||||
}
|
||||
|
||||
# Download Monero bins
|
||||
dw_monero() {
|
||||
|
||||
extract_monero() {
|
||||
echo "-> extracting monerod and monero-wallet-rpc from archive" && \
|
||||
tar -xzf "monero-bins-haveno-${platform}.tar.gz" && \
|
||||
chmod +x {monerod,monero-wallet-rpc} || exit 1
|
||||
}
|
||||
|
||||
if is_mac; then
|
||||
platform="mac"
|
||||
else
|
||||
platform="linux"
|
||||
fi
|
||||
|
||||
if [ -f "monero-bins-haveno-${platform}.tar.gz" ]; then
|
||||
if check_monero; then
|
||||
echo "-> Correct Monero archive already downloaded"
|
||||
if [ ! -f "monerod" ] || [ ! -f "monero-wallet-rpc" ]; then
|
||||
extract_monero
|
||||
fi
|
||||
else
|
||||
echo "-> Monero archive found but outdated or corrupted. Downloading it again..." && \
|
||||
rm monero-bins-haveno-${platform}.tar.gz && \
|
||||
dw_source https://github.com/haveno-dex/monero/releases/download/${MONERO_TAG}/monero-bins-haveno-${platform}.tar.gz && \
|
||||
check_monero && \
|
||||
extract_monero
|
||||
fi
|
||||
else
|
||||
dw_source https://github.com/haveno-dex/monero/releases/download/${MONERO_TAG}/monero-bins-haveno-${platform}.tar.gz && \
|
||||
check_monero && \
|
||||
extract_monero
|
||||
fi
|
||||
}
|
||||
|
||||
# Download Bitcoin bins
|
||||
dw_bitcoin() {
|
||||
if is_mac; then
|
||||
btc_platform="osx64"
|
||||
else
|
||||
btc_platform="x86_64-linux-gnu"
|
||||
fi
|
||||
|
||||
if [ -f bitcoin-${BTC_VERSION}-${btc_platform}.tar.gz ]; then
|
||||
check_bitcoin
|
||||
else
|
||||
dw_source https://bitcoin.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-${btc_platform}.tar.gz || { echo "! something went wrong while downloading the Bitcoin binaries. Exiting..."; exit 1; } && \
|
||||
check_bitcoin
|
||||
fi
|
||||
|
||||
tar -xzf bitcoin-${BTC_VERSION}-${btc_platform}.tar.gz && \
|
||||
cp bitcoin-${BTC_VERSION}/bin/{bitcoin-cli,bitcoind} . && \
|
||||
rm -r bitcoin-${BTC_VERSION} || exit 1
|
||||
}
|
||||
|
||||
while true; do
|
||||
cd .localnet
|
||||
|
||||
if ! is_linux && ! is_mac; then
|
||||
bins_deps=("monerod" "monero-wallet-rpc") # "bitcoind" "bitcoin-cli"
|
||||
|
||||
for i in ${bins_deps[@]}; do
|
||||
[ -f "$i" ] || { echo "${i} not found."; echo "Dependencies are installed automatically only on Linux and Mac. Please manually install bitcoind, bitcoin-cli, monerod, and monero-wallet-rpc executables into haveno/.localnet/ before running make."; exit 1; }
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
dw_monero
|
||||
# dw_bitcoin
|
||||
exit 0
|
||||
done
|