mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Merge branch 'master' into fix-offer-volume-jumps
This commit is contained in:
commit
4a9623bd1b
@ -179,6 +179,7 @@
|
||||
</Properties>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="RIGHT_MARGIN" value="120" />
|
||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||
<option name="BLANK_LINES_BEFORE_PACKAGE" value="1" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||
<option name="WRAP_ON_TYPING" value="0" />
|
||||
|
@ -19,6 +19,7 @@ All Bisq contributors submit changes via pull requests. The workflow is as follo
|
||||
- Fork the repository
|
||||
- Create a topic branch from the `master` branch
|
||||
- Commit patches
|
||||
- Squash redundant or unnecessary commits
|
||||
- Submit a pull request from your topic branch back to the `master` branch of the main repository
|
||||
|
||||
Pull requests should be focused on a single change. Do not mix, for example, refactorings with a bug fix or implementation of a new feature. This practice makes it easier for fellow contributors to review each pull request on its merits and and to give a clear ACK/NACK (see below).
|
||||
@ -73,6 +74,10 @@ https://help.github.com/articles/signing-commits-with-gpg/ for instructions.
|
||||
|
||||
The [.editorconfig](.editorconfig) settings in this repository ensure consistent management of whitespace, line endings and more. Most modern editors support it natively or with plugin. See http://editorconfig.org for details. See also [bisq-network/style#10](https://github.com/bisq-network/style/issues/10).
|
||||
|
||||
### Keep the git history clean
|
||||
|
||||
It's very important to keep the git history clear, light and easily browsable. This means contributors must make sure their pull requests include only meaningful commits (if they are redundant or were added after a review, they should be removed) and _no merge commits_.
|
||||
|
||||
### Additional style guidelines
|
||||
|
||||
See the issues in the [bisq-network/style](https://github.com/bisq-network/style/issues) repository.
|
||||
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.asset.coins;
|
||||
|
||||
import bisq.asset.AddressValidationResult;
|
||||
import bisq.asset.AddressValidator;
|
||||
import bisq.asset.Coin;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bitcoinj.core.Base58;
|
||||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bouncycastle.crypto.digests.Blake2bDigest;
|
||||
|
||||
public class Ergo extends Coin {
|
||||
|
||||
public Ergo() {
|
||||
super("Ergo", "ERG", new ErgoAddressValidator());
|
||||
}
|
||||
|
||||
public static class ErgoAddressValidator implements AddressValidator {
|
||||
|
||||
@Override
|
||||
public AddressValidationResult validate(String address) {
|
||||
try {
|
||||
byte[] decoded = Base58.decode(address);
|
||||
if (decoded.length < 4) {
|
||||
return AddressValidationResult.invalidAddress("Input too short: " + decoded.length);
|
||||
}
|
||||
if (decoded[0] != 1 && decoded[0] != 2 && decoded[0] != 3) {
|
||||
return AddressValidationResult.invalidAddress("Invalid prefix");
|
||||
}
|
||||
byte[] data = Arrays.copyOfRange(decoded, 0, decoded.length - 4);
|
||||
byte[] checksum = Arrays.copyOfRange(decoded, decoded.length - 4, decoded.length);
|
||||
byte[] hashed = new byte[32];
|
||||
{
|
||||
Blake2bDigest digest = new Blake2bDigest(256);
|
||||
digest.update(data, 0, data.length);
|
||||
digest.doFinal(hashed, 0);
|
||||
}
|
||||
byte[] actualChecksum = Arrays.copyOfRange(hashed, 0, 4);
|
||||
if (!Arrays.equals(checksum, actualChecksum)) {
|
||||
return AddressValidationResult.invalidAddress("Invalid checksum");
|
||||
}
|
||||
} catch (AddressFormatException e) {
|
||||
return AddressValidationResult.invalidAddress(e);
|
||||
}
|
||||
return AddressValidationResult.validAddress();
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,6 @@ import bisq.asset.CryptoNoteAddressValidator;
|
||||
public class Monero extends Coin {
|
||||
|
||||
public Monero() {
|
||||
super("Monero", "XMR", new CryptoNoteAddressValidator(18, 42));
|
||||
super("Monero", "XMR", new CryptoNoteAddressValidator(18, 19, 42));
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ bisq.asset.coins.Donu
|
||||
bisq.asset.coins.Dragonglass
|
||||
bisq.asset.coins.DSTRA
|
||||
bisq.asset.coins.Emercoin
|
||||
bisq.asset.coins.Ergo
|
||||
bisq.asset.coins.Ether
|
||||
bisq.asset.coins.EtherClassic
|
||||
bisq.asset.coins.FourtyTwo
|
||||
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.asset.coins;
|
||||
|
||||
import bisq.asset.AbstractAssetTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ErgoTest extends AbstractAssetTest {
|
||||
|
||||
public ErgoTest() {
|
||||
super(new Ergo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidAddresses() {
|
||||
assertValidAddress("9fRAWhdxEsTcdb8PhGNrZfwqa65zfkuYHAMmkQLcic1gdLSV5vA");
|
||||
assertValidAddress("25qGdVWg2yyYho8uC1pLtc7KxFn4nEEAwD");
|
||||
assertValidAddress("23NL9a8ngN28ovtLiKLgHexcdTKBbUMLhH");
|
||||
assertValidAddress("7bwdkU5V8");
|
||||
assertValidAddress("BxKBaHkvrTvLZrDcZjcsxsF7aSsrN73ijeFZXtbj4CXZHHcvBtqSxQ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidAddresses() {
|
||||
assertInvalidAddress("9fRAWhdxEsTcdb8PhGNrZfwqa65zfkuYHAMmkQLcic1gdLSV5vAaa");
|
||||
assertInvalidAddress("afRAWhdxEsTcdb8PhGNrZfwqa65zfkuYHAMmkQLcic1gdLSV5vA");
|
||||
assertInvalidAddress("25qGdVWg2yyYho8uC1pLtc7KxFn4nEEAwDaa");
|
||||
assertInvalidAddress("23NL9a8ngN28ovtLiKLgHexcdTKBbUMLhHaa");
|
||||
assertInvalidAddress("7bwdkU5V8aa");
|
||||
assertInvalidAddress("BxKBaHkvrTvLZrDcZjcsxsF7aSsrN73ijeFZXtbj4CXZHHcvBtqSxQ#");
|
||||
}
|
||||
}
|
@ -31,6 +31,11 @@ public class MoneroTest extends AbstractAssetTest {
|
||||
assertValidAddress("4BJHitCigGy6giuYsJFP26KGkTKiQDJ6HJP1pan2ir2CCV8Twc2WWmo4fu1NVXt8XLGYAkjo5cJ3yH68Lfz9ZXEUJ9MeqPW");
|
||||
assertValidAddress("46tM15KsogEW5MiVmBn7waPF8u8ZsB6aHjJk7BAv1wvMKfWhQ2h2so5BCJ9cRakfPt5BFo452oy3K8UK6L2u2v7aJ3Nf7P2");
|
||||
assertValidAddress("86iQTnEqQ9mXJFvBvbY3KU5do5Jh2NCkpTcZsw3TMZ6oKNJhELvAreZFQ1p8EknRRTKPp2vg9fJvy47Q4ARVChjLMuUAFQJ");
|
||||
|
||||
// integrated addresses
|
||||
assertValidAddress("4LL9oSLmtpccfufTMvppY6JwXNouMBzSkbLYfpAV5Usx3skxNgYeYTRj5UzqtReoS44qo9mtmXCqY45DJ852K5Jv2bYXZKKQePHES9khPK");
|
||||
assertValidAddress("4GdoN7NCTi8a5gZug7PrwZNKjvHFmKeV11L6pNJPgj5QNEHsN6eeX3DaAQFwZ1ufD4LYCZKArktt113W7QjWvQ7CWD1FFMXoYHeE6M55P9");
|
||||
assertValidAddress("4GdoN7NCTi8a5gZug7PrwZNKjvHFmKeV11L6pNJPgj5QNEHsN6eeX3DaAQFwZ1ufD4LYCZKArktt113W7QjWvQ7CW82yHFEGvSG3NJRNtH");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -60,7 +60,7 @@ configure(subprojects) {
|
||||
logbackVersion = '1.1.10'
|
||||
lombokVersion = '1.18.2'
|
||||
mockitoVersion = '3.0.0'
|
||||
netlayerVersion = '0.6.5.1'
|
||||
netlayerVersion = '0.6.5.2'
|
||||
protobufVersion = '3.9.1'
|
||||
pushyVersion = '0.13.2'
|
||||
qrgenVersion = '1.3'
|
||||
@ -158,7 +158,6 @@ configure(project(':assets')) {
|
||||
compile "com.google.guava:guava:$guavaVersion"
|
||||
compile "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
compile "org.apache.commons:commons-lang3:$langVersion"
|
||||
compile "org.bouncycastle:bcpg-jdk15on:$bcVersion"
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,9 +179,6 @@ configure(project(':common')) {
|
||||
compile "org.openjfx:javafx-graphics:11:$os"
|
||||
compile "com.google.protobuf:protobuf-java:$protobufVersion"
|
||||
compile 'com.google.code.gson:gson:2.7'
|
||||
compile("com.googlecode.json-simple:json-simple:$jsonsimpleVersion") {
|
||||
exclude(module: 'junit')
|
||||
}
|
||||
compile "org.springframework:spring-core:$springVersion"
|
||||
compile "org.slf4j:slf4j-api:$slf4jVersion"
|
||||
compile "ch.qos.logback:logback-core:$logbackVersion"
|
||||
@ -199,7 +195,6 @@ configure(project(':common')) {
|
||||
exclude(module: 'protobuf-java')
|
||||
}
|
||||
compile "org.jetbrains:annotations:$jetbrainsAnnotationsVersion"
|
||||
runtime "org.bouncycastle:bcprov-jdk15on:$bcVersion"
|
||||
compile "org.bouncycastle:bcpg-jdk15on:$bcVersion"
|
||||
compile "commons-io:commons-io:$ioVersion"
|
||||
compile "org.apache.commons:commons-lang3:$langVersion"
|
||||
@ -396,7 +391,6 @@ configure(project(':seednode')) {
|
||||
|
||||
dependencies {
|
||||
compile project(':core')
|
||||
runtime "org.bouncycastle:bcprov-jdk15on:$bcVersion"
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
testCompile "org.springframework:spring-test:$springVersion"
|
||||
|
@ -54,8 +54,7 @@ public class FrameRateTimer implements Timer, Runnable {
|
||||
stop();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
log.error(t.getMessage());
|
||||
t.printStackTrace();
|
||||
log.error("exception in FrameRateTimer", t);
|
||||
stop();
|
||||
throw t;
|
||||
}
|
||||
|
@ -93,8 +93,7 @@ public class UserThread {
|
||||
return timerClass.getDeclaredConstructor().newInstance();
|
||||
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
String message = "Could not instantiate timer bsTimerClass=" + timerClass;
|
||||
log.error(message);
|
||||
e.printStackTrace();
|
||||
log.error(message, e);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
@ -38,4 +38,3 @@ public class CryptoUtils {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,7 @@
|
||||
package bisq.common.crypto;
|
||||
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import bisq.common.util.Hex;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.KeyGenerator;
|
||||
@ -70,8 +69,7 @@ public class Encryption {
|
||||
log.trace("Generate msgEncryptionKeyPair needed {} ms", System.currentTimeMillis() - ts);
|
||||
return keyPair;
|
||||
} catch (Throwable e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
log.error("Could not create key.", e);
|
||||
throw new RuntimeException("Could not create key.");
|
||||
}
|
||||
}
|
||||
@ -87,7 +85,7 @@ public class Encryption {
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
return cipher.doFinal(payload);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
log.error("error in encrypt", e);
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
}
|
||||
@ -128,8 +126,7 @@ public class Encryption {
|
||||
outputStream.flush();
|
||||
payloadWithHmac = outputStream.toByteArray().clone();
|
||||
} catch (IOException | NoSuchProviderException e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
log.error("Could not create hmac", e);
|
||||
throw new RuntimeException("Could not create hmac");
|
||||
} finally {
|
||||
if (outputStream != null) {
|
||||
@ -140,8 +137,7 @@ public class Encryption {
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
log.error("Could not create hmac", e);
|
||||
throw new RuntimeException("Could not create hmac");
|
||||
}
|
||||
return payloadWithHmac;
|
||||
@ -153,8 +149,7 @@ public class Encryption {
|
||||
byte[] hmacTest = getHmac(message, secretKey);
|
||||
return Arrays.equals(hmacTest, hmac);
|
||||
} catch (Throwable e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
log.error("Could not create cipher", e);
|
||||
throw new RuntimeException("Could not create cipher");
|
||||
}
|
||||
}
|
||||
@ -177,7 +172,7 @@ public class Encryption {
|
||||
|
||||
public static byte[] decryptPayloadWithHmac(byte[] encryptedPayloadWithHmac, SecretKey secretKey) throws CryptoException {
|
||||
byte[] payloadWithHmac = decrypt(encryptedPayloadWithHmac, secretKey);
|
||||
String payloadWithHmacAsHex = Hex.toHexString(payloadWithHmac);
|
||||
String payloadWithHmacAsHex = Hex.encode(payloadWithHmac);
|
||||
// first part is raw message
|
||||
int length = payloadWithHmacAsHex.length();
|
||||
int sep = length - 64;
|
||||
@ -204,7 +199,7 @@ public class Encryption {
|
||||
cipher.init(Cipher.WRAP_MODE, publicKey, oaepParameterSpec);
|
||||
return cipher.wrap(secretKey);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
log.error("Couldn't encrypt payload", e);
|
||||
throw new CryptoException("Couldn't encrypt payload");
|
||||
}
|
||||
}
|
||||
@ -233,8 +228,7 @@ public class Encryption {
|
||||
keyPairGenerator.init(bits);
|
||||
return keyPairGenerator.generateKey();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
log.error("Couldn't generate key", e);
|
||||
throw new RuntimeException("Couldn't generate key");
|
||||
}
|
||||
}
|
||||
@ -252,7 +246,6 @@ public class Encryption {
|
||||
return KeyFactory.getInstance(Encryption.ASYM_KEY_ALGO).generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes));
|
||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
log.error("Error creating sigPublicKey from bytes. sigPublicKeyBytes as hex={}, error={}", Utilities.bytesAsHexString(encryptionPubKeyBytes), e);
|
||||
e.printStackTrace();
|
||||
throw new KeyConversionException(e);
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,7 @@ public class Hash {
|
||||
digest.update(data, 0, data.length);
|
||||
return digest.digest();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.error("Could not create MessageDigest for hash. " + e.toString());
|
||||
e.printStackTrace();
|
||||
log.error("Could not create MessageDigest for hash. ", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
@ -20,18 +20,12 @@ package bisq.common.crypto;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
|
||||
import java.security.KeyPair;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Getter
|
||||
@EqualsAndHashCode
|
||||
@Slf4j
|
||||
@ -41,33 +35,18 @@ public final class KeyRing {
|
||||
private final KeyPair encryptionKeyPair;
|
||||
private final PubKeyRing pubKeyRing;
|
||||
|
||||
// We generate by default a PGP keypair but the user can set his own if he prefers.
|
||||
// Not impl. yet but prepared in data structure
|
||||
@Nullable
|
||||
@Setter
|
||||
// TODO remove Nullable once impl.
|
||||
private PGPKeyPair pgpKeyPair;
|
||||
|
||||
@Inject
|
||||
public KeyRing(KeyStorage keyStorage) {
|
||||
if (keyStorage.allKeyFilesExist()) {
|
||||
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_SIGNATURE);
|
||||
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_ENCRYPTION);
|
||||
|
||||
// TODO not impl
|
||||
pgpKeyPair = keyStorage.loadPgpKeyPair(KeyStorage.KeyEntry.PGP);
|
||||
} else {
|
||||
// First time we create key pairs
|
||||
signatureKeyPair = Sig.generateKeyPair();
|
||||
encryptionKeyPair = Encryption.generateKeyPair();
|
||||
|
||||
// TODO not impl
|
||||
pgpKeyPair = PGP.generateKeyPair();
|
||||
keyStorage.saveKeyRing(this);
|
||||
}
|
||||
// TODO remove Nullable once impl.
|
||||
final PGPPublicKey pgpPublicKey = pgpKeyPair != null ? pgpKeyPair.getPublicKey() : null;
|
||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic(), pgpPublicKey);
|
||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
|
||||
}
|
||||
|
||||
// Don't print keys for security reasons
|
||||
|
@ -24,8 +24,6 @@ import com.google.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -54,8 +52,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
// TODO: use a password protection for key storage
|
||||
@Singleton
|
||||
public class KeyStorage {
|
||||
@ -65,9 +61,7 @@ public class KeyStorage {
|
||||
|
||||
public enum KeyEntry {
|
||||
MSG_SIGNATURE("sig", Sig.KEY_ALGO),
|
||||
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO),
|
||||
// TODO not impl
|
||||
PGP("pgp", null);
|
||||
MSG_ENCRYPTION("enc", Encryption.ASYM_KEY_ALGO);
|
||||
|
||||
private final String fileName;
|
||||
private final String algorithm;
|
||||
@ -111,14 +105,6 @@ public class KeyStorage {
|
||||
return new File(storageDir + "/" + keyEntry.getFileName() + ".key").exists();
|
||||
}
|
||||
|
||||
// TODO not impl
|
||||
@SuppressWarnings({"SameParameterValue", "SameReturnValue", "UnusedParameters"})
|
||||
@Nullable
|
||||
public PGPKeyPair loadPgpKeyPair(KeyEntry keyEntry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public KeyPair loadKeyPair(KeyEntry keyEntry) {
|
||||
FileUtil.rollingBackup(storageDir, keyEntry.getFileName() + ".key", 20);
|
||||
// long now = System.currentTimeMillis();
|
||||
@ -136,8 +122,7 @@ public class KeyStorage {
|
||||
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
|
||||
privateKey = keyFactory.generatePrivate(privateKeySpec);
|
||||
} catch (InvalidKeySpecException | IOException e) {
|
||||
log.error(e.getMessage());
|
||||
e.printStackTrace();
|
||||
log.error("Could not load key " + keyEntry.toString(), e.getMessage());
|
||||
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);
|
||||
}
|
||||
|
||||
@ -161,8 +146,7 @@ public class KeyStorage {
|
||||
log.debug("load completed in {} msec", System.currentTimeMillis() - new Date().getTime());
|
||||
return new KeyPair(publicKey, privateKey);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
log.error("Could not load key " + keyEntry.toString(), e);
|
||||
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);
|
||||
}
|
||||
}
|
||||
@ -181,8 +165,7 @@ public class KeyStorage {
|
||||
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + ".key")) {
|
||||
fos.write(pkcs8EncodedKeySpec.getEncoded());
|
||||
} catch (IOException e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
log.error("Could not save key " + name, e);
|
||||
throw new RuntimeException("Could not save key " + name, e);
|
||||
}
|
||||
}
|
||||
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.common.crypto;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import org.bouncycastle.bcpg.BCPGKey;
|
||||
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPKeyPair;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPUtil;
|
||||
import org.bouncycastle.openpgp.jcajce.JcaPGPPublicKeyRingCollection;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings("UnusedAssignment")
|
||||
@Slf4j
|
||||
public class PGP {
|
||||
|
||||
// TODO not tested yet, remove Nullable once impl.
|
||||
// PEM encoding
|
||||
@Nullable
|
||||
public static PGPPublicKey getPubKeyFromPem(@Nullable String pem) {
|
||||
if (pem != null) {
|
||||
InputStream inputStream = new ByteArrayInputStream(pem.getBytes(Charsets.UTF_8));
|
||||
try {
|
||||
inputStream = PGPUtil.getDecoderStream(inputStream);
|
||||
try {
|
||||
JcaPGPPublicKeyRingCollection ringCollection = new JcaPGPPublicKeyRingCollection(inputStream);
|
||||
Iterator<PGPPublicKeyRing> keyRingsIterator = ringCollection.getKeyRings();
|
||||
while (keyRingsIterator.hasNext()) {
|
||||
PGPPublicKeyRing pgpPublicKeyRing = keyRingsIterator.next();
|
||||
Iterator<PGPPublicKey> pubKeysIterator = pgpPublicKeyRing.getPublicKeys();
|
||||
while (pubKeysIterator.hasNext()) {
|
||||
final PGPPublicKey pgpPublicKey = pubKeysIterator.next();
|
||||
if ((pgpPublicKey).isEncryptionKey()) {
|
||||
log.debug(pgpPublicKey.getClass().getName()
|
||||
+ " KeyID: " + Long.toHexString(pgpPublicKey.getKeyID())
|
||||
+ " type: " + pgpPublicKey.getAlgorithm()
|
||||
+ " fingerprint: " + new String(Hex.encode(pgpPublicKey.getFingerprint())));
|
||||
|
||||
BCPGKey bcKey = pgpPublicKey.getPublicKeyPacket().getKey();
|
||||
log.debug(bcKey.getClass().getName());
|
||||
if (bcKey instanceof RSAPublicBCPGKey) {
|
||||
RSAPublicBCPGKey bcRSA = (RSAPublicBCPGKey) bcKey;
|
||||
RSAPublicKeySpec specRSA = new RSAPublicKeySpec(bcRSA.getModulus(), bcRSA.getPublicExponent());
|
||||
PublicKey jceKey = KeyFactory.getInstance("RSA").generatePublic(specRSA);
|
||||
// if you want to use the key in JCE, use jceKey
|
||||
// if you want to write "X.509" (SPKI) DER format to a file:
|
||||
//Files.write(new File(pubKeyAsString).toPath(), jceKey.getEncoded());
|
||||
// if you want to write in PEM, bouncycastle can do that
|
||||
// or you can just do base64 and add BEGIN/END lines
|
||||
// return pubKeyAsString; // assume only one key; if need to handle multiple keys
|
||||
// or select other than the first, specify more clearly
|
||||
}
|
||||
|
||||
return pgpPublicKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} catch (PGPException | InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
log.error("Error creating publicKey from pem. pem={}, error={}", pem, e);
|
||||
e.printStackTrace();
|
||||
throw new KeyConversionException(e);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Error creating publicKey from pem. pem={}, error={}", pem, e);
|
||||
e.printStackTrace();
|
||||
throw new KeyConversionException(e);
|
||||
} finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.warn("Error creating publicKey from pem. pem=null");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO not impl, remove Nullable once impl.
|
||||
// PEM encoding
|
||||
@SuppressWarnings({"SameReturnValue", "UnusedParameters"})
|
||||
@NotNull
|
||||
public static String getPEMFromPubKey(@Nullable PGPPublicKey pgpPubKey) {
|
||||
// We use empty string as we must not have null in proto file
|
||||
return "";
|
||||
}
|
||||
|
||||
// TODO not impl, remove Nullable once impl.
|
||||
@SuppressWarnings("SameReturnValue")
|
||||
@Nullable
|
||||
public static PGPKeyPair generateKeyPair() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -25,16 +25,12 @@ import com.google.protobuf.ByteString;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Same as KeyRing but with public keys only.
|
||||
* Used to send public keys over the wire to other peer.
|
||||
@ -45,22 +41,15 @@ import javax.annotation.Nullable;
|
||||
public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJson {
|
||||
private final byte[] signaturePubKeyBytes;
|
||||
private final byte[] encryptionPubKeyBytes;
|
||||
@Nullable
|
||||
private final String pgpPubKeyAsPem;
|
||||
|
||||
private transient PublicKey signaturePubKey;
|
||||
private transient PublicKey encryptionPubKey;
|
||||
@Nullable
|
||||
private transient PGPPublicKey pgpPubKey;
|
||||
|
||||
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey, @Nullable PGPPublicKey pgpPubKey) {
|
||||
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey) {
|
||||
this.signaturePubKeyBytes = Sig.getPublicKeyBytes(signaturePubKey);
|
||||
this.encryptionPubKeyBytes = Encryption.getPublicKeyBytes(encryptionPubKey);
|
||||
this.pgpPubKeyAsPem = PGP.getPEMFromPubKey(pgpPubKey);
|
||||
|
||||
this.signaturePubKey = signaturePubKey;
|
||||
this.encryptionPubKey = encryptionPubKey;
|
||||
this.pgpPubKey = pgpPubKey;
|
||||
}
|
||||
|
||||
|
||||
@ -69,15 +58,11 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@VisibleForTesting
|
||||
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes, @Nullable String pgpPubKeyAsPem) {
|
||||
public PubKeyRing(byte[] signaturePubKeyBytes, byte[] encryptionPubKeyBytes) {
|
||||
this.signaturePubKeyBytes = signaturePubKeyBytes;
|
||||
this.encryptionPubKeyBytes = encryptionPubKeyBytes;
|
||||
this.pgpPubKeyAsPem = pgpPubKeyAsPem;
|
||||
|
||||
signaturePubKey = Sig.getPublicKeyFromBytes(signaturePubKeyBytes);
|
||||
encryptionPubKey = Encryption.getPublicKeyFromBytes(encryptionPubKeyBytes);
|
||||
if (pgpPubKeyAsPem != null)
|
||||
pgpPubKey = PGP.getPubKeyFromPem(pgpPubKeyAsPem);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -85,14 +70,13 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
|
||||
return protobuf.PubKeyRing.newBuilder()
|
||||
.setSignaturePubKeyBytes(ByteString.copyFrom(signaturePubKeyBytes))
|
||||
.setEncryptionPubKeyBytes(ByteString.copyFrom(encryptionPubKeyBytes))
|
||||
.setPgpPubKeyAsPem(pgpPubKeyAsPem)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static PubKeyRing fromProto(protobuf.PubKeyRing proto) {
|
||||
return new PubKeyRing(proto.getSignaturePubKeyBytes().toByteArray(),
|
||||
proto.getEncryptionPubKeyBytes().toByteArray(),
|
||||
proto.getPgpPubKeyAsPem());
|
||||
return new PubKeyRing(
|
||||
proto.getSignaturePubKeyBytes().toByteArray(),
|
||||
proto.getEncryptionPubKeyBytes().toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,7 +84,6 @@ public final class PubKeyRing implements NetworkPayload, UsedForTradeContractJso
|
||||
return "PubKeyRing{" +
|
||||
"signaturePubKeyHex=" + Utilities.bytesAsHexString(signaturePubKeyBytes) +
|
||||
", encryptionPubKeyHex=" + Utilities.bytesAsHexString(encryptionPubKeyBytes) +
|
||||
", pgpPubKeyAsString=" + pgpPubKeyAsPem +
|
||||
'}';
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
@ -18,11 +18,10 @@
|
||||
package bisq.common.crypto;
|
||||
|
||||
import bisq.common.util.Utilities;
|
||||
import bisq.common.util.Base64;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
@ -65,8 +64,7 @@ public class Sig {
|
||||
log.trace("Generate msgSignatureKeyPair needed {} ms", System.currentTimeMillis() - ts);
|
||||
return keyPair;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.toString());
|
||||
log.error("Could not create key.", e);
|
||||
throw new RuntimeException("Could not create key.");
|
||||
}
|
||||
}
|
||||
@ -95,7 +93,7 @@ public class Sig {
|
||||
*/
|
||||
public static String sign(PrivateKey privateKey, String message) throws CryptoException {
|
||||
byte[] sigAsBytes = sign(privateKey, message.getBytes(Charsets.UTF_8));
|
||||
return Base64.toBase64String(sigAsBytes);
|
||||
return Base64.encode(sigAsBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,4 +141,3 @@ public class Sig {
|
||||
return new X509EncodedKeySpec(sigPublicKey.getEncoded()).getEncoded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,14 +20,9 @@ package bisq.common.storage;
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.util.Utilities;
|
||||
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@ -102,15 +97,4 @@ public class JsonFileManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Object readJsonFromDisc(String fileName) {
|
||||
final File jsonFile = new File(Paths.get(dir.getAbsolutePath(), fileName + ".json").toString());
|
||||
JSONParser parser = new JSONParser();
|
||||
try {
|
||||
return parser.parse(new FileReader(jsonFile));
|
||||
} catch (ParseException | IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
33
common/src/main/java/bisq/common/util/Base64.java
Normal file
33
common/src/main/java/bisq/common/util/Base64.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.common.util;
|
||||
|
||||
/**
|
||||
* We use Java 8 builtin Base64 because it is much faster than Guava and Apache versions:
|
||||
* http://java-performance.info/base64-encoding-and-decoding-performance/
|
||||
*/
|
||||
public class Base64 {
|
||||
|
||||
public static byte[] decode(String base64) {
|
||||
return java.util.Base64.getDecoder().decode(base64);
|
||||
}
|
||||
|
||||
public static String encode(byte[] bytes) {
|
||||
return java.util.Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
}
|
31
common/src/main/java/bisq/common/util/Hex.java
Normal file
31
common/src/main/java/bisq/common/util/Hex.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.common.util;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
|
||||
public class Hex {
|
||||
|
||||
public static byte[] decode(String hex) {
|
||||
return BaseEncoding.base16().lowerCase().decode(hex.toLowerCase());
|
||||
}
|
||||
|
||||
public static String encode(byte[] bytes) {
|
||||
return BaseEncoding.base16().lowerCase().encode(bytes);
|
||||
}
|
||||
}
|
@ -410,7 +410,7 @@ message Peer {
|
||||
message PubKeyRing {
|
||||
bytes signature_pub_key_bytes = 1;
|
||||
bytes encryption_pub_key_bytes = 2;
|
||||
string pgp_pub_key_as_pem = 3;
|
||||
reserved 3; // WAS: string pgp_pub_key_as_pem = 3;
|
||||
}
|
||||
|
||||
message SealedAndSigned {
|
||||
@ -805,6 +805,7 @@ message PaymentAccountPayload {
|
||||
PromptPayAccountPayload prompt_pay_account_payload = 25;
|
||||
AdvancedCashAccountPayload advanced_cash_account_payload = 26;
|
||||
InstantCryptoCurrencyAccountPayload instant_crypto_currency_account_payload = 27;
|
||||
JapanBankAccountPayload japan_bank_account_payload = 28;
|
||||
}
|
||||
map<string, string> exclude_from_json_data = 15;
|
||||
}
|
||||
@ -862,6 +863,16 @@ message NationalBankAccountPayload {
|
||||
message SameBankAccountPayload {
|
||||
}
|
||||
|
||||
message JapanBankAccountPayload {
|
||||
string bank_name = 1;
|
||||
string bank_code = 2;
|
||||
string bank_branch_name = 3;
|
||||
string bank_branch_code = 4;
|
||||
string bank_account_type = 5;
|
||||
string bank_account_name = 6;
|
||||
string bank_account_number = 7;
|
||||
}
|
||||
|
||||
message SpecificBanksAccountPayload {
|
||||
repeated string accepted_banks = 1;
|
||||
}
|
||||
|
@ -70,9 +70,7 @@ public class AvoidStandbyModeService {
|
||||
private void start() {
|
||||
isStopped = false;
|
||||
log.info("AvoidStandbyModeService started");
|
||||
Thread thread = new Thread(this::play);
|
||||
thread.setName("AvoidStandbyModeService-thread");
|
||||
thread.start();
|
||||
new Thread(this::play, "AvoidStandbyModeService-thread").start();
|
||||
}
|
||||
|
||||
|
||||
|
@ -434,11 +434,8 @@ public class BisqSetup {
|
||||
bisqEnvironment.getIgnoreLocalBtcNode()) {
|
||||
step3();
|
||||
} else {
|
||||
Thread checkIfLocalHostNodeIsRunningThread = new Thread(() -> {
|
||||
Thread.currentThread().setName("checkIfLocalHostNodeIsRunningThread");
|
||||
Socket socket = null;
|
||||
try {
|
||||
socket = new Socket();
|
||||
new Thread(() -> {
|
||||
try (Socket socket = new Socket()) {
|
||||
socket.connect(new InetSocketAddress(InetAddresses.forString("127.0.0.1"),
|
||||
BisqEnvironment.getBaseCurrencyNetwork().getParameters().getPort()), 5000);
|
||||
log.info("Localhost Bitcoin node detected.");
|
||||
@ -448,16 +445,8 @@ public class BisqSetup {
|
||||
});
|
||||
} catch (Throwable e) {
|
||||
UserThread.execute(BisqSetup.this::step3);
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
try {
|
||||
socket.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
checkIfLocalHostNodeIsRunningThread.start();
|
||||
}, "checkIfLocalHostNodeIsRunningThread").start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,9 +463,8 @@ public class BisqSetup {
|
||||
// If users compile themselves they might miss that step and then would get an exception in the trade.
|
||||
// To avoid that we add here at startup a sample encryption and signing to see if it don't causes an exception.
|
||||
// See: https://github.com/bisq-network/exchange/blob/master/doc/build.md#7-enable-unlimited-strength-for-cryptographic-keys
|
||||
Thread checkCryptoThread = new Thread(() -> {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.currentThread().setName("checkCryptoThread");
|
||||
// just use any simple dummy msg
|
||||
Ping payload = new Ping(1, 1);
|
||||
SealedAndSigned sealedAndSigned = EncryptionService.encryptHybridWithSignature(payload,
|
||||
@ -496,8 +484,7 @@ public class BisqSetup {
|
||||
if (cryptoSetupFailedHandler != null)
|
||||
cryptoSetupFailedHandler.accept(msg);
|
||||
}
|
||||
});
|
||||
checkCryptoThread.start();
|
||||
}, "checkCryptoThread").start();
|
||||
}
|
||||
|
||||
private void startP2pNetworkAndWallet() {
|
||||
|
@ -49,40 +49,35 @@ public class SetupUtils {
|
||||
// If users compile themselves they might miss that step and then would get an exception in the trade.
|
||||
// To avoid that we add here at startup a sample encryption and signing to see if it don't causes an exception.
|
||||
// See: https://github.com/bisq-network/exchange/blob/master/doc/build.md#7-enable-unlimited-strength-for-cryptographic-keys
|
||||
Thread checkCryptoThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.currentThread().setName("checkCryptoThread");
|
||||
// just use any simple dummy msg
|
||||
Ping payload = new Ping(1, 1);
|
||||
SealedAndSigned sealedAndSigned = EncryptionService.encryptHybridWithSignature(payload,
|
||||
keyRing.getSignatureKeyPair(), keyRing.getPubKeyRing().getEncryptionPubKey());
|
||||
DecryptedDataTuple tuple = encryptionService.decryptHybridWithSignature(sealedAndSigned,
|
||||
keyRing.getEncryptionKeyPair().getPrivate());
|
||||
if (tuple.getNetworkEnvelope() instanceof Ping &&
|
||||
((Ping) tuple.getNetworkEnvelope()).getNonce() == payload.getNonce() &&
|
||||
((Ping) tuple.getNetworkEnvelope()).getLastRoundTripTime() == payload.getLastRoundTripTime()) {
|
||||
log.debug("Crypto test succeeded");
|
||||
Thread checkCryptoThread = new Thread(() -> {
|
||||
try {
|
||||
// just use any simple dummy msg
|
||||
Ping payload = new Ping(1, 1);
|
||||
SealedAndSigned sealedAndSigned = EncryptionService.encryptHybridWithSignature(payload,
|
||||
keyRing.getSignatureKeyPair(), keyRing.getPubKeyRing().getEncryptionPubKey());
|
||||
DecryptedDataTuple tuple = encryptionService.decryptHybridWithSignature(sealedAndSigned,
|
||||
keyRing.getEncryptionKeyPair().getPrivate());
|
||||
if (tuple.getNetworkEnvelope() instanceof Ping &&
|
||||
((Ping) tuple.getNetworkEnvelope()).getNonce() == payload.getNonce() &&
|
||||
((Ping) tuple.getNetworkEnvelope()).getLastRoundTripTime() == payload.getLastRoundTripTime()) {
|
||||
log.debug("Crypto test succeeded");
|
||||
|
||||
UserThread.execute(resultHandler::handleResult);
|
||||
} else {
|
||||
errorHandler.accept(new CryptoException("Payload not correct after decryption"));
|
||||
}
|
||||
} catch (CryptoException | ProtobufferException e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
errorHandler.accept(e);
|
||||
UserThread.execute(resultHandler::handleResult);
|
||||
} else {
|
||||
errorHandler.accept(new CryptoException("Payload not correct after decryption"));
|
||||
}
|
||||
} catch (CryptoException | ProtobufferException e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
errorHandler.accept(e);
|
||||
}
|
||||
};
|
||||
}, "checkCryptoThread");
|
||||
checkCryptoThread.start();
|
||||
}
|
||||
|
||||
public static BooleanProperty readFromResources(P2PDataStorage p2PDataStorage) {
|
||||
BooleanProperty result = new SimpleBooleanProperty();
|
||||
Thread thread = new Thread(() -> {
|
||||
Thread.currentThread().setName("readFromResourcesThread");
|
||||
new Thread(() -> {
|
||||
// Used to load different files per base currency (EntryMap_BTC_MAINNET, EntryMap_LTC,...)
|
||||
final BaseCurrencyNetwork baseCurrencyNetwork = BisqEnvironment.getBaseCurrencyNetwork();
|
||||
final String postFix = "_" + baseCurrencyNetwork.name();
|
||||
@ -90,8 +85,7 @@ public class SetupUtils {
|
||||
p2PDataStorage.readFromResources(postFix);
|
||||
log.info("readFromResources took {} ms", (new Date().getTime() - ts));
|
||||
UserThread.execute(() -> result.set(true));
|
||||
});
|
||||
thread.start();
|
||||
}, "readFromResourcesThread").start();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public class WalletAppSetup {
|
||||
result = Res.get("mainView.footer.btcInfo",
|
||||
peers,
|
||||
Res.get("mainView.footer.btcInfo.synchronizingWith"),
|
||||
getBtcNetworkAsString() + ": " + formatter.formatToPercentWithSymbol(percentage));
|
||||
getBtcNetworkAsString() + ": " + BSFormatter.formatToPercentWithSymbol(percentage));
|
||||
} else {
|
||||
result = Res.get("mainView.footer.btcInfo",
|
||||
peers,
|
||||
|
@ -561,13 +561,12 @@ public class WalletConfig extends AbstractIdleService {
|
||||
|
||||
private void installShutdownHook() {
|
||||
if (autoStop) Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
Thread.currentThread().setName("ShutdownHook");
|
||||
try {
|
||||
WalletConfig.this.stopAsync();
|
||||
WalletConfig.this.awaitTerminated();
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
}));
|
||||
}, "WalletConfig ShutdownHook"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -180,9 +180,9 @@ public class TradeWalletService {
|
||||
boolean doBroadcast,
|
||||
@Nullable TxBroadcaster.Callback callback)
|
||||
throws InsufficientMoneyException, AddressFormatException {
|
||||
log.debug("fundingAddress {}", fundingAddress.toString());
|
||||
log.debug("reservedForTradeAddress {}", reservedForTradeAddress.toString());
|
||||
log.debug("changeAddress {}", changeAddress.toString());
|
||||
log.debug("fundingAddress {}", fundingAddress);
|
||||
log.debug("reservedForTradeAddress {}", reservedForTradeAddress);
|
||||
log.debug("changeAddress {}", changeAddress);
|
||||
log.info("reservedFundsForOffer {}", reservedFundsForOffer.toPlainString());
|
||||
log.debug("useSavingsWallet {}", useSavingsWallet);
|
||||
log.info("tradingFee {}", tradingFee.toPlainString());
|
||||
@ -245,9 +245,9 @@ public class TradeWalletService {
|
||||
TransactionVerificationException, WalletException,
|
||||
InsufficientMoneyException, AddressFormatException {
|
||||
|
||||
log.debug("preparedBsqTx {}", preparedBsqTx.toString());
|
||||
log.debug("fundingAddress {}", fundingAddress.toString());
|
||||
log.debug("changeAddress {}", changeAddress.toString());
|
||||
log.debug("preparedBsqTx {}", preparedBsqTx);
|
||||
log.debug("fundingAddress {}", fundingAddress);
|
||||
log.debug("changeAddress {}", changeAddress);
|
||||
log.debug("reservedFundsForOffer {}", reservedFundsForOffer.toPlainString());
|
||||
log.debug("useSavingsWallet {}", useSavingsWallet);
|
||||
log.debug("txFee {}", txFee.toPlainString());
|
||||
@ -343,10 +343,12 @@ public class TradeWalletService {
|
||||
*/
|
||||
public InputsAndChangeOutput takerCreatesDepositsTxInputs(Transaction takeOfferFeeTx, Coin inputAmount, Coin txFee, Address takersAddress) throws
|
||||
TransactionVerificationException {
|
||||
log.debug("takerCreatesDepositsTxInputs called");
|
||||
log.debug("inputAmount {}", inputAmount.toFriendlyString());
|
||||
log.debug("txFee {}", txFee.toFriendlyString());
|
||||
log.debug("takersAddress {}", takersAddress.toString());
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("takerCreatesDepositsTxInputs called");
|
||||
log.debug("inputAmount {}", inputAmount.toFriendlyString());
|
||||
log.debug("txFee {}", txFee.toFriendlyString());
|
||||
log.debug("takersAddress {}", takersAddress.toString());
|
||||
}
|
||||
|
||||
// We add the mining fee 2 times to the deposit tx:
|
||||
// 1. Will be spent when publishing the deposit tx (paid by buyer)
|
||||
@ -445,9 +447,9 @@ public class TradeWalletService {
|
||||
log.debug("takerChangeAddressString {}", takerChangeAddressString);
|
||||
log.debug("makerAddress {}", makerAddress);
|
||||
log.debug("makerChangeAddress {}", makerChangeAddress);
|
||||
log.debug("buyerPubKey {}", ECKey.fromPublicOnly(buyerPubKey).toString());
|
||||
log.debug("sellerPubKey {}", ECKey.fromPublicOnly(sellerPubKey).toString());
|
||||
log.debug("arbitratorPubKey {}", ECKey.fromPublicOnly(arbitratorPubKey).toString());
|
||||
log.debug("buyerPubKey {}", ECKey.fromPublicOnly(buyerPubKey));
|
||||
log.debug("sellerPubKey {}", ECKey.fromPublicOnly(sellerPubKey));
|
||||
log.debug("arbitratorPubKey {}", ECKey.fromPublicOnly(arbitratorPubKey));
|
||||
|
||||
checkArgument(!takerRawTransactionInputs.isEmpty());
|
||||
|
||||
|
@ -40,8 +40,8 @@ public class DaoUtil {
|
||||
long now = new Date().getTime();
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd MMM", Locale.getDefault());
|
||||
SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm", Locale.getDefault());
|
||||
String startDateTime = formatter.formatDateTime(new Date(now + (start - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String endDateTime = formatter.formatDateTime(new Date(now + (end - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String startDateTime = BSFormatter.formatDateTime(new Date(now + (start - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String endDateTime = BSFormatter.formatDateTime(new Date(now + (end - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
|
||||
return Res.get("dao.cycle.phaseDurationWithoutBlocks", start, end, startDateTime, endDateTime);
|
||||
}
|
||||
@ -53,9 +53,9 @@ public class DaoUtil {
|
||||
long now = new Date().getTime();
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("dd MMM", Locale.getDefault());
|
||||
SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm", Locale.getDefault());
|
||||
String startDateTime = formatter.formatDateTime(new Date(now + (start - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String endDateTime = formatter.formatDateTime(new Date(now + (end - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String durationTime = formatter.formatDurationAsWords(duration * 10 * 60 * 1000, false, false);
|
||||
String startDateTime = BSFormatter.formatDateTime(new Date(now + (start - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String endDateTime = BSFormatter.formatDateTime(new Date(now + (end - height) * 10 * 60 * 1000L), dateFormatter, timeFormatter);
|
||||
String durationTime = BSFormatter.formatDurationAsWords(duration * 10 * 60 * 1000, false, false);
|
||||
return Res.get("dao.cycle.phaseDuration", duration, durationTime, start, end, startDateTime, endDateTime);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import bisq.core.dao.state.model.governance.Issuance;
|
||||
import bisq.core.dao.state.model.governance.IssuanceType;
|
||||
import bisq.core.dao.state.model.governance.ParamChange;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
|
||||
@ -923,7 +924,7 @@ public class DaoStateService implements DaoSetupService {
|
||||
}
|
||||
|
||||
public double getParamValueAsPercentDouble(String paramValue) {
|
||||
return bsqFormatter.parsePercentStringToDouble(paramValue);
|
||||
return ParsingUtils.parsePercentStringToDouble(paramValue);
|
||||
}
|
||||
|
||||
public int getParamValueAsBlock(String paramValue) {
|
||||
|
@ -34,6 +34,7 @@ public class LanguageUtil {
|
||||
"el", // Greek
|
||||
"es", // Spanish
|
||||
"pt", // Portuguese
|
||||
"pt_BR", // Brazilian Portuguese
|
||||
"zh", // Chinese
|
||||
"ru", // Russian
|
||||
"fr", // French
|
||||
@ -118,6 +119,8 @@ public class LanguageUtil {
|
||||
// Serbia
|
||||
// shows it in russian by default
|
||||
return "Srpski";
|
||||
} else if (locale.getLanguage().equals("pt_br")) {
|
||||
return "português (Brasil)";
|
||||
} else {
|
||||
return locale.getDisplayName(locale);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
package bisq.core.monetary;
|
||||
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import org.bitcoinj.core.Monetary;
|
||||
import org.bitcoinj.utils.MonetaryFormat;
|
||||
@ -89,7 +89,7 @@ public final class Altcoin implements Monetary, Comparable<Altcoin> {
|
||||
* @throws IllegalArgumentException if you try to specify fractional satoshis, or a value out of range.
|
||||
*/
|
||||
public static Altcoin parseAltcoin(final String currencyCode, String input) {
|
||||
String cleaned = BSFormatter.convertCharsForNumber(input);
|
||||
String cleaned = ParsingUtils.convertCharsForNumber(input);
|
||||
try {
|
||||
long val = new BigDecimal(cleaned).movePointRight(SMALLEST_UNIT_EXPONENT)
|
||||
.toBigIntegerExact().longValue();
|
||||
|
@ -18,7 +18,7 @@
|
||||
package bisq.core.monetary;
|
||||
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Monetary;
|
||||
@ -58,7 +58,7 @@ public class Price extends MonetaryWrapper implements Comparable<Price> {
|
||||
* @return The parsed Price.
|
||||
*/
|
||||
public static Price parse(String currencyCode, String input) {
|
||||
String cleaned = BSFormatter.convertCharsForNumber(input);
|
||||
String cleaned = ParsingUtils.convertCharsForNumber(input);
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return new Price(Fiat.parseFiat(currencyCode, cleaned));
|
||||
else
|
||||
|
@ -18,7 +18,7 @@
|
||||
package bisq.core.monetary;
|
||||
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import org.bitcoinj.core.Monetary;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
@ -36,7 +36,7 @@ public class Volume extends MonetaryWrapper implements Comparable<Volume> {
|
||||
}
|
||||
|
||||
public static Volume parse(String input, String currencyCode) {
|
||||
String cleaned = BSFormatter.convertCharsForNumber(input);
|
||||
String cleaned = ParsingUtils.convertCharsForNumber(input);
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return new Volume(Fiat.parseFiat(currencyCode, cleaned));
|
||||
else
|
||||
|
@ -180,9 +180,9 @@ public class MarketAlerts {
|
||||
ratio = Math.abs(ratio);
|
||||
String msg = Res.get("account.notifications.marketAlert.message.msg",
|
||||
direction,
|
||||
formatter.getCurrencyPair(currencyCode),
|
||||
formatter.formatPrice(offerPrice),
|
||||
formatter.formatToPercentWithSymbol(ratio / 10000d),
|
||||
BSFormatter.getCurrencyPair(currencyCode),
|
||||
BSFormatter.formatPrice(offerPrice),
|
||||
BSFormatter.formatToPercentWithSymbol(ratio / 10000d),
|
||||
marketDir,
|
||||
Res.get(offer.getPaymentMethod().getId()),
|
||||
shortOfferId);
|
||||
|
@ -70,8 +70,8 @@ public class PriceAlert {
|
||||
if (priceAsLong > filter.getHigh() || priceAsLong < filter.getLow()) {
|
||||
String msg = Res.get("account.notifications.priceAlert.message.msg",
|
||||
currencyName,
|
||||
formatter.formatMarketPrice(priceAsDouble, currencyCode),
|
||||
formatter.getCurrencyPair(currencyCode));
|
||||
BSFormatter.formatMarketPrice(priceAsDouble, currencyCode),
|
||||
BSFormatter.getCurrencyPair(currencyCode));
|
||||
MobileMessage message = new MobileMessage(Res.get("account.notifications.priceAlert.message.title", currencyName),
|
||||
msg,
|
||||
MobileMessageType.PRICE);
|
||||
|
@ -306,17 +306,6 @@ public class OfferUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getFeeWithFiatAmount(Coin makerFeeAsCoin, Optional<Volume> optionalFeeInFiat, BSFormatter formatter) {
|
||||
String fee = makerFeeAsCoin != null ? formatter.formatCoinWithCode(makerFeeAsCoin) : Res.get("shared.na");
|
||||
String feeInFiatAsString;
|
||||
if (optionalFeeInFiat != null && optionalFeeInFiat.isPresent()) {
|
||||
feeInFiatAsString = formatter.formatVolumeWithCode(optionalFeeInFiat.get());
|
||||
} else {
|
||||
feeInFiatAsString = Res.get("shared.na");
|
||||
}
|
||||
return Res.get("feeOptionWindow.fee", fee, feeInFiatAsString);
|
||||
}
|
||||
|
||||
|
||||
public static Map<String, String> getExtraDataMap(AccountAgeWitnessService accountAgeWitnessService,
|
||||
ReferralIdService referralIdService,
|
||||
|
124
core/src/main/java/bisq/core/payment/JapanBankAccount.java
Normal file
124
core/src/main/java/bisq/core/payment/JapanBankAccount.java
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.core.payment;
|
||||
|
||||
import bisq.core.payment.payload.JapanBankAccountPayload;
|
||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
||||
import bisq.core.payment.payload.PaymentMethod;
|
||||
import bisq.core.payment.payload.JapanBankAccountPayload;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import bisq.core.locale.Country;
|
||||
import bisq.core.locale.FiatCurrency;
|
||||
import bisq.core.payment.payload.JapanBankAccountPayload;
|
||||
|
||||
public final class JapanBankAccount extends PaymentAccount
|
||||
{
|
||||
public JapanBankAccount()
|
||||
{
|
||||
super(PaymentMethod.JAPAN_BANK);
|
||||
setSingleTradeCurrency(new FiatCurrency("JPY"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PaymentAccountPayload createPayload()
|
||||
{
|
||||
return new JapanBankAccountPayload(paymentMethod.getId(), id);
|
||||
}
|
||||
|
||||
// bank code
|
||||
public String getBankCode()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankCode();
|
||||
}
|
||||
public void setBankCode(String bankCode)
|
||||
{
|
||||
if (bankCode == null) bankCode = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankCode(bankCode);
|
||||
}
|
||||
|
||||
// bank name
|
||||
public String getBankName()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankName();
|
||||
}
|
||||
public void setBankName(String bankName)
|
||||
{
|
||||
if (bankName == null) bankName = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankName(bankName);
|
||||
}
|
||||
|
||||
// branch code
|
||||
public String getBankBranchCode()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankBranchCode();
|
||||
}
|
||||
public void setBankBranchCode(String bankBranchCode)
|
||||
{
|
||||
if (bankBranchCode == null) bankBranchCode = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankBranchCode(bankBranchCode);
|
||||
}
|
||||
|
||||
// branch name
|
||||
public String getBankBranchName()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankBranchName();
|
||||
}
|
||||
public void setBankBranchName(String bankBranchName)
|
||||
{
|
||||
if (bankBranchName == null) bankBranchName = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankBranchName(bankBranchName);
|
||||
}
|
||||
|
||||
// account type
|
||||
public String getBankAccountType()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankAccountType();
|
||||
}
|
||||
public void setBankAccountType(String bankAccountType)
|
||||
{
|
||||
if (bankAccountType == null) bankAccountType = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankAccountType(bankAccountType);
|
||||
}
|
||||
|
||||
// account number
|
||||
public String getBankAccountNumber()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankAccountNumber();
|
||||
}
|
||||
public void setBankAccountNumber(String bankAccountNumber)
|
||||
{
|
||||
if (bankAccountNumber == null) bankAccountNumber = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankAccountNumber(bankAccountNumber);
|
||||
}
|
||||
|
||||
// account name
|
||||
public String getBankAccountName()
|
||||
{
|
||||
return ((JapanBankAccountPayload) paymentAccountPayload).getBankAccountName();
|
||||
}
|
||||
public void setBankAccountName(String bankAccountName)
|
||||
{
|
||||
if (bankAccountName == null) bankAccountName = "";
|
||||
((JapanBankAccountPayload) paymentAccountPayload).setBankAccountName(bankAccountName);
|
||||
}
|
||||
}
|
@ -44,6 +44,8 @@ public class PaymentAccountFactory {
|
||||
return new SameBankAccount();
|
||||
case PaymentMethod.SPECIFIC_BANKS_ID:
|
||||
return new SpecificBanksAccount();
|
||||
case PaymentMethod.JAPAN_BANK_ID:
|
||||
return new JapanBankAccount();
|
||||
case PaymentMethod.ALI_PAY_ID:
|
||||
return new AliPayAccount();
|
||||
case PaymentMethod.WECHAT_PAY_ID:
|
||||
|
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.core.payment.payload;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
// Cannot be deleted as it would break old trade history entries
|
||||
// Removed due too high chargeback risk
|
||||
@Deprecated
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
public final class JapanBankAccountPayload extends PaymentAccountPayload {
|
||||
// bank
|
||||
private String bankName = "";
|
||||
private String bankCode = "";
|
||||
// branch
|
||||
private String bankBranchName = "";
|
||||
private String bankBranchCode = "";
|
||||
// account
|
||||
private String bankAccountType = "";
|
||||
private String bankAccountName = "";
|
||||
private String bankAccountNumber = "";
|
||||
|
||||
public JapanBankAccountPayload(String paymentMethod, String id) {
|
||||
super(paymentMethod, id);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PROTO BUFFER
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private JapanBankAccountPayload(String paymentMethod,
|
||||
String id,
|
||||
String bankName,
|
||||
String bankCode,
|
||||
String bankBranchName,
|
||||
String bankBranchCode,
|
||||
String bankAccountType,
|
||||
String bankAccountName,
|
||||
String bankAccountNumber,
|
||||
long maxTradePeriod,
|
||||
Map<String, String> excludeFromJsonDataMap) {
|
||||
super(paymentMethod,
|
||||
id,
|
||||
maxTradePeriod,
|
||||
excludeFromJsonDataMap);
|
||||
|
||||
this.bankName = bankName;
|
||||
this.bankCode = bankCode;
|
||||
this.bankBranchName = bankBranchName;
|
||||
this.bankBranchCode = bankBranchCode;
|
||||
this.bankAccountType = bankAccountType;
|
||||
this.bankAccountName = bankAccountName;
|
||||
this.bankAccountNumber = bankAccountNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message toProtoMessage() {
|
||||
return getPaymentAccountPayloadBuilder()
|
||||
.setJapanBankAccountPayload(
|
||||
protobuf.JapanBankAccountPayload.newBuilder()
|
||||
.setBankName(bankName)
|
||||
.setBankCode(bankCode)
|
||||
.setBankBranchName(bankBranchName)
|
||||
.setBankBranchCode(bankBranchCode)
|
||||
.setBankAccountType(bankAccountType)
|
||||
.setBankAccountName(bankAccountName)
|
||||
.setBankAccountNumber(bankAccountNumber)
|
||||
).build();
|
||||
}
|
||||
|
||||
public static JapanBankAccountPayload fromProto(protobuf.PaymentAccountPayload proto) {
|
||||
protobuf.JapanBankAccountPayload japanBankAccountPayload = proto.getJapanBankAccountPayload();
|
||||
return new JapanBankAccountPayload(proto.getPaymentMethodId(),
|
||||
proto.getId(),
|
||||
japanBankAccountPayload.getBankName(),
|
||||
japanBankAccountPayload.getBankCode(),
|
||||
japanBankAccountPayload.getBankBranchName(),
|
||||
japanBankAccountPayload.getBankBranchCode(),
|
||||
japanBankAccountPayload.getBankAccountType(),
|
||||
japanBankAccountPayload.getBankAccountName(),
|
||||
japanBankAccountPayload.getBankAccountNumber(),
|
||||
proto.getMaxTradePeriod(),
|
||||
CollectionUtils.isEmpty(proto.getExcludeFromJsonDataMap()) ? null : new HashMap<>(proto.getExcludeFromJsonDataMap()));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getPaymentDetails()
|
||||
{
|
||||
return Res.get(paymentMethodId) + " - " + getPaymentDetailsForTradePopup().replace("\n", ", ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPaymentDetailsForTradePopup()
|
||||
{
|
||||
return bankName + "(" + bankCode + ")\n" +
|
||||
bankBranchName + "(" + bankBranchCode + ")\n" +
|
||||
bankAccountType + ": " + bankAccountNumber + "\n" +
|
||||
bankAccountName + "\n";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] getAgeWitnessInputData() {
|
||||
String all = this.bankName + this.bankBranchName + this.bankAccountType + this.bankAccountNumber + this.bankAccountName;
|
||||
return super.getAgeWitnessInputData(all.getBytes(Charset.forName("UTF-8")));
|
||||
}
|
||||
}
|
@ -72,6 +72,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable {
|
||||
public static final String SEPA_INSTANT_ID = "SEPA_INSTANT";
|
||||
public static final String FASTER_PAYMENTS_ID = "FASTER_PAYMENTS";
|
||||
public static final String NATIONAL_BANK_ID = "NATIONAL_BANK";
|
||||
public static final String JAPAN_BANK_ID = "JAPAN_BANK";
|
||||
public static final String SAME_BANK_ID = "SAME_BANK";
|
||||
public static final String SPECIFIC_BANKS_ID = "SPECIFIC_BANKS";
|
||||
public static final String SWISH_ID = "SWISH";
|
||||
@ -108,6 +109,7 @@ public final class PaymentMethod implements PersistablePayload, Comparable {
|
||||
public static PaymentMethod SEPA_INSTANT;
|
||||
public static PaymentMethod FASTER_PAYMENTS;
|
||||
public static PaymentMethod NATIONAL_BANK;
|
||||
public static PaymentMethod JAPAN_BANK;
|
||||
public static PaymentMethod SAME_BANK;
|
||||
public static PaymentMethod SPECIFIC_BANKS;
|
||||
public static PaymentMethod SWISH;
|
||||
@ -176,6 +178,9 @@ public final class PaymentMethod implements PersistablePayload, Comparable {
|
||||
PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK),
|
||||
ADVANCED_CASH = new PaymentMethod(ADVANCED_CASH_ID, DAY, DEFAULT_TRADE_LIMIT_VERY_LOW_RISK),
|
||||
|
||||
// Japan
|
||||
JAPAN_BANK = new PaymentMethod(JAPAN_BANK_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK),
|
||||
|
||||
// China
|
||||
ALI_PAY = new PaymentMethod(ALI_PAY_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK),
|
||||
WECHAT_PAY = new PaymentMethod(WECHAT_PAY_ID, DAY, DEFAULT_TRADE_LIMIT_LOW_RISK),
|
||||
|
@ -33,6 +33,7 @@ import bisq.core.payment.payload.FasterPaymentsAccountPayload;
|
||||
import bisq.core.payment.payload.HalCashAccountPayload;
|
||||
import bisq.core.payment.payload.InstantCryptoCurrencyPayload;
|
||||
import bisq.core.payment.payload.InteracETransferAccountPayload;
|
||||
import bisq.core.payment.payload.JapanBankAccountPayload;;
|
||||
import bisq.core.payment.payload.MoneyBeamAccountPayload;
|
||||
import bisq.core.payment.payload.MoneyGramAccountPayload;
|
||||
import bisq.core.payment.payload.NationalBankAccountPayload;
|
||||
@ -113,6 +114,8 @@ public class CoreProtoResolver implements ProtoResolver {
|
||||
return FasterPaymentsAccountPayload.fromProto(proto);
|
||||
case INTERAC_E_TRANSFER_ACCOUNT_PAYLOAD:
|
||||
return InteracETransferAccountPayload.fromProto(proto);
|
||||
case JAPAN_BANK_ACCOUNT_PAYLOAD:
|
||||
return JapanBankAccountPayload.fromProto(proto);
|
||||
case UPHOLD_ACCOUNT_PAYLOAD:
|
||||
return UpholdAccountPayload.fromProto(proto);
|
||||
case MONEY_BEAM_ACCOUNT_PAYLOAD:
|
||||
|
@ -48,7 +48,7 @@ public class ApplyFilter extends TradeTask {
|
||||
|
||||
FilterManager filterManager = processModel.getFilterManager();
|
||||
if (nodeAddress != null && filterManager.isNodeAddressBanned(nodeAddress)) {
|
||||
failed("Other trader is banned by his node address.\n" +
|
||||
failed("Other trader is banned by their node address.\n" +
|
||||
"tradingPeerNodeAddress=" + nodeAddress);
|
||||
} else if (filterManager.isOfferIdBanned(trade.getId())) {
|
||||
failed("Offer ID is banned.\n" +
|
||||
@ -60,7 +60,7 @@ public class ApplyFilter extends TradeTask {
|
||||
failed("Payment method is banned.\n" +
|
||||
"Payment method=" + trade.getOffer().getPaymentMethod().getId());
|
||||
} else if (filterManager.isPeersPaymentAccountDataAreBanned(paymentAccountPayload, appliedPaymentAccountFilter)) {
|
||||
failed("Other trader is banned by his trading account data.\n" +
|
||||
failed("Other trader is banned by their trading account data.\n" +
|
||||
"paymentAccountPayload=" + paymentAccountPayload.getPaymentDetails() + "\n" +
|
||||
"banFilter=" + appliedPaymentAccountFilter[0].toString());
|
||||
} else if (filterManager.requireUpdateToNewVersionForTrading()) {
|
||||
|
@ -39,11 +39,13 @@ public class SellerVerifiesPeersAccountAge extends TradeTask {
|
||||
try {
|
||||
runInterceptHook();
|
||||
|
||||
boolean isTradeRisky = OfferRestrictions.isTradeRisky(trade);
|
||||
boolean isTradePeersAccountAgeImmature = AccountAgeRestrictions.isTradePeersAccountAgeImmature(
|
||||
processModel.getAccountAgeWitnessService(), trade);
|
||||
log.debug("SellerVerifiesPeersAccountAge isOfferRisky={} isTradePeersAccountAgeImmature={}",
|
||||
OfferRestrictions.isTradeRisky(trade), AccountAgeRestrictions.isTradePeersAccountAgeImmature(
|
||||
processModel.getAccountAgeWitnessService(), trade));
|
||||
if (OfferRestrictions.isTradeRisky(trade) &&
|
||||
AccountAgeRestrictions.isTradePeersAccountAgeImmature(processModel.getAccountAgeWitnessService(), trade)) {
|
||||
isTradeRisky, isTradePeersAccountAgeImmature);
|
||||
if (isTradeRisky &&
|
||||
isTradePeersAccountAgeImmature) {
|
||||
failed("Violation of security restrictions:\n" +
|
||||
" - The peer's account was created after March 1st 2019\n" +
|
||||
" - The trade amount is above 0.01 BTC\n" +
|
||||
|
@ -20,12 +20,9 @@ package bisq.core.util;
|
||||
import bisq.core.app.BisqEnvironment;
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.locale.GlobalSettings;
|
||||
import bisq.core.locale.LanguageUtil;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.monetary.Altcoin;
|
||||
import bisq.core.monetary.Price;
|
||||
import bisq.core.monetary.Volume;
|
||||
import bisq.core.offer.Offer;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
|
||||
import bisq.network.p2p.NodeAddress;
|
||||
@ -55,6 +52,7 @@ import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -64,27 +62,24 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class BSFormatter {
|
||||
public final static String RANGE_SEPARATOR = " - ";
|
||||
|
||||
protected boolean useMilliBit;
|
||||
protected int scale = 3;
|
||||
|
||||
// We don't support localized formatting. Format is always using "." as decimal mark and no grouping separator.
|
||||
// Input of "," as decimal mark (like in german locale) will be replaced with ".".
|
||||
// Input of a group separator (1,123,45) lead to an validation error.
|
||||
// Note: BtcFormat was intended to be used, but it lead to many problems (automatic format to mBit,
|
||||
// no way to remove grouping separator). It seems to be not optimal for user input formatting.
|
||||
protected MonetaryFormat coinFormat;
|
||||
@Getter
|
||||
protected MonetaryFormat monetaryFormat;
|
||||
|
||||
// protected String currencyCode = CurrencyUtil.getDefaultFiatCurrencyAsCode();
|
||||
|
||||
protected final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
|
||||
protected final MonetaryFormat fiatVolumeFormat = new MonetaryFormat().shift(0).minDecimals(2).repeatOptionalDecimals(0, 0);
|
||||
protected final MonetaryFormat altcoinFormat = new MonetaryFormat().shift(0).minDecimals(8).repeatOptionalDecimals(0, 0);
|
||||
protected final DecimalFormat decimalFormat = new DecimalFormat("#.#");
|
||||
public static final MonetaryFormat fiatPriceFormat = new MonetaryFormat().shift(0).minDecimals(4).repeatOptionalDecimals(0, 0);
|
||||
protected static final MonetaryFormat altcoinFormat = new MonetaryFormat().shift(0).minDecimals(8).repeatOptionalDecimals(0, 0);
|
||||
protected static final DecimalFormat decimalFormat = new DecimalFormat("#.#");
|
||||
|
||||
|
||||
@Inject
|
||||
public BSFormatter() {
|
||||
coinFormat = BisqEnvironment.getParameters().getMonetaryFormat();
|
||||
monetaryFormat = BisqEnvironment.getParameters().getMonetaryFormat();
|
||||
}
|
||||
|
||||
|
||||
@ -106,10 +101,14 @@ public class BSFormatter {
|
||||
}
|
||||
|
||||
public String formatCoin(Coin coin, int decimalPlaces, boolean decimalAligned, int maxNumberOfDigits) {
|
||||
return formatCoin(coin, decimalPlaces, decimalAligned, maxNumberOfDigits, coinFormat);
|
||||
return formatCoin(coin, decimalPlaces, decimalAligned, maxNumberOfDigits, monetaryFormat);
|
||||
}
|
||||
|
||||
public String formatCoin(Coin coin, int decimalPlaces, boolean decimalAligned, int maxNumberOfDigits, MonetaryFormat coinFormat) {
|
||||
public static String formatCoin(Coin coin,
|
||||
int decimalPlaces,
|
||||
boolean decimalAligned,
|
||||
int maxNumberOfDigits,
|
||||
MonetaryFormat coinFormat) {
|
||||
String formattedCoin = "";
|
||||
|
||||
if (coin != null) {
|
||||
@ -132,18 +131,18 @@ public class BSFormatter {
|
||||
}
|
||||
|
||||
public String formatCoinWithCode(Coin coin) {
|
||||
return formatCoinWithCode(coin, coinFormat);
|
||||
return formatCoinWithCode(coin, monetaryFormat);
|
||||
}
|
||||
|
||||
public String formatCoinWithCode(long value) {
|
||||
return formatCoinWithCode(Coin.valueOf(value), monetaryFormat);
|
||||
}
|
||||
|
||||
public static String formatCoinWithCode(long value, MonetaryFormat coinFormat) {
|
||||
return formatCoinWithCode(Coin.valueOf(value), coinFormat);
|
||||
}
|
||||
|
||||
public String formatCoinWithCode(long value, MonetaryFormat coinFormat) {
|
||||
return formatCoinWithCode(Coin.valueOf(value), coinFormat);
|
||||
}
|
||||
|
||||
public String formatCoinWithCode(Coin coin, MonetaryFormat coinFormat) {
|
||||
public static String formatCoinWithCode(Coin coin, MonetaryFormat coinFormat) {
|
||||
if (coin != null) {
|
||||
try {
|
||||
// we don't use the code feature from coinFormat as it does automatic switching between mBTC and BTC and
|
||||
@ -158,62 +157,11 @@ public class BSFormatter {
|
||||
}
|
||||
}
|
||||
|
||||
public Coin parseToCoin(String input) {
|
||||
return parseToCoin(input, coinFormat);
|
||||
}
|
||||
|
||||
public Coin parseToCoin(String input, MonetaryFormat coinFormat) {
|
||||
if (input != null && input.length() > 0) {
|
||||
try {
|
||||
return coinFormat.parse(cleanDoubleInput(input));
|
||||
} catch (Throwable t) {
|
||||
log.warn("Exception at parseToBtc: " + t.toString());
|
||||
return Coin.ZERO;
|
||||
}
|
||||
} else {
|
||||
return Coin.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts to a coin with max. 4 decimal places. Last place gets rounded.
|
||||
* 0.01234 -> 0.0123
|
||||
* 0.01235 -> 0.0124
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
*/
|
||||
public Coin parseToCoinWith4Decimals(String input) {
|
||||
try {
|
||||
return Coin.valueOf(new BigDecimal(parseToCoin(cleanDoubleInput(input)).value).setScale(-scale - 1,
|
||||
BigDecimal.ROUND_HALF_UP).setScale(scale + 1, BigDecimal.ROUND_HALF_UP).toBigInteger().longValue());
|
||||
} catch (Throwable t) {
|
||||
if (input != null && input.length() > 0)
|
||||
log.warn("Exception at parseToCoinWith4Decimals: " + t.toString());
|
||||
return Coin.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasBtcValidDecimals(String input) {
|
||||
return parseToCoin(input).equals(parseToCoinWith4Decimals(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a coin with the properties defined in the format (used to reduce decimal places)
|
||||
*
|
||||
* @param coin The coin which should be transformed
|
||||
* @return The transformed coin
|
||||
*/
|
||||
public Coin reduceTo4Decimals(Coin coin) {
|
||||
return parseToCoin(formatCoin(coin));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// FIAT
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String formatFiat(Fiat fiat, MonetaryFormat format, boolean appendCurrencyCode) {
|
||||
public static String formatFiat(Fiat fiat, MonetaryFormat format, boolean appendCurrencyCode) {
|
||||
if (fiat != null) {
|
||||
try {
|
||||
final String res = format.noCode().format(fiat).toString();
|
||||
@ -230,10 +178,10 @@ public class BSFormatter {
|
||||
}
|
||||
}
|
||||
|
||||
protected Fiat parseToFiat(String input, String currencyCode) {
|
||||
private static Fiat parseToFiat(String input, String currencyCode) {
|
||||
if (input != null && input.length() > 0) {
|
||||
try {
|
||||
return Fiat.parseFiat(currencyCode, cleanDoubleInput(input));
|
||||
return Fiat.parseFiat(currencyCode, ParsingUtils.cleanDoubleInput(input));
|
||||
} catch (Exception e) {
|
||||
log.warn("Exception at parseToFiat: " + e.toString());
|
||||
return Fiat.valueOf(currencyCode, 0);
|
||||
@ -253,10 +201,10 @@ public class BSFormatter {
|
||||
* @return
|
||||
*/
|
||||
|
||||
public Fiat parseToFiatWithPrecision(String input, String currencyCode) {
|
||||
public static Fiat parseToFiatWithPrecision(String input, String currencyCode) {
|
||||
if (input != null && input.length() > 0) {
|
||||
try {
|
||||
return parseToFiat(new BigDecimal(cleanDoubleInput(input)).setScale(2, BigDecimal.ROUND_HALF_UP).toString(),
|
||||
return parseToFiat(new BigDecimal(ParsingUtils.cleanDoubleInput(input)).setScale(2, BigDecimal.ROUND_HALF_UP).toString(),
|
||||
currencyCode);
|
||||
} catch (Throwable t) {
|
||||
log.warn("Exception at parseToFiatWithPrecision: " + t.toString());
|
||||
@ -267,24 +215,12 @@ public class BSFormatter {
|
||||
return Fiat.valueOf(currencyCode, 0);
|
||||
}
|
||||
|
||||
public boolean isFiatAlteredWhenPrecisionApplied(String input, String currencyCode) {
|
||||
return parseToFiat(input, currencyCode).equals(parseToFiatWithPrecision(input, currencyCode));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Altcoin
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String formatAltcoin(Altcoin altcoin) {
|
||||
return formatAltcoin(altcoin, false);
|
||||
}
|
||||
|
||||
public String formatAltcoinWithCode(Altcoin altcoin) {
|
||||
return formatAltcoin(altcoin, true);
|
||||
}
|
||||
|
||||
public String formatAltcoin(Altcoin altcoin, boolean appendCurrencyCode) {
|
||||
private static String formatAltcoin(Altcoin altcoin, boolean appendCurrencyCode) {
|
||||
if (altcoin != null) {
|
||||
try {
|
||||
String res = altcoinFormat.noCode().format(altcoin).toString();
|
||||
@ -306,21 +242,8 @@ public class BSFormatter {
|
||||
// Volume
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String formatVolume(Offer offer, Boolean decimalAligned, int maxNumberOfDigits) {
|
||||
return formatVolume(offer, decimalAligned, maxNumberOfDigits, true);
|
||||
}
|
||||
|
||||
public String formatVolume(Offer offer, Boolean decimalAligned, int maxNumberOfDigits, boolean showRange) {
|
||||
String formattedVolume = offer.isRange() && showRange ? formatVolume(offer.getMinVolume()) + RANGE_SEPARATOR + formatVolume(offer.getVolume()) : formatVolume(offer.getVolume());
|
||||
|
||||
if (decimalAligned) {
|
||||
formattedVolume = fillUpPlacesWithEmptyStrings(formattedVolume, maxNumberOfDigits);
|
||||
}
|
||||
return formattedVolume;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String fillUpPlacesWithEmptyStrings(String formattedNumber, int maxNumberOfDigits) {
|
||||
public static String fillUpPlacesWithEmptyStrings(String formattedNumber, int maxNumberOfDigits) {
|
||||
//FIXME: temporary deactivate adding spaces in front of numbers as we don't use a monospace font right now.
|
||||
/*int numberOfPlacesToFill = maxNumberOfDigits - formattedNumber.length();
|
||||
for (int i = 0; i < numberOfPlacesToFill; i++) {
|
||||
@ -329,27 +252,7 @@ public class BSFormatter {
|
||||
return formattedNumber;
|
||||
}
|
||||
|
||||
public String formatVolume(Volume volume) {
|
||||
return formatVolume(volume, fiatVolumeFormat, false);
|
||||
}
|
||||
|
||||
public String formatVolumeWithCode(Volume volume) {
|
||||
return formatVolume(volume, fiatVolumeFormat, true);
|
||||
}
|
||||
|
||||
public String formatVolume(Volume volume, MonetaryFormat fiatVolumeFormat, boolean appendCurrencyCode) {
|
||||
if (volume != null) {
|
||||
Monetary monetary = volume.getMonetary();
|
||||
if (monetary instanceof Fiat)
|
||||
return formatFiat((Fiat) monetary, fiatVolumeFormat, appendCurrencyCode);
|
||||
else
|
||||
return formatAltcoinVolume((Altcoin) monetary, appendCurrencyCode);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String formatAltcoinVolume(Altcoin altcoin, boolean appendCurrencyCode) {
|
||||
public static String formatAltcoinVolume(Altcoin altcoin, boolean appendCurrencyCode) {
|
||||
if (altcoin != null) {
|
||||
try {
|
||||
// TODO quick hack...
|
||||
@ -371,47 +274,13 @@ public class BSFormatter {
|
||||
}
|
||||
}
|
||||
|
||||
public String formatVolumeLabel(String currencyCode) {
|
||||
return formatVolumeLabel(currencyCode, "");
|
||||
}
|
||||
|
||||
public String formatVolumeLabel(String currencyCode, String postFix) {
|
||||
return Res.get("formatter.formatVolumeLabel",
|
||||
currencyCode, postFix);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Amount
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String formatAmount(Offer offer) {
|
||||
return formatAmount(offer, false);
|
||||
}
|
||||
|
||||
public String formatAmount(Offer offer, boolean decimalAligned) {
|
||||
String formattedAmount = offer.isRange() ? formatCoin(offer.getMinAmount()) + RANGE_SEPARATOR + formatCoin(offer.getAmount()) : formatCoin(offer.getAmount());
|
||||
if (decimalAligned) {
|
||||
formattedAmount = fillUpPlacesWithEmptyStrings(formattedAmount, 15);
|
||||
}
|
||||
return formattedAmount;
|
||||
}
|
||||
|
||||
public String formatAmount(Offer offer, int decimalPlaces, boolean decimalAligned, int maxPlaces) {
|
||||
String formattedAmount = offer.isRange() ? formatCoin(offer.getMinAmount(), decimalPlaces) + RANGE_SEPARATOR + formatCoin(offer.getAmount(), decimalPlaces) : formatCoin(offer.getAmount(), decimalPlaces);
|
||||
|
||||
if (decimalAligned) {
|
||||
formattedAmount = fillUpPlacesWithEmptyStrings(formattedAmount, maxPlaces);
|
||||
}
|
||||
return formattedAmount;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Price
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public String formatPrice(Price price, MonetaryFormat fiatPriceFormat, boolean appendCurrencyCode) {
|
||||
public static String formatPrice(Price price, MonetaryFormat fiatPriceFormat, boolean appendCurrencyCode) {
|
||||
if (price != null) {
|
||||
Monetary monetary = price.getMonetary();
|
||||
if (monetary instanceof Fiat)
|
||||
@ -423,35 +292,26 @@ public class BSFormatter {
|
||||
}
|
||||
}
|
||||
|
||||
public String formatPrice(Price price, boolean appendCurrencyCode) {
|
||||
public static String formatPrice(Price price, boolean appendCurrencyCode) {
|
||||
return formatPrice(price, fiatPriceFormat, true);
|
||||
}
|
||||
|
||||
public String formatPrice(Price price) {
|
||||
public static String formatPrice(Price price) {
|
||||
return formatPrice(price, fiatPriceFormat, false);
|
||||
}
|
||||
|
||||
public String formatPrice(Price price, Boolean decimalAligned, int maxPlaces) {
|
||||
String formattedPrice = formatPrice(price);
|
||||
|
||||
if (decimalAligned) {
|
||||
formattedPrice = fillUpPlacesWithEmptyStrings(formattedPrice, maxPlaces);
|
||||
}
|
||||
return formattedPrice;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Market price
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String formatMarketPrice(double price, String currencyCode) {
|
||||
public static String formatMarketPrice(double price, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return formatMarketPrice(price, 2);
|
||||
else
|
||||
return formatMarketPrice(price, 8);
|
||||
}
|
||||
|
||||
public String formatMarketPrice(double price, int precision) {
|
||||
public static String formatMarketPrice(double price, int precision) {
|
||||
return formatRoundedDoubleWithPrecision(price, precision);
|
||||
}
|
||||
|
||||
@ -460,40 +320,25 @@ public class BSFormatter {
|
||||
// Other
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String formatRoundedDoubleWithPrecision(double value, int precision) {
|
||||
public static String formatRoundedDoubleWithPrecision(double value, int precision) {
|
||||
decimalFormat.setMinimumFractionDigits(precision);
|
||||
decimalFormat.setMaximumFractionDigits(precision);
|
||||
return decimalFormat.format(MathUtils.roundDouble(value, precision)).replace(",", ".");
|
||||
}
|
||||
|
||||
public String getDirectionWithCode(OfferPayload.Direction direction, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return (direction == OfferPayload.Direction.BUY) ? Res.get("shared.buyCurrency", Res.getBaseCurrencyCode()) : Res.get("shared.sellCurrency", Res.getBaseCurrencyCode());
|
||||
else
|
||||
return (direction == OfferPayload.Direction.SELL) ? Res.get("shared.buyCurrency", currencyCode) : Res.get("shared.sellCurrency", currencyCode);
|
||||
}
|
||||
|
||||
public String getDirectionWithCodeDetailed(OfferPayload.Direction direction, String currencyCode) {
|
||||
public static String getDirectionWithCodeDetailed(OfferPayload.Direction direction, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return (direction == OfferPayload.Direction.BUY) ? Res.get("shared.buyingBTCWith", currencyCode) : Res.get("shared.sellingBTCFor", currencyCode);
|
||||
else
|
||||
return (direction == OfferPayload.Direction.SELL) ? Res.get("shared.buyingCurrency", currencyCode) : Res.get("shared.sellingCurrency", currencyCode);
|
||||
}
|
||||
|
||||
public String arbitratorAddressesToString(List<NodeAddress> nodeAddresses) {
|
||||
public static String arbitratorAddressesToString(List<NodeAddress> nodeAddresses) {
|
||||
return nodeAddresses.stream().map(NodeAddress::getFullAddress).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
public String languageCodesToString(List<String> languageLocales) {
|
||||
return languageLocales.stream().map(LanguageUtil::getDisplayName).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
public String formatDateTime(Date date) {
|
||||
return formatDateTime(date, true);
|
||||
}
|
||||
|
||||
public String formatDateTime(Date date, boolean useLocaleAndLocalTimezone) {
|
||||
Locale locale = useLocaleAndLocalTimezone ? getLocale() : Locale.US;
|
||||
public static String formatDateTime(Date date, boolean useLocaleAndLocalTimezone) {
|
||||
Locale locale = useLocaleAndLocalTimezone ? GlobalSettings.getLocale() : Locale.US;
|
||||
DateFormat dateInstance = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
|
||||
DateFormat timeInstance = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
|
||||
if (!useLocaleAndLocalTimezone) {
|
||||
@ -503,7 +348,7 @@ public class BSFormatter {
|
||||
return formatDateTime(date, dateInstance, timeInstance);
|
||||
}
|
||||
|
||||
public String formatDateTime(Date date, DateFormat dateFormatter, DateFormat timeFormatter) {
|
||||
public static String formatDateTime(Date date, DateFormat dateFormatter, DateFormat timeFormatter) {
|
||||
if (date != null) {
|
||||
return dateFormatter.format(date) + " " + timeFormatter.format(date);
|
||||
} else {
|
||||
@ -511,113 +356,26 @@ public class BSFormatter {
|
||||
}
|
||||
}
|
||||
|
||||
public String formatDateTimeSpan(Date dateFrom, Date dateTo) {
|
||||
if (dateFrom != null && dateTo != null) {
|
||||
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale());
|
||||
DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale());
|
||||
return dateFormatter.format(dateFrom) + " " + timeFormatter.format(dateFrom) + RANGE_SEPARATOR + timeFormatter.format(dateTo);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String formatTime(Date date) {
|
||||
if (date != null) {
|
||||
DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, getLocale());
|
||||
return timeFormatter.format(date);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String formatDate(Date date) {
|
||||
if (date != null) {
|
||||
DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.DEFAULT, getLocale());
|
||||
return dateFormatter.format(date);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String formatToPercentWithSymbol(double value) {
|
||||
public static String formatToPercentWithSymbol(double value) {
|
||||
return formatToPercent(value) + "%";
|
||||
}
|
||||
|
||||
public String formatPercentagePrice(double value) {
|
||||
public static String formatPercentagePrice(double value) {
|
||||
return formatToPercentWithSymbol(value);
|
||||
}
|
||||
|
||||
public String formatToPercent(double value) {
|
||||
public static String formatToPercent(double value) {
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.##");
|
||||
decimalFormat.setMinimumFractionDigits(2);
|
||||
decimalFormat.setMaximumFractionDigits(2);
|
||||
return decimalFormat.format(MathUtils.roundDouble(value * 100.0, 2)).replace(",", ".");
|
||||
}
|
||||
|
||||
public double parseNumberStringToDouble(String input) throws NumberFormatException {
|
||||
return Double.parseDouble(cleanDoubleInput(input));
|
||||
}
|
||||
|
||||
public double parsePercentStringToDouble(String percentString) throws NumberFormatException {
|
||||
String input = percentString.replace("%", "");
|
||||
input = cleanDoubleInput(input);
|
||||
double value = Double.parseDouble(input);
|
||||
return MathUtils.roundDouble(value / 100d, 4);
|
||||
}
|
||||
|
||||
public long parsePriceStringToLong(String currencyCode, String amount, int precision) {
|
||||
if (amount == null || amount.isEmpty())
|
||||
return 0;
|
||||
|
||||
long value = 0;
|
||||
try {
|
||||
double amountValue = Double.parseDouble(amount);
|
||||
amount = formatRoundedDoubleWithPrecision(amountValue, precision);
|
||||
value = Price.parse(currencyCode, amount).getValue();
|
||||
} catch (NumberFormatException ignore) {
|
||||
// expected NumberFormatException if input is not a number
|
||||
} catch (Throwable t) {
|
||||
log.error("parsePriceStringToLong: " + t.toString());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String convertCharsForNumber(String input) {
|
||||
// Some languages like finnish use the long dash for the minus
|
||||
input = input.replace("−", "-");
|
||||
input = StringUtils.deleteWhitespace(input);
|
||||
return input.replace(",", ".");
|
||||
}
|
||||
|
||||
protected String cleanDoubleInput(String input) {
|
||||
input = convertCharsForNumber(input);
|
||||
if (input.equals("."))
|
||||
input = input.replace(".", "0.");
|
||||
if (input.equals("-."))
|
||||
input = input.replace("-.", "-0.");
|
||||
// don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific
|
||||
// notation (1.0E-6) which screw up coinFormat.parse
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
// Just called to check if we have a valid double, throws exception otherwise
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
Double.parseDouble(input);
|
||||
return input;
|
||||
}
|
||||
|
||||
public String formatAccountAge(long durationMillis) {
|
||||
durationMillis = Math.max(0, durationMillis);
|
||||
String day = Res.get("time.day").toLowerCase();
|
||||
String days = Res.get("time.days");
|
||||
String format = "d\' " + days + "\'";
|
||||
return StringUtils.replaceOnce(DurationFormatUtils.formatDuration(durationMillis, format), "1 " + days, "1 " + day);
|
||||
}
|
||||
|
||||
public String formatDurationAsWords(long durationMillis) {
|
||||
public static String formatDurationAsWords(long durationMillis) {
|
||||
return formatDurationAsWords(durationMillis, false, true);
|
||||
}
|
||||
|
||||
public String formatDurationAsWords(long durationMillis, boolean showSeconds, boolean showZeroValues) {
|
||||
public static String formatDurationAsWords(long durationMillis, boolean showSeconds, boolean showZeroValues) {
|
||||
String format = "";
|
||||
String second = Res.get("time.second");
|
||||
String minute = Res.get("time.minute");
|
||||
@ -657,77 +415,7 @@ public class BSFormatter {
|
||||
return duration.trim();
|
||||
}
|
||||
|
||||
public String booleanToYesNo(boolean value) {
|
||||
return value ? Res.get("shared.yes") : Res.get("shared.no");
|
||||
}
|
||||
|
||||
public String getDirectionBothSides(OfferPayload.Direction direction, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
currencyCode = Res.getBaseCurrencyCode();
|
||||
return direction == OfferPayload.Direction.BUY ?
|
||||
Res.get("formatter.makerTaker", currencyCode, Res.get("shared.buyer"), currencyCode, Res.get("shared.seller")) :
|
||||
Res.get("formatter.makerTaker", currencyCode, Res.get("shared.seller"), currencyCode, Res.get("shared.buyer"));
|
||||
} else {
|
||||
return direction == OfferPayload.Direction.SELL ?
|
||||
Res.get("formatter.makerTaker", currencyCode, Res.get("shared.buyer"), currencyCode, Res.get("shared.seller")) :
|
||||
Res.get("formatter.makerTaker", currencyCode, Res.get("shared.seller"), currencyCode, Res.get("shared.buyer"));
|
||||
}
|
||||
}
|
||||
|
||||
public String getDirectionForBuyer(boolean isMyOffer, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
String code = Res.getBaseCurrencyCode();
|
||||
return isMyOffer ?
|
||||
Res.get("formatter.youAreAsMaker", Res.get("shared.buying"), code, Res.get("shared.selling"), code) :
|
||||
Res.get("formatter.youAreAsTaker", Res.get("shared.buying"), code, Res.get("shared.selling"), code);
|
||||
} else {
|
||||
return isMyOffer ?
|
||||
Res.get("formatter.youAreAsMaker", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), currencyCode) :
|
||||
Res.get("formatter.youAreAsTaker", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), currencyCode);
|
||||
}
|
||||
}
|
||||
|
||||
public String getDirectionForSeller(boolean isMyOffer, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
String code = Res.getBaseCurrencyCode();
|
||||
return isMyOffer ?
|
||||
Res.get("formatter.youAreAsMaker", Res.get("shared.selling"), code, Res.get("shared.buying"), code) :
|
||||
Res.get("formatter.youAreAsTaker", Res.get("shared.selling"), code, Res.get("shared.buying"), code);
|
||||
} else {
|
||||
return isMyOffer ?
|
||||
Res.get("formatter.youAreAsMaker", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), currencyCode) :
|
||||
Res.get("formatter.youAreAsTaker", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), currencyCode);
|
||||
}
|
||||
}
|
||||
|
||||
public String getDirectionForTakeOffer(OfferPayload.Direction direction, String currencyCode) {
|
||||
String baseCurrencyCode = Res.getBaseCurrencyCode();
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
return direction == OfferPayload.Direction.BUY ?
|
||||
Res.get("formatter.youAre", Res.get("shared.selling"), baseCurrencyCode, Res.get("shared.buying"), currencyCode) :
|
||||
Res.get("formatter.youAre", Res.get("shared.buying"), baseCurrencyCode, Res.get("shared.selling"), currencyCode);
|
||||
} else {
|
||||
|
||||
return direction == OfferPayload.Direction.SELL ?
|
||||
Res.get("formatter.youAre", Res.get("shared.selling"), currencyCode, Res.get("shared.buying"), baseCurrencyCode) :
|
||||
Res.get("formatter.youAre", Res.get("shared.buying"), currencyCode, Res.get("shared.selling"), baseCurrencyCode);
|
||||
}
|
||||
}
|
||||
|
||||
public String getOfferDirectionForCreateOffer(OfferPayload.Direction direction, String currencyCode) {
|
||||
String baseCurrencyCode = Res.getBaseCurrencyCode();
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
return direction == OfferPayload.Direction.BUY ?
|
||||
Res.get("formatter.youAreCreatingAnOffer.fiat", Res.get("shared.buy"), baseCurrencyCode) :
|
||||
Res.get("formatter.youAreCreatingAnOffer.fiat", Res.get("shared.sell"), baseCurrencyCode);
|
||||
} else {
|
||||
return direction == OfferPayload.Direction.SELL ?
|
||||
Res.get("formatter.youAreCreatingAnOffer.altcoin", Res.get("shared.buy"), currencyCode, Res.get("shared.selling"), baseCurrencyCode) :
|
||||
Res.get("formatter.youAreCreatingAnOffer.altcoin", Res.get("shared.sell"), currencyCode, Res.get("shared.buying"), baseCurrencyCode);
|
||||
}
|
||||
}
|
||||
|
||||
public String getRole(boolean isBuyerMakerAndSellerTaker, boolean isMaker, String currencyCode) {
|
||||
public static String getRole(boolean isBuyerMakerAndSellerTaker, boolean isMaker, String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode)) {
|
||||
String baseCurrencyCode = Res.getBaseCurrencyCode();
|
||||
if (isBuyerMakerAndSellerTaker)
|
||||
@ -751,7 +439,7 @@ public class BSFormatter {
|
||||
|
||||
}
|
||||
|
||||
public String formatBytes(long bytes) {
|
||||
public static String formatBytes(long bytes) {
|
||||
double kb = 1024;
|
||||
double mb = kb * kb;
|
||||
DecimalFormat decimalFormat = new DecimalFormat("#.##");
|
||||
@ -763,47 +451,28 @@ public class BSFormatter {
|
||||
return decimalFormat.format(bytes / mb) + " MB";
|
||||
}
|
||||
|
||||
public String getCurrencyPair(String currencyCode) {
|
||||
public static String getCurrencyPair(String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return Res.getBaseCurrencyCode() + "/" + currencyCode;
|
||||
else
|
||||
return currencyCode + "/" + Res.getBaseCurrencyCode();
|
||||
}
|
||||
|
||||
public String getCounterCurrency(String currencyCode) {
|
||||
public static String getCounterCurrency(String currencyCode) {
|
||||
if (CurrencyUtil.isFiatCurrency(currencyCode))
|
||||
return currencyCode;
|
||||
else
|
||||
return Res.getBaseCurrencyCode();
|
||||
}
|
||||
|
||||
public String getBaseCurrency(String currencyCode) {
|
||||
if (CurrencyUtil.isCryptoCurrency(currencyCode))
|
||||
return currencyCode;
|
||||
else
|
||||
return Res.getBaseCurrencyCode();
|
||||
}
|
||||
|
||||
public String getCounterCurrencyAndCurrencyPair(String currencyCode) {
|
||||
return getCounterCurrency(currencyCode) + " (" + getCurrencyPair(currencyCode) + ")";
|
||||
}
|
||||
|
||||
public String getCurrencyNameAndCurrencyPair(String currencyCode) {
|
||||
return CurrencyUtil.getNameByCode(currencyCode) + " (" + getCurrencyPair(currencyCode) + ")";
|
||||
}
|
||||
|
||||
public String getPriceWithCurrencyCode(String currencyCode) {
|
||||
public static String getPriceWithCurrencyCode(String currencyCode) {
|
||||
return getPriceWithCurrencyCode(currencyCode, "shared.priceInCurForCur");
|
||||
}
|
||||
|
||||
public String getPriceWithCurrencyCode(String currencyCode, String translationKey) {
|
||||
public static String getPriceWithCurrencyCode(String currencyCode, String translationKey) {
|
||||
if (CurrencyUtil.isCryptoCurrency(currencyCode))
|
||||
return Res.get(translationKey, Res.getBaseCurrencyCode(), currencyCode);
|
||||
else
|
||||
return Res.get(translationKey, currencyCode, Res.getBaseCurrencyCode());
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return GlobalSettings.getLocale();
|
||||
}
|
||||
}
|
||||
|
@ -61,12 +61,12 @@ public class BsqFormatter extends BSFormatter {
|
||||
GlobalSettings.localeProperty().addListener((observable, oldValue, newValue) -> setFormatter(newValue));
|
||||
setFormatter(GlobalSettings.getLocale());
|
||||
|
||||
btcCoinFormat = super.coinFormat;
|
||||
btcCoinFormat = super.monetaryFormat;
|
||||
|
||||
final String baseCurrencyCode = BisqEnvironment.getBaseCurrencyNetwork().getCurrencyCode();
|
||||
switch (baseCurrencyCode) {
|
||||
case "BTC":
|
||||
coinFormat = new MonetaryFormat().shift(6).code(6, "BSQ").minDecimals(2);
|
||||
monetaryFormat = new MonetaryFormat().shift(6).code(6, "BSQ").minDecimals(2);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("baseCurrencyCode not defined. baseCurrencyCode=" + baseCurrencyCode);
|
||||
@ -123,11 +123,11 @@ public class BsqFormatter extends BSFormatter {
|
||||
}
|
||||
|
||||
public String formatBSQSatoshis(long satoshi) {
|
||||
return super.formatCoin(satoshi, coinFormat);
|
||||
return super.formatCoin(satoshi, monetaryFormat);
|
||||
}
|
||||
|
||||
public String formatBSQSatoshisWithCode(long satoshi) {
|
||||
return super.formatCoinWithCode(satoshi, coinFormat);
|
||||
return super.formatCoinWithCode(satoshi, monetaryFormat);
|
||||
}
|
||||
|
||||
public String formatBTCSatoshis(long satoshi) {
|
||||
@ -147,7 +147,7 @@ public class BsqFormatter extends BSFormatter {
|
||||
}
|
||||
|
||||
public Coin parseToBTC(String input) {
|
||||
return super.parseToCoin(input, btcCoinFormat);
|
||||
return ParsingUtils.parseToCoin(input, btcCoinFormat);
|
||||
}
|
||||
|
||||
public void validateBtcInput(String input) throws ProposalValidationException {
|
||||
@ -155,12 +155,12 @@ public class BsqFormatter extends BSFormatter {
|
||||
}
|
||||
|
||||
public void validateBsqInput(String input) throws ProposalValidationException {
|
||||
validateCoinInput(input, this.coinFormat);
|
||||
validateCoinInput(input, this.monetaryFormat);
|
||||
}
|
||||
|
||||
private void validateCoinInput(String input, MonetaryFormat coinFormat) throws ProposalValidationException {
|
||||
try {
|
||||
coinFormat.parse(cleanDoubleInput(input));
|
||||
coinFormat.parse(ParsingUtils.cleanDoubleInput(input));
|
||||
} catch (Throwable t) {
|
||||
throw new ProposalValidationException("Invalid format for a " + coinFormat.code() + " value");
|
||||
}
|
||||
@ -172,11 +172,11 @@ public class BsqFormatter extends BSFormatter {
|
||||
// In case we add a new param old clients will not know that enum and fall back to UNDEFINED.
|
||||
return Res.get("shared.na");
|
||||
case BSQ:
|
||||
return formatCoinWithCode(parseToCoin(value));
|
||||
return formatCoinWithCode(ParsingUtils.parseToCoin(value, this));
|
||||
case BTC:
|
||||
return formatBTCWithCode(parseToBTC(value));
|
||||
case PERCENT:
|
||||
return formatToPercentWithSymbol(parsePercentStringToDouble(value));
|
||||
return formatToPercentWithSymbol(ParsingUtils.parsePercentStringToDouble(value));
|
||||
case BLOCK:
|
||||
return Res.get("dao.param.blocks", Integer.parseInt(value));
|
||||
case ADDRESS:
|
||||
@ -190,7 +190,7 @@ public class BsqFormatter extends BSFormatter {
|
||||
public Coin parseParamValueToCoin(Param param, String inputValue) {
|
||||
switch (param.getParamType()) {
|
||||
case BSQ:
|
||||
return parseToCoin(inputValue);
|
||||
return ParsingUtils.parseToCoin(inputValue, this);
|
||||
case BTC:
|
||||
return parseToBTC(inputValue);
|
||||
default:
|
||||
@ -216,7 +216,7 @@ public class BsqFormatter extends BSFormatter {
|
||||
case BTC:
|
||||
return formatBTC(parseParamValueToCoin(param, inputValue));
|
||||
case PERCENT:
|
||||
return formatToPercent(parsePercentStringToDouble(inputValue));
|
||||
return formatToPercent(ParsingUtils.parsePercentStringToDouble(inputValue));
|
||||
case BLOCK:
|
||||
return Integer.toString(parseParamValueToBlocks(param, inputValue));
|
||||
case ADDRESS:
|
||||
|
83
core/src/main/java/bisq/core/util/ParsingUtils.java
Normal file
83
core/src/main/java/bisq/core/util/ParsingUtils.java
Normal file
@ -0,0 +1,83 @@
|
||||
package bisq.core.util;
|
||||
|
||||
import bisq.core.monetary.Price;
|
||||
|
||||
import bisq.common.util.MathUtils;
|
||||
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.utils.MonetaryFormat;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class ParsingUtils {
|
||||
public static Coin parseToCoin(String input, BSFormatter bsFormatter) {
|
||||
return parseToCoin(input, bsFormatter.getMonetaryFormat());
|
||||
}
|
||||
|
||||
public static Coin parseToCoin(String input, MonetaryFormat coinFormat) {
|
||||
if (input != null && input.length() > 0) {
|
||||
try {
|
||||
return coinFormat.parse(cleanDoubleInput(input));
|
||||
} catch (Throwable t) {
|
||||
log.warn("Exception at parseToBtc: " + t.toString());
|
||||
return Coin.ZERO;
|
||||
}
|
||||
} else {
|
||||
return Coin.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
public static double parseNumberStringToDouble(String input) throws NumberFormatException {
|
||||
return Double.parseDouble(cleanDoubleInput(input));
|
||||
}
|
||||
|
||||
public static double parsePercentStringToDouble(String percentString) throws NumberFormatException {
|
||||
String input = percentString.replace("%", "");
|
||||
input = cleanDoubleInput(input);
|
||||
double value = Double.parseDouble(input);
|
||||
return MathUtils.roundDouble(value / 100d, 4);
|
||||
}
|
||||
|
||||
public static long parsePriceStringToLong(String currencyCode, String amount, int precision) {
|
||||
if (amount == null || amount.isEmpty())
|
||||
return 0;
|
||||
|
||||
long value = 0;
|
||||
try {
|
||||
double amountValue = Double.parseDouble(amount);
|
||||
amount = BSFormatter.formatRoundedDoubleWithPrecision(amountValue, precision);
|
||||
value = Price.parse(currencyCode, amount).getValue();
|
||||
} catch (NumberFormatException ignore) {
|
||||
// expected NumberFormatException if input is not a number
|
||||
} catch (Throwable t) {
|
||||
log.error("parsePriceStringToLong: " + t.toString());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String convertCharsForNumber(String input) {
|
||||
// Some languages like finnish use the long dash for the minus
|
||||
input = input.replace("−", "-");
|
||||
input = StringUtils.deleteWhitespace(input);
|
||||
return input.replace(",", ".");
|
||||
}
|
||||
|
||||
public static String cleanDoubleInput(String input) {
|
||||
input = convertCharsForNumber(input);
|
||||
if (input.equals("."))
|
||||
input = input.replace(".", "0.");
|
||||
if (input.equals("-."))
|
||||
input = input.replace("-.", "-0.");
|
||||
// don't use String.valueOf(Double.parseDouble(input)) as return value as it gives scientific
|
||||
// notation (1.0E-6) which screw up coinFormat.parse
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
// Just called to check if we have a valid double, throws exception otherwise
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
Double.parseDouble(input);
|
||||
return input;
|
||||
}
|
||||
}
|
@ -503,7 +503,7 @@ takeOffer.failed.offerTaken=You cannot take that offer because the offer was alr
|
||||
takeOffer.failed.offerRemoved=You cannot take that offer because the offer has been removed in the meantime.
|
||||
takeOffer.failed.offererNotOnline=Take offer request failed because maker is not online anymore.
|
||||
takeOffer.failed.offererOffline=You cannot take that offer because the maker is offline.
|
||||
takeOffer.warning.connectionToPeerLost=You lost connection to the maker.\nHe might have gone offline or has closed the connection to you because of too many open connections.\n\nIf you can still see his offer in the offerbook you can try to take the offer again.
|
||||
takeOffer.warning.connectionToPeerLost=You lost connection to the maker.\nThey might have gone offline or has closed the connection to you because of too many open connections.\n\nIf you can still see their offer in the offerbook you can try to take the offer again.
|
||||
|
||||
takeOffer.error.noFundsLost=\n\nNo funds have left your wallet yet.\nPlease try to restart your application and check your network connection to see if you can resolve the issue.
|
||||
takeOffer.error.feePaid=\n\nPlease try to restart your application and check your network connection to see if you can resolve the issue.
|
||||
@ -606,7 +606,7 @@ portfolio.pending.step2_seller.waitPayment.headline=Wait for payment
|
||||
portfolio.pending.step2_seller.f2fInfo.headline=Buyer's contact information
|
||||
portfolio.pending.step2_seller.waitPayment.msg=The deposit transaction has at least one blockchain confirmation.\nYou need to wait until the BTC buyer starts the {0} payment.
|
||||
portfolio.pending.step2_seller.warn=The BTC buyer still has not done the {0} payment.\nYou need to wait until they have started the payment.\nIf the trade has not been completed on {1} the arbitrator will investigate.
|
||||
portfolio.pending.step2_seller.openForDispute=The BTC buyer has not started his payment!\nThe max. allowed period for the trade has elapsed.\nYou can wait longer and give the trading peer more time or contact the arbitrator for opening a dispute.
|
||||
portfolio.pending.step2_seller.openForDispute=The BTC buyer has not started their payment!\nThe max. allowed period for the trade has elapsed.\nYou can wait longer and give the trading peer more time or contact the arbitrator for opening a dispute.
|
||||
|
||||
tradeChat.chatWindowTitle=Chat window for trade with ID ''{0}''
|
||||
tradeChat.openChat=Open chat window
|
||||
@ -742,7 +742,7 @@ portfolio.pending.disputeOpened=Dispute opened
|
||||
portfolio.pending.openSupport=Open support ticket
|
||||
portfolio.pending.supportTicketOpened=Support ticket opened
|
||||
portfolio.pending.requestSupport=Request support
|
||||
portfolio.pending.error.requestSupport=Please report the problem to your arbitrator.\n\nHe will forward the information to the developers to investigate the problem.\nAfter the problem has been analyzed you will get back all locked funds.
|
||||
portfolio.pending.error.requestSupport=Please report the problem to your arbitrator.\n\nThey will forward the information to the developers to investigate the problem.\nAfter the problem has been analyzed you will get back all locked funds.
|
||||
portfolio.pending.communicateWithArbitrator=Please communicate in the \"Support\" screen with the arbitrator.
|
||||
portfolio.pending.supportTicketOpenedMyUser=You opened already a support ticket.\n{0}
|
||||
portfolio.pending.disputeOpenedMyUser=You opened already a dispute.\n{0}
|
||||
@ -848,7 +848,7 @@ support.filter=Filter list
|
||||
support.filter.prompt=Enter trade ID, date, onion address or account data
|
||||
support.noTickets=There are no open tickets
|
||||
support.sendingMessage=Sending Message...
|
||||
support.receiverNotOnline=Receiver is not online. Message is saved to his mailbox.
|
||||
support.receiverNotOnline=Receiver is not online. Message is saved to their mailbox.
|
||||
support.sendMessageError=Sending message failed. Error: {0}
|
||||
support.wrongVersion=The offer in that dispute has been created with an older version of Bisq.\n\
|
||||
You cannot close that dispute with your version of the application.\n\n\
|
||||
@ -1078,7 +1078,7 @@ account.arbitratorSelection.whichDoYouAccept=Which arbitrators do you accept
|
||||
account.arbitratorSelection.autoSelect=Auto select all arbitrators with matching language
|
||||
account.arbitratorSelection.regDate=Registration date
|
||||
account.arbitratorSelection.languages=Languages
|
||||
account.arbitratorSelection.cannotSelectHimself=An arbitrator cannot select himself for trading.
|
||||
account.arbitratorSelection.cannotSelectHimself=An arbitrator cannot select themselves for trading.
|
||||
account.arbitratorSelection.noMatchingLang=No matching language.
|
||||
account.arbitratorSelection.noLang=You can only select arbitrators who are speaking at least 1 common language.
|
||||
account.arbitratorSelection.minOne=You need to have at least one arbitrator selected.
|
||||
@ -2804,7 +2804,6 @@ payment.f2f.info.openURL=Open web page
|
||||
payment.f2f.offerbook.tooltip.countryAndCity=Country and city: {0} / {1}
|
||||
payment.f2f.offerbook.tooltip.extra=Additional information: {0}
|
||||
|
||||
|
||||
# We use constants from the code so we do not use our normal naming convention
|
||||
# dynamic values are not recognized by IntelliJ
|
||||
|
||||
@ -2817,6 +2816,7 @@ CASH_DEPOSIT=Cash Deposit
|
||||
MONEY_GRAM=MoneyGram
|
||||
WESTERN_UNION=Western Union
|
||||
F2F=Face to face (in person)
|
||||
JAPAN_BANK=Japan Zengin Furikomi
|
||||
|
||||
# suppress inspection "UnusedProperty"
|
||||
NATIONAL_BANK_SHORT=National banks
|
||||
@ -2834,6 +2834,8 @@ MONEY_GRAM_SHORT=MoneyGram
|
||||
WESTERN_UNION_SHORT=Western Union
|
||||
# suppress inspection "UnusedProperty"
|
||||
F2F_SHORT=F2F
|
||||
# suppress inspection "UnusedProperty"
|
||||
JAPAN_BANK_SHORT=Japan Furikomi
|
||||
|
||||
# Do not translate brand names
|
||||
# suppress inspection "UnusedProperty"
|
||||
|
@ -2317,6 +2317,7 @@ CASH_DEPOSIT=現金入金
|
||||
MONEY_GRAM=MoneyGram
|
||||
WESTERN_UNION=Western Union
|
||||
F2F=対面(直接)
|
||||
JAPAN_BANK=日本全銀振込
|
||||
|
||||
# suppress inspection "UnusedProperty"
|
||||
NATIONAL_BANK_SHORT=国立銀行
|
||||
@ -2334,6 +2335,8 @@ MONEY_GRAM_SHORT=MoneyGram
|
||||
WESTERN_UNION_SHORT=Western Union
|
||||
# suppress inspection "UnusedProperty"
|
||||
F2F_SHORT=対面
|
||||
# suppress inspection "UnusedProperty"
|
||||
JAPAN_BANK_SHORT=日本全銀振込
|
||||
|
||||
# Do not translate brand names
|
||||
# suppress inspection "UnusedProperty"
|
||||
|
2501
core/src/main/resources/i18n/displayStrings_pt_BR.properties
Normal file
2501
core/src/main/resources/i18n/displayStrings_pt_BR.properties
Normal file
File diff suppressed because it is too large
Load Diff
@ -44,7 +44,7 @@ public class ArbitratorTest {
|
||||
return new Arbitrator(new NodeAddress("host", 1000),
|
||||
getBytes(100),
|
||||
"btcaddress",
|
||||
new PubKeyRing(getBytes(100), getBytes(100), "key"),
|
||||
new PubKeyRing(getBytes(100), getBytes(100)),
|
||||
Lists.newArrayList(),
|
||||
new Date().getTime(),
|
||||
getBytes(100),
|
||||
@ -56,4 +56,3 @@ public class ArbitratorTest {
|
||||
return RandomUtils.nextBytes(count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class MediatorTest {
|
||||
|
||||
public static Mediator getMediatorMock() {
|
||||
return new Mediator(new NodeAddress("host", 1000),
|
||||
new PubKeyRing(getBytes(100), getBytes(100), "key"),
|
||||
new PubKeyRing(getBytes(100), getBytes(100)),
|
||||
Lists.newArrayList(),
|
||||
new Date().getTime(),
|
||||
getBytes(100),
|
||||
@ -51,6 +51,4 @@ public class MediatorTest {
|
||||
"info",
|
||||
null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -22,11 +22,8 @@ import bisq.common.crypto.KeyRing;
|
||||
import bisq.common.crypto.KeyStorage;
|
||||
import bisq.common.storage.FileUtil;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import java.io.File;
|
||||
@ -62,5 +59,3 @@ public class EncryptionTest {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd $(dirname $0)
|
||||
tx pull -l de,el_GR,es,ja,pt,ru,zh_CN,vi,th_TH,fa,fr
|
||||
tx pull -l de,el_GR,es,ja,pt,ru,zh_CN,vi,th_TH,fa,fr,pt_BR
|
||||
|
||||
translations="translations/bisq-desktop.displaystringsproperties"
|
||||
i18n="src/main/resources/i18n"
|
||||
@ -17,5 +17,6 @@ mv "$translations/vi.properties" "$i18n/displayStrings_vi.properties"
|
||||
mv "$translations/th_TH.properties" "$i18n/displayStrings_th.properties"
|
||||
mv "$translations/fa.properties" "$i18n/displayStrings_fa.properties"
|
||||
mv "$translations/fr.properties" "$i18n/displayStrings_fr.properties"
|
||||
mv "$translations/pt_BR.properties" "$i18n/displayStrings_pt_BR.properties"
|
||||
|
||||
rm -rf $translations
|
||||
|
43
desktop/package/macosx/create_desktop_for_testing.sh
Executable file
43
desktop/package/macosx/create_desktop_for_testing.sh
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd $(dirname $0)/../../
|
||||
|
||||
mkdir -p deploy
|
||||
|
||||
set -e
|
||||
|
||||
version="1.1.5-SNAPSHOT"
|
||||
commithash="ec633f0c3771893b47956b8d05b17c6f3f1919c1"
|
||||
|
||||
cd ..
|
||||
./gradlew :desktop:build -x test shadowJar
|
||||
cd desktop
|
||||
|
||||
EXE_JAR=build/libs/desktop-$version-all.jar
|
||||
JAR_WITH_HASH_NAME=desktop-$version-$commithash-all.jar
|
||||
EXE_JAR_WITH_HASH=build/libs/$JAR_WITH_HASH_NAME
|
||||
DEPLOY_JAR=deploy/$JAR_WITH_HASH_NAME
|
||||
|
||||
# we need to strip out Java 9 module configuration used in the fontawesomefx library as it causes the javapackager to stop,
|
||||
# because of this existing module information, although it is not used as a module.
|
||||
echo Unzipping jar to delete module config
|
||||
tmp=build/libs/tmp
|
||||
unzip -o -q $EXE_JAR -d $tmp
|
||||
|
||||
# Sometimes $tmp/module-info.class is not available. TODO check why and if still needed
|
||||
rm -f $tmp/module-info.class
|
||||
|
||||
rm $EXE_JAR
|
||||
echo Zipping jar again without module config
|
||||
cd $tmp; zip -r -q -X "../$JAR_WITH_HASH_NAME" *
|
||||
cd ../../../; rm -rf $tmp
|
||||
|
||||
cp $EXE_JAR_WITH_HASH $DEPLOY_JAR
|
||||
|
||||
echo Create signature
|
||||
gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $DEPLOY_JAR.asc --detach-sig --armor $DEPLOY_JAR
|
||||
|
||||
echo Verify signatures
|
||||
gpg --digest-algo SHA256 --verify $DEPLOY_JAR{.asc*,}
|
||||
|
||||
open deploy
|
43
desktop/package/macosx/create_seednode_for_testing.sh
Executable file
43
desktop/package/macosx/create_seednode_for_testing.sh
Executable file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd $(dirname $0)/../../
|
||||
|
||||
set -e
|
||||
|
||||
version="1.1.5-SNAPSHOT"
|
||||
commithash="ec633f0c3771893b47956b8d05b17c6f3f1919c1"
|
||||
|
||||
cd ..
|
||||
./gradlew :seednode:build -x test shadowJar
|
||||
cd seednode
|
||||
|
||||
mkdir -p deploy
|
||||
|
||||
EXE_JAR=build/libs/seednode-all.jar
|
||||
JAR_WITH_HASH_NAME=seednode-$version-$commithash-all.jar
|
||||
EXE_JAR_WITH_HASH=build/libs/$JAR_WITH_HASH_NAME
|
||||
DEPLOY_JAR=deploy/$JAR_WITH_HASH_NAME
|
||||
|
||||
# we need to strip out Java 9 module configuration used in the fontawesomefx library as it causes the javapackager to stop,
|
||||
# because of this existing module information, although it is not used as a module.
|
||||
echo Unzipping jar to delete module config
|
||||
tmp=build/libs/tmp
|
||||
unzip -o -q $EXE_JAR -d $tmp
|
||||
|
||||
# Sometimes $tmp/module-info.class is not available. TODO check why and if still needed
|
||||
rm -f $tmp/module-info.class
|
||||
|
||||
rm $EXE_JAR
|
||||
echo Zipping jar again without module config
|
||||
cd $tmp; zip -r -q -X "../$JAR_WITH_HASH_NAME" *
|
||||
cd ../../../; rm -rf $tmp
|
||||
|
||||
cp $EXE_JAR_WITH_HASH $DEPLOY_JAR
|
||||
|
||||
echo Create signature
|
||||
gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $DEPLOY_JAR.asc --detach-sig --armor $DEPLOY_JAR
|
||||
|
||||
echo Verify signatures
|
||||
gpg --digest-algo SHA256 --verify $DEPLOY_JAR{.asc*,}
|
||||
|
||||
open deploy
|
@ -1389,6 +1389,30 @@ textfield */
|
||||
-fx-fill: -bs-color-primary-dark;
|
||||
}
|
||||
|
||||
.trade-msg-state-undefined {
|
||||
-fx-text-fill: -bs-yellow;
|
||||
}
|
||||
|
||||
.trade-msg-state-sent {
|
||||
-fx-text-fill: -bs-yellow-light;
|
||||
}
|
||||
|
||||
.trade-msg-state-arrived {
|
||||
-fx-text-fill: -bs-turquoise;
|
||||
}
|
||||
|
||||
.trade-msg-state-stored {
|
||||
-fx-text-fill: -bs-color-blue-4;
|
||||
}
|
||||
|
||||
.trade-msg-state-acknowledged {
|
||||
-fx-text-fill: -bs-color-primary;
|
||||
}
|
||||
|
||||
.trade-msg-state-failed {
|
||||
-fx-text-fill: -bs-rd-error-red;
|
||||
}
|
||||
|
||||
#open-support-button {
|
||||
-fx-font-weight: bold;
|
||||
-fx-font-size: 1.077em;
|
||||
@ -1547,6 +1571,7 @@ textfield */
|
||||
#charts .axis, #price-chart .axis, #volume-chart .axis, #charts-dao .axis {
|
||||
-fx-tick-label-fill: -bs-rd-font-lighter;
|
||||
-fx-tick-label-font-size: 0.769em;
|
||||
-fx-font-size: 0.880em;
|
||||
}
|
||||
|
||||
#charts .chart-plot-background, #charts-dao .chart-plot-background {
|
||||
@ -1576,6 +1601,9 @@ textfield */
|
||||
#charts .default-color1.chart-series-area-fill, #charts-dao .default-color0.chart-series-area-fill {
|
||||
-fx-fill: -bs-buy-transparent;
|
||||
}
|
||||
.chart-vertical-grid-lines {
|
||||
-fx-stroke: transparent;
|
||||
}
|
||||
|
||||
#charts .axis-label {
|
||||
-fx-font-size: 0.769em;
|
||||
@ -1995,3 +2023,7 @@ textfield */
|
||||
-fx-background-color: -bs-red-soft;
|
||||
-fx-text-fill: -bs-background-color;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
-fx-text-fill: -fx-faint-focus-color;
|
||||
}
|
||||
|
@ -33,13 +33,13 @@ public class ColoredDecimalPlacesWithZerosText extends HBox {
|
||||
super();
|
||||
|
||||
if (numberOfZerosToColorize <= 0) {
|
||||
getChildren().addAll(new Text(number));
|
||||
getChildren().addAll(new Label(number));
|
||||
} else if (number.contains(BSFormatter.RANGE_SEPARATOR)) {
|
||||
String[] splitNumber = number.split(BSFormatter.RANGE_SEPARATOR);
|
||||
Tuple2<Label, Label> numbers = getSplittedNumberNodes(splitNumber[0], numberOfZerosToColorize);
|
||||
getChildren().addAll(numbers.first, numbers.second);
|
||||
|
||||
getChildren().add(new Text(BSFormatter.RANGE_SEPARATOR));
|
||||
getChildren().add(new Label(BSFormatter.RANGE_SEPARATOR));
|
||||
|
||||
numbers = getSplittedNumberNodes(splitNumber[1], numberOfZerosToColorize);
|
||||
getChildren().addAll(numbers.first, numbers.second);
|
||||
|
@ -18,6 +18,7 @@
|
||||
package bisq.desktop.components;
|
||||
|
||||
import bisq.desktop.main.overlays.editor.PeerInfoWithTagEditor;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.alert.PrivateNotificationManager;
|
||||
@ -141,7 +142,7 @@ public class PeerInfoIcon extends Group {
|
||||
boolean isFiatCurrency = CurrencyUtil.isFiatCurrency(offer.getCurrencyCode());
|
||||
|
||||
String accountAge = isFiatCurrency ?
|
||||
peersAccountAge > -1 ? Res.get("peerInfoIcon.tooltip.age", formatter.formatAccountAge(peersAccountAge)) :
|
||||
peersAccountAge > -1 ? Res.get("peerInfoIcon.tooltip.age", DisplayUtils.formatAccountAge(peersAccountAge)) :
|
||||
Res.get("peerInfoIcon.tooltip.unknownAge") :
|
||||
"";
|
||||
tooltipText = hasTraded ?
|
||||
@ -268,7 +269,7 @@ public class PeerInfoIcon extends Group {
|
||||
long makersAccountAge) {
|
||||
final String accountAgeTagEditor = isFiatCurrency ?
|
||||
makersAccountAge > -1 ?
|
||||
formatter.formatAccountAge(makersAccountAge) :
|
||||
DisplayUtils.formatAccountAge(makersAccountAge) :
|
||||
Res.get("peerInfo.unknownAge") :
|
||||
null;
|
||||
setOnMouseClicked(e -> new PeerInfoWithTagEditor(privateNotificationManager, offer, preferences, useDevPrivilegeKeys)
|
||||
|
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.components.paymentmethods;
|
||||
|
||||
import bisq.common.util.Tuple2;
|
||||
import bisq.common.util.Tuple3;
|
||||
import bisq.common.util.Tuple4;
|
||||
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.components.AutocompleteComboBox;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.validation.LengthValidator;
|
||||
import bisq.desktop.util.validation.RegexValidator;
|
||||
import bisq.desktop.util.validation.JapanBankTransferValidator;
|
||||
import bisq.desktop.util.validation.JapanBankBranchCodeValidator;
|
||||
import bisq.desktop.util.validation.JapanBankBranchNameValidator;
|
||||
import bisq.desktop.util.validation.JapanBankAccountNumberValidator;
|
||||
import bisq.desktop.util.validation.JapanBankAccountNameValidator;
|
||||
import bisq.desktop.components.paymentmethods.data.JapanBankData;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.locale.TradeCurrency;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.JapanBankAccount;
|
||||
import bisq.core.payment.payload.PaymentAccountPayload;
|
||||
import bisq.core.payment.payload.JapanBankAccountPayload;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.validation.InputValidator;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import static bisq.desktop.util.FormBuilder.*;
|
||||
import static bisq.desktop.util.GUIUtil.getComboBoxButtonCell;
|
||||
|
||||
public class JapanBankTransferForm extends PaymentMethodForm
|
||||
{
|
||||
private final JapanBankAccount japanBankAccount;
|
||||
protected ComboBox<String> bankComboBox, bankAccountTypeComboBox;
|
||||
private InputTextField bankAccountNumberInputTextField;
|
||||
|
||||
private JapanBankTransferValidator japanBankTransferValidator;
|
||||
private JapanBankBranchNameValidator japanBankBranchNameValidator;
|
||||
private JapanBankBranchCodeValidator japanBankBranchCodeValidator;
|
||||
private JapanBankAccountNameValidator japanBankAccountNameValidator;
|
||||
private JapanBankAccountNumberValidator japanBankAccountNumberValidator;
|
||||
|
||||
private LengthValidator lengthValidator;
|
||||
private RegexValidator regexValidator;
|
||||
|
||||
public static int addFormForBuyer(GridPane gridPane, int gridRow, // {{{
|
||||
PaymentAccountPayload paymentAccountPayload)
|
||||
{
|
||||
JapanBankAccountPayload japanBankAccount = ((JapanBankAccountPayload) paymentAccountPayload);
|
||||
|
||||
addCompactTopLabelTextFieldWithCopyIcon(gridPane, ++gridRow,
|
||||
JapanBankData.getString("payment.account.owner"),
|
||||
((JapanBankAccountPayload) paymentAccountPayload).getBankName());
|
||||
|
||||
TextField bankCodeTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("bank.code"), japanBankAccount.getBankCode()).second;
|
||||
bankCodeTextField.setPrefWidth(30);
|
||||
bankCodeTextField.setEditable(false);
|
||||
|
||||
TextField bankNameTextField = addCompactTopLabelTextField(gridPane, gridRow, 1, JapanBankData.getString("bank.name"), japanBankAccount.getBankName()).second;
|
||||
bankNameTextField.setPrefWidth(70);
|
||||
bankNameTextField.setEditable(false);
|
||||
|
||||
TextField branchCodeTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("branch.code"), japanBankAccount.getBankBranchCode()).second;
|
||||
branchCodeTextField.setPrefWidth(30);
|
||||
branchCodeTextField.setEditable(false);
|
||||
|
||||
TextField branchNameTextField = addCompactTopLabelTextField(gridPane, ++gridRow, 1, JapanBankData.getString("branch.name"), japanBankAccount.getBankBranchName()).second;
|
||||
branchNameTextField.setPrefWidth(70);
|
||||
branchNameTextField.setEditable(false);
|
||||
|
||||
TextField accountNumberTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("account.number"), japanBankAccount.getBankAccountNumber()).second;
|
||||
accountNumberTextField.setPrefWidth(30);
|
||||
accountNumberTextField.setEditable(false);
|
||||
|
||||
TextField accountNameTextField = addCompactTopLabelTextField(gridPane, gridRow, 1, JapanBankData.getString("account.name"), japanBankAccount.getBankAccountName()).second;
|
||||
accountNameTextField.setPrefWidth(70);
|
||||
accountNameTextField.setEditable(false);
|
||||
|
||||
return gridRow;
|
||||
} // }}}
|
||||
|
||||
public JapanBankTransferForm(PaymentAccount paymentAccount,
|
||||
AccountAgeWitnessService accountAgeWitnessService,
|
||||
JapanBankTransferValidator japanBankTransferValidator,
|
||||
InputValidator inputValidator, GridPane gridPane,
|
||||
int gridRow, BSFormatter formatter)
|
||||
{
|
||||
super(paymentAccount, accountAgeWitnessService, inputValidator, gridPane, gridRow, formatter);
|
||||
this.japanBankAccount = (JapanBankAccount) paymentAccount;
|
||||
|
||||
this.japanBankTransferValidator = japanBankTransferValidator;
|
||||
this.japanBankBranchCodeValidator = new JapanBankBranchCodeValidator();
|
||||
this.japanBankAccountNumberValidator = new JapanBankAccountNumberValidator();
|
||||
|
||||
this.lengthValidator = new LengthValidator();
|
||||
this.regexValidator = new RegexValidator();
|
||||
this.japanBankBranchNameValidator = new JapanBankBranchNameValidator(lengthValidator, regexValidator);
|
||||
this.japanBankAccountNameValidator = new JapanBankAccountNameValidator(lengthValidator, regexValidator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFormForDisplayAccount() // {{{
|
||||
{
|
||||
gridRowFrom = gridRow;
|
||||
|
||||
addTopLabelTextField(gridPane, ++gridRow, Res.get("payment.account.name"),
|
||||
japanBankAccount.getAccountName(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
|
||||
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("shared.paymentMethod"),
|
||||
Res.get(japanBankAccount.getPaymentMethod().getId()));
|
||||
|
||||
addBankDisplay();
|
||||
addBankBranchDisplay();
|
||||
addBankAccountDisplay();
|
||||
addBankAccountTypeDisplay();
|
||||
|
||||
addLimitations(true);
|
||||
} // }}}
|
||||
private void addBankDisplay() // {{{
|
||||
{
|
||||
String bankText = japanBankAccount.getBankCode() + " " + japanBankAccount.getBankName();
|
||||
TextField bankTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("bank"), bankText).second;
|
||||
bankTextField.setEditable(false);
|
||||
} // }}}
|
||||
private void addBankBranchDisplay() // {{{
|
||||
{
|
||||
String branchText = japanBankAccount.getBankBranchCode() + " " + japanBankAccount.getBankBranchName();
|
||||
TextField branchTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("branch"), branchText).second;
|
||||
branchTextField.setEditable(false);
|
||||
} // }}}
|
||||
private void addBankAccountDisplay() // {{{
|
||||
{
|
||||
String accountText = japanBankAccount.getBankAccountNumber() + " " + japanBankAccount.getBankAccountName();
|
||||
TextField accountTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("account"), accountText).second;
|
||||
accountTextField.setEditable(false);
|
||||
} // }}}
|
||||
private void addBankAccountTypeDisplay() // {{{
|
||||
{
|
||||
TradeCurrency singleTradeCurrency = japanBankAccount.getSingleTradeCurrency();
|
||||
String currency = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : "null";
|
||||
String accountTypeText = currency + " " + japanBankAccount.getBankAccountType();
|
||||
TextField accountTypeTextField = addCompactTopLabelTextField(gridPane, ++gridRow, JapanBankData.getString("account.type"), accountTypeText).second;
|
||||
accountTypeTextField.setEditable(false);
|
||||
} // }}}
|
||||
|
||||
@Override
|
||||
public void addFormForAddAccount() // {{{
|
||||
{
|
||||
gridRowFrom = gridRow;
|
||||
|
||||
addBankInput();
|
||||
addBankBranchInput();
|
||||
addBankAccountInput();
|
||||
addBankAccountTypeInput();
|
||||
|
||||
addLimitations(false);
|
||||
addAccountNameTextFieldWithAutoFillToggleButton();
|
||||
} // }}}
|
||||
private void addBankInput() // {{{
|
||||
{
|
||||
gridRow++;
|
||||
|
||||
Tuple4<Label, TextField, Label, ComboBox<String>> tuple4 = addTopLabelTextFieldAutocompleteComboBox(gridPane, gridRow, JapanBankData.getString("bank.code"), JapanBankData.getString("bank.name"), 10);
|
||||
|
||||
// Bank Code (readonly)
|
||||
TextField bankCodeField = tuple4.second;
|
||||
bankCodeField.setPrefWidth(175);
|
||||
bankCodeField.setMaxWidth(175);
|
||||
bankCodeField.setEditable(false);
|
||||
|
||||
// Bank Selector
|
||||
bankComboBox = tuple4.forth;
|
||||
bankComboBox.setPromptText(JapanBankData.getString("bank.select"));
|
||||
bankComboBox.setButtonCell(getComboBoxButtonCell(JapanBankData.getString("bank.name"), bankComboBox));
|
||||
bankComboBox.getEditor().focusedProperty().addListener(observable -> {
|
||||
bankComboBox.setPromptText("");
|
||||
});
|
||||
bankComboBox.setConverter(new StringConverter<String>() {
|
||||
@Override
|
||||
public String toString(String bank) {
|
||||
return bank != null ? bank : "";
|
||||
}
|
||||
public String fromString(String s) {
|
||||
return s != null ? s : "";
|
||||
}
|
||||
});
|
||||
((AutocompleteComboBox) bankComboBox).setAutocompleteItems(JapanBankData.prettyPrintBankList());
|
||||
|
||||
bankComboBox.setPrefWidth(425);
|
||||
bankComboBox.setVisibleRowCount(425);
|
||||
|
||||
((AutocompleteComboBox) bankComboBox).setOnChangeConfirmed(e -> {
|
||||
// get selected value
|
||||
String bank = bankComboBox.getSelectionModel().getSelectedItem();
|
||||
|
||||
// parse first 4 characters as bank code
|
||||
String bankCode = StringUtils.substring(bank, 0, 4);
|
||||
if (bankCode != null)
|
||||
{
|
||||
// set bank code field to this value
|
||||
bankCodeField.setText(bankCode);
|
||||
// save to payload
|
||||
japanBankAccount.setBankCode(bankCode);
|
||||
|
||||
// parse remainder as bank name
|
||||
String bankNameFull = StringUtils.substringAfter(bank, JapanBankData.SPACE);
|
||||
if (bankNameFull != null)
|
||||
{
|
||||
// parse beginning as japanese bank name
|
||||
String bankNameJa = StringUtils.substringBefore(bankNameFull, JapanBankData.SPACE);
|
||||
if (bankNameJa != null)
|
||||
{
|
||||
// set bank name field to this value
|
||||
bankComboBox.getEditor().setText(bankNameJa);
|
||||
// save to payload
|
||||
japanBankAccount.setBankName(bankNameJa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateFromInputs();
|
||||
});
|
||||
} // }}}
|
||||
private void addBankBranchInput() // {{{
|
||||
{
|
||||
gridRow++;
|
||||
Tuple2<InputTextField, InputTextField> tuple2 = addInputTextFieldInputTextField(gridPane, gridRow, JapanBankData.getString("branch.code"), JapanBankData.getString("branch.name"));
|
||||
|
||||
// branch code
|
||||
InputTextField bankBranchCodeInputTextField = tuple2.first;
|
||||
bankBranchCodeInputTextField.setValidator(japanBankBranchCodeValidator);
|
||||
bankBranchCodeInputTextField.setPrefWidth(175);
|
||||
bankBranchCodeInputTextField.setMaxWidth(175);
|
||||
bankBranchCodeInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
japanBankAccount.setBankBranchCode(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
|
||||
// branch name
|
||||
InputTextField bankBranchNameInputTextField = tuple2.second;
|
||||
bankBranchNameInputTextField.setValidator(japanBankBranchNameValidator);
|
||||
bankBranchNameInputTextField.setPrefWidth(425);
|
||||
bankBranchNameInputTextField.setMaxWidth(425);
|
||||
bankBranchNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
japanBankAccount.setBankBranchName(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
} // }}}
|
||||
private void addBankAccountInput() // {{{
|
||||
{
|
||||
gridRow++;
|
||||
Tuple2<InputTextField, InputTextField> tuple2 = addInputTextFieldInputTextField(gridPane, gridRow, JapanBankData.getString("account.number"), JapanBankData.getString("account.name"));
|
||||
|
||||
// account number
|
||||
bankAccountNumberInputTextField = tuple2.first;
|
||||
bankAccountNumberInputTextField.setValidator(japanBankAccountNumberValidator);
|
||||
bankAccountNumberInputTextField.setPrefWidth(175);
|
||||
bankAccountNumberInputTextField.setMaxWidth(175);
|
||||
bankAccountNumberInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
japanBankAccount.setBankAccountNumber(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
|
||||
// account name
|
||||
InputTextField bankAccountNameInputTextField = tuple2.second;
|
||||
bankAccountNameInputTextField.setValidator(japanBankAccountNameValidator);
|
||||
bankAccountNameInputTextField.setPrefWidth(425);
|
||||
bankAccountNameInputTextField.setMaxWidth(425);
|
||||
bankAccountNameInputTextField.textProperty().addListener((ov, oldValue, newValue) -> {
|
||||
japanBankAccount.setBankAccountName(newValue);
|
||||
updateFromInputs();
|
||||
});
|
||||
} // }}}
|
||||
private void addBankAccountTypeInput() // {{{
|
||||
{
|
||||
// account currency
|
||||
gridRow++;
|
||||
|
||||
TradeCurrency singleTradeCurrency = japanBankAccount.getSingleTradeCurrency();
|
||||
String nameAndCode = singleTradeCurrency != null ? singleTradeCurrency.getNameAndCode() : "null";
|
||||
addCompactTopLabelTextField(gridPane, gridRow, Res.get("shared.currency"), nameAndCode);
|
||||
|
||||
// account type
|
||||
gridRow++;
|
||||
|
||||
ToggleGroup toggleGroup = new ToggleGroup();
|
||||
Tuple3<Label, RadioButton, RadioButton> tuple3 =
|
||||
addTopLabelRadioButtonRadioButton(
|
||||
gridPane, gridRow, toggleGroup,
|
||||
JapanBankData.getString("account.type.select"),
|
||||
JapanBankData.getString("account.type.futsu"),
|
||||
JapanBankData.getString("account.type.touza"),
|
||||
0
|
||||
);
|
||||
|
||||
toggleGroup.getToggles().get(0).setSelected(true);
|
||||
japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.futsu.ja"));
|
||||
|
||||
RadioButton futsu = tuple3.second;
|
||||
RadioButton touza = tuple3.third;
|
||||
|
||||
toggleGroup.selectedToggleProperty().addListener
|
||||
(
|
||||
(ov, oldValue, newValue) ->
|
||||
{
|
||||
if (futsu.isSelected())
|
||||
japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.futsu.ja"));
|
||||
if (touza.isSelected())
|
||||
japanBankAccount.setBankAccountType(JapanBankData.getString("account.type.touza.ja"));
|
||||
}
|
||||
);
|
||||
} // }}}
|
||||
|
||||
@Override
|
||||
public void updateFromInputs() // {{{
|
||||
{
|
||||
System.out.println("JapanBankTransferForm: updateFromInputs()");
|
||||
System.out.println("bankName: "+japanBankAccount.getBankName());
|
||||
System.out.println("bankCode: "+japanBankAccount.getBankCode());
|
||||
System.out.println("bankBranchName: "+japanBankAccount.getBankBranchName());
|
||||
System.out.println("bankBranchCode: "+japanBankAccount.getBankBranchCode());
|
||||
System.out.println("bankAccountType: "+japanBankAccount.getBankAccountType());
|
||||
System.out.println("bankAccountName: "+japanBankAccount.getBankAccountName());
|
||||
System.out.println("bankAccountNumber: "+japanBankAccount.getBankAccountNumber());
|
||||
super.updateFromInputs();
|
||||
} // }}}
|
||||
|
||||
@Override
|
||||
protected void autoFillNameTextField() // {{{
|
||||
{
|
||||
if (useCustomAccountNameToggleButton != null && !useCustomAccountNameToggleButton.isSelected())
|
||||
{
|
||||
accountNameTextField.setText(
|
||||
Res.get(paymentAccount.getPaymentMethod().getId())
|
||||
.concat(": ")
|
||||
.concat(japanBankAccount.getBankName())
|
||||
.concat(" ")
|
||||
.concat(japanBankAccount.getBankBranchName())
|
||||
.concat(" ")
|
||||
.concat(japanBankAccount.getBankAccountNumber())
|
||||
.concat(" ")
|
||||
.concat(japanBankAccount.getBankAccountName())
|
||||
);
|
||||
}
|
||||
} // }}}
|
||||
|
||||
@Override
|
||||
public void updateAllInputsValid() // {{{
|
||||
{
|
||||
boolean result =
|
||||
(
|
||||
isAccountNameValid() &&
|
||||
inputValidator.validate(japanBankAccount.getBankCode()).isValid &&
|
||||
inputValidator.validate(japanBankAccount.getBankName()).isValid &&
|
||||
japanBankBranchCodeValidator.validate(japanBankAccount.getBankBranchCode()).isValid &&
|
||||
japanBankBranchNameValidator.validate(japanBankAccount.getBankBranchName()).isValid &&
|
||||
japanBankAccountNumberValidator.validate(japanBankAccount.getBankAccountNumber()).isValid &&
|
||||
japanBankAccountNameValidator.validate(japanBankAccount.getBankAccountName()).isValid &&
|
||||
inputValidator.validate(japanBankAccount.getBankAccountType()).isValid
|
||||
);
|
||||
allInputsValid.set(result);
|
||||
} // }}}
|
||||
}
|
||||
|
||||
// vim:ts=4:sw=4:expandtab:foldmethod=marker:nowrap:
|
@ -21,6 +21,7 @@ import bisq.desktop.components.AutoTooltipCheckBox;
|
||||
import bisq.desktop.components.InfoTextField;
|
||||
import bisq.desktop.components.InputTextField;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.Layout;
|
||||
|
||||
@ -182,7 +183,7 @@ public abstract class PaymentMethodForm {
|
||||
Res.get("payment.maxPeriodAndLimit",
|
||||
getTimeText(hours),
|
||||
formatter.formatCoinWithCode(Coin.valueOf(accountAgeWitnessService.getMyTradeLimit(paymentAccount, tradeCurrency.getCode()))),
|
||||
formatter.formatAccountAge(accountAge));
|
||||
DisplayUtils.formatAccountAge(accountAge));
|
||||
|
||||
if (isDisplayForm)
|
||||
addCompactTopLabelTextField(gridPane, ++gridRow, Res.get("payment.limitations"), limitationsText);
|
||||
|
@ -0,0 +1,885 @@
|
||||
/*
|
||||
* This file is part of Bisq.
|
||||
*
|
||||
* Bisq is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bisq is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.desktop.components.paymentmethods.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import bisq.core.locale.Country;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
/*
|
||||
Japan's National Banking Association assigns 4 digit codes to all
|
||||
Financial Institutions, so we use that as the primary "Bank ID",
|
||||
add the English names for the top ~30 major international banks,
|
||||
and remove local farmers agricultural cooperative associations
|
||||
to keep the list to a reasonable size. Please update annually.
|
||||
|
||||
Source: Zengin Net list of Financial Institutions
|
||||
Last Updated: July 16, 2019
|
||||
URL: https://www.zengin-net.jp/company/member/
|
||||
PDF: https://www.zengin-net.jp/company/pdf/member1.pdf
|
||||
PDF: https://www.zengin-net.jp/company/pdf/member2.pdf
|
||||
|
||||
Source: Bank of Japan list of Financial Institutions
|
||||
Last Updated: July 16, 2019
|
||||
URL: https://www5.boj.or.jp/bojnet/codenew/mokujinew.htm
|
||||
File: code1_20190716.xlsx
|
||||
Excel sheet: 金融機関等コード一覧
|
||||
*/
|
||||
|
||||
public class JapanBankData
|
||||
{
|
||||
/*
|
||||
Returns the main list of ~500 banks in Japan with bank codes,
|
||||
but since 90%+ of people will be using one of ~30 major banks,
|
||||
we hard-code those at the top for easier pull-down selection,
|
||||
and add their English names in paranthesis for foreigners.
|
||||
*/
|
||||
public static List<String> prettyPrintBankList() // {{{
|
||||
{
|
||||
List<String> prettyList = new ArrayList<String>();
|
||||
|
||||
// add mega banks at the top
|
||||
for (Map.Entry<String, String> bank: megaBanksEnglish.entrySet())
|
||||
{
|
||||
String bankId = bank.getKey();
|
||||
String bankNameEn = bank.getValue();
|
||||
String bankNameJa = majorBanksJapanese.get(bankId);
|
||||
if (bankNameJa == null) bankNameJa = minorBanksJapanese.get(bankId);
|
||||
prettyList.add(prettyPrintMajorBank(bankId, bankNameJa, bankNameEn));
|
||||
}
|
||||
|
||||
// append the major banks next
|
||||
for (Map.Entry<String, String> bank : majorBanksJapanese.entrySet())
|
||||
{
|
||||
String bankId = bank.getKey();
|
||||
String bankNameJa = bank.getValue();
|
||||
// avoid duplicates
|
||||
if (megaBanksEnglish.get(bankId) != null) continue;
|
||||
prettyList.add(prettyPrintBank(bankId, bankNameJa));
|
||||
}
|
||||
|
||||
// append the minor local banks last
|
||||
for (Map.Entry<String, String> bank : minorBanksJapanese.entrySet())
|
||||
{
|
||||
String bankId = bank.getKey();
|
||||
String bankNameJa = bank.getValue();
|
||||
prettyList.add(prettyPrintBank(bankId, bankNameJa));
|
||||
}
|
||||
|
||||
return prettyList;
|
||||
} // }}}
|
||||
|
||||
// Pretty print major banks like this: (0001) みずほ (Mizuho Bank)
|
||||
private static String prettyPrintMajorBank(String bankId, String bankNameJa, String bankNameEn) // {{{
|
||||
{
|
||||
return ID_OPEN + bankId + ID_CLOSE + SPACE +
|
||||
JA_OPEN + bankNameJa + JA_CLOSE + SPACE +
|
||||
EN_OPEN + bankNameEn + EN_CLOSE;
|
||||
} // }}}
|
||||
// Pretty print other banks like this: (9524) みずほ証券
|
||||
private static String prettyPrintBank(String bankId, String bankName) // {{{
|
||||
{
|
||||
return ID_OPEN + bankId + ID_CLOSE + SPACE +
|
||||
JA_OPEN + bankName + JA_CLOSE;
|
||||
} // }}}
|
||||
|
||||
// top 30 mega banks with english
|
||||
private static final Map<String, String> megaBanksEnglish = ImmutableMap.<String, String> builder()
|
||||
// {{{ japan post office
|
||||
.put("9900", "Japan Post Bank Yucho")
|
||||
// }}}
|
||||
// {{{ japan mega-banks
|
||||
.put("0001", "Mizuho Bank")
|
||||
.put("0005", "Mitsubishi UFJ Bank (MUFG)")
|
||||
.put("0009", "Sumitomo Mitsui Banking Corporation (SMBC)")
|
||||
.put("0010", "Resona Bank")
|
||||
// }}}
|
||||
// {{{ major online banks
|
||||
.put("0033", "Japan Net Bank")
|
||||
.put("0034", "Seven Bank (7-11)")
|
||||
.put("0035", "Sony Bank")
|
||||
.put("0036", "Rakuten Bank")
|
||||
.put("0038", "SBI Sumishin Net Bank")
|
||||
.put("0039", "Jibun Bank")
|
||||
.put("0040", "Aeon Bank")
|
||||
.put("0042", "Lawson Bank")
|
||||
// }}}
|
||||
// {{{ major trust banks, etc.
|
||||
.put("0150", "Suruga Bank")
|
||||
.put("0288", "Mitsubishi UFJ Trust Bank")
|
||||
.put("0289", "Mizuho Trust Bank")
|
||||
.put("0294", "Sumitomo Trust Bank")
|
||||
.put("0300", "SMBC Trust Bank (PRESTIA)")
|
||||
.put("0304", "Nomura Trust Bank")
|
||||
.put("0307", "Orix Trust Bank")
|
||||
.put("0310", "GMO Aozora Net Bank")
|
||||
.put("0321", "Japan Securities Trust Bank")
|
||||
.put("0397", "Shinsei Bank")
|
||||
.put("0398", "Aozora Bank")
|
||||
.put("0402", "JP Morgan Chase Bank")
|
||||
.put("0442", "BNY Mellon")
|
||||
.put("0458", "DBS Bank")
|
||||
.put("0472", "SBJ Shinhan Bank Japan")
|
||||
// }}}
|
||||
.build();
|
||||
|
||||
// major ~200 banks
|
||||
private static final Map<String, String> majorBanksJapanese = ImmutableMap.<String, String> builder()
|
||||
// {{{ ゆうちょ銀行 (9900)
|
||||
.put("9900", "ゆうちょ銀行")
|
||||
// }}}
|
||||
// {{{ 都市銀行 (0001 ~ 0029)
|
||||
.put("0001", "みずほ銀行")
|
||||
.put("0005", "三菱UFJ銀行")
|
||||
.put("0009", "三井住友銀行")
|
||||
.put("0010", "りそな銀行")
|
||||
.put("0017", "埼玉りそな銀行")
|
||||
// }}}
|
||||
// {{{ ネット専業銀行等 (0030 ~ 0049)
|
||||
.put("0033", "ジャパンネット銀行")
|
||||
.put("0034", "セブン銀行")
|
||||
.put("0035", "ソニー銀行")
|
||||
.put("0036", "楽天銀行")
|
||||
.put("0038", "住信SBIネット銀行")
|
||||
.put("0039", "じぶん銀行")
|
||||
.put("0040", "イオン銀行")
|
||||
.put("0041", "大和ネクスト銀行")
|
||||
.put("0042", "ローソン銀行")
|
||||
// }}}
|
||||
// {{{ 協会 (0050 ~ 0099)
|
||||
.put("0051", "全銀協")
|
||||
.put("0052", "横浜銀行協会")
|
||||
.put("0053", "釧路銀行協会")
|
||||
.put("0054", "札幌銀行協会")
|
||||
.put("0056", "函館銀行協会")
|
||||
.put("0057", "青森銀行協会")
|
||||
.put("0058", "秋田銀行協会")
|
||||
.put("0059", "宮城銀行協会")
|
||||
.put("0060", "福島銀行協会")
|
||||
.put("0061", "群馬銀行協会")
|
||||
.put("0062", "新潟銀行協会")
|
||||
.put("0063", "石川銀行協会")
|
||||
.put("0064", "山梨銀行協会")
|
||||
.put("0065", "長野銀行協会")
|
||||
.put("0066", "静岡銀行協会")
|
||||
.put("0067", "名古屋銀行協会")
|
||||
.put("0068", "京都銀行協会")
|
||||
.put("0069", "大阪銀行協会")
|
||||
.put("0070", "神戸銀行協会")
|
||||
.put("0071", "岡山銀行協会")
|
||||
.put("0072", "広島銀行協会")
|
||||
.put("0073", "島根銀行協会")
|
||||
.put("0074", "山口銀行協会")
|
||||
.put("0075", "香川銀行協会")
|
||||
.put("0076", "愛媛銀行協会")
|
||||
.put("0077", "高知銀行協会")
|
||||
.put("0078", "北九州銀行協会")
|
||||
.put("0079", "福岡銀行協会")
|
||||
.put("0080", "大分銀行協会")
|
||||
.put("0081", "長崎銀行協会")
|
||||
.put("0082", "熊本銀行協会")
|
||||
.put("0083", "鹿児島銀行協会")
|
||||
.put("0084", "沖縄銀行協会")
|
||||
.put("0090", "全銀ネット")
|
||||
.put("0095", "CLSBANK")
|
||||
// }}}
|
||||
// {{{ 地方銀行 (0116 ~ 0190)
|
||||
.put("0116", "北海道銀行")
|
||||
.put("0117", "青森銀行")
|
||||
.put("0118", "みちのく銀行")
|
||||
.put("0119", "秋田銀行")
|
||||
.put("0120", "北都銀行")
|
||||
.put("0121", "荘内銀行")
|
||||
.put("0122", "山形銀行")
|
||||
.put("0123", "岩手銀行")
|
||||
.put("0124", "東北銀行")
|
||||
.put("0125", "七十七銀行")
|
||||
.put("0126", "東邦銀行")
|
||||
.put("0128", "群馬銀行")
|
||||
.put("0129", "足利銀行")
|
||||
.put("0130", "常陽銀行")
|
||||
.put("0131", "筑波銀行")
|
||||
.put("0133", "武蔵野銀行")
|
||||
.put("0134", "千葉銀行")
|
||||
.put("0135", "千葉興業銀行")
|
||||
.put("0137", "きらぼし銀行")
|
||||
.put("0138", "横浜銀行")
|
||||
.put("0140", "第四銀行")
|
||||
.put("0141", "北越銀行")
|
||||
.put("0142", "山梨中央銀行")
|
||||
.put("0143", "八十二銀行")
|
||||
.put("0144", "北陸銀行")
|
||||
.put("0145", "富山銀行")
|
||||
.put("0146", "北國銀行")
|
||||
.put("0147", "福井銀行")
|
||||
.put("0149", "静岡銀行")
|
||||
.put("0150", "スルガ銀行")
|
||||
.put("0151", "清水銀行")
|
||||
.put("0152", "大垣共立銀行")
|
||||
.put("0153", "十六銀行")
|
||||
.put("0154", "三重銀行")
|
||||
.put("0155", "百五銀行")
|
||||
.put("0157", "滋賀銀行")
|
||||
.put("0158", "京都銀行")
|
||||
.put("0159", "関西みらい銀行")
|
||||
.put("0161", "池田泉州銀行")
|
||||
.put("0162", "南都銀行")
|
||||
.put("0163", "紀陽銀行")
|
||||
.put("0164", "但馬銀行")
|
||||
.put("0166", "鳥取銀行")
|
||||
.put("0167", "山陰合同銀行")
|
||||
.put("0168", "中国銀行")
|
||||
.put("0169", "広島銀行")
|
||||
.put("0170", "山口銀行")
|
||||
.put("0172", "阿波銀行")
|
||||
.put("0173", "百十四銀行")
|
||||
.put("0174", "伊予銀行")
|
||||
.put("0175", "四国銀行")
|
||||
.put("0177", "福岡銀行")
|
||||
.put("0178", "筑邦銀行")
|
||||
.put("0179", "佐賀銀行")
|
||||
.put("0180", "十八銀行")
|
||||
.put("0181", "親和銀行")
|
||||
.put("0182", "肥後銀行")
|
||||
.put("0183", "大分銀行")
|
||||
.put("0184", "宮崎銀行")
|
||||
.put("0185", "鹿児島銀行")
|
||||
.put("0187", "琉球銀行")
|
||||
.put("0188", "沖縄銀行")
|
||||
.put("0190", "西日本シティ銀行")
|
||||
.put("0191", "北九州銀行")
|
||||
// }}}
|
||||
// {{{ 信託銀行 (0288 ~ 0326)
|
||||
.put("0288", "三菱UFJ信託銀行")
|
||||
.put("0289", "みずほ信託銀行")
|
||||
.put("0294", "三井住友信託銀行")
|
||||
.put("0295", "BNYM信託")
|
||||
.put("0297", "日本マスタートラスト信託銀行")
|
||||
.put("0299", "ステート信託")
|
||||
.put("0300", "SMBC信託銀行 プレスティア")
|
||||
.put("0304", "野村信託銀行")
|
||||
.put("0307", "オリックス銀行")
|
||||
.put("0310", "GMOあおぞらネット銀行")
|
||||
.put("0311", "農中信託")
|
||||
.put("0320", "新生信託")
|
||||
.put("0321", "日証金信託")
|
||||
.put("0324", "日本トラスティサービス信託銀行")
|
||||
.put("0325", "資産管理サービス信託銀行")
|
||||
// }}}
|
||||
// {{{ 旧長期信用銀行 (0397 ~ 0398)
|
||||
.put("0397", "新生銀行")
|
||||
.put("0398", "あおぞら銀行")
|
||||
// }}}
|
||||
// {{{ foreign banks (0400 ~ 0497)
|
||||
.put("0401", "シティバンク、エヌ・エイ 銀行")
|
||||
.put("0402", "JPモルガン・チェース銀行")
|
||||
.put("0403", "アメリカ銀行")
|
||||
.put("0411", "香港上海銀行")
|
||||
.put("0413", "スタンチヤート")
|
||||
.put("0414", "バークレイズ")
|
||||
.put("0421", "アグリコル")
|
||||
.put("0423", "ハナ")
|
||||
.put("0424", "印度")
|
||||
.put("0425", "兆豐國際商銀")
|
||||
.put("0426", "バンコツク")
|
||||
.put("0429", "バンクネガラ")
|
||||
.put("0430", "ドイツ銀行")
|
||||
.put("0432", "ブラジル")
|
||||
.put("0438", "ユーオバシーズ")
|
||||
.put("0439", "ユービーエス")
|
||||
.put("0442", "BNYメロン")
|
||||
.put("0443", "ビー・エヌ・ピー・パリバ銀行")
|
||||
.put("0444", "チヤイニーズ")
|
||||
.put("0445", "ソシエテ")
|
||||
.put("0456", "ユバフ")
|
||||
.put("0458", "DBS")
|
||||
.put("0459", "パキスタン")
|
||||
.put("0460", "クレデイスイス")
|
||||
.put("0461", "コメルツ銀行")
|
||||
.put("0463", "ウニクレデイト")
|
||||
.put("0468", "インドステイト")
|
||||
.put("0471", "カナダロイヤル")
|
||||
.put("0472", "SBJ銀行")
|
||||
.put("0477", "ウリイ")
|
||||
.put("0482", "アイエヌジー")
|
||||
.put("0484", "ナツトオース")
|
||||
.put("0485", "アンズバンク")
|
||||
.put("0487", "コモンウエルス")
|
||||
.put("0489", "バンクチヤイナ")
|
||||
.put("0495", "ステストリート")
|
||||
.put("0498", "中小企業")
|
||||
// }}}
|
||||
// {{{ 第二地方銀行 (0501 ~ 0597)
|
||||
.put("0501", "北洋銀行")
|
||||
.put("0508", "きらやか銀行")
|
||||
.put("0509", "北日本銀行")
|
||||
.put("0512", "仙台銀行")
|
||||
.put("0513", "福島銀行")
|
||||
.put("0514", "大東銀行")
|
||||
.put("0516", "東和銀行")
|
||||
.put("0517", "栃木銀行")
|
||||
.put("0522", "京葉銀行")
|
||||
.put("0525", "東日本銀行")
|
||||
.put("0526", "東京スター銀行")
|
||||
.put("0530", "神奈川銀行")
|
||||
.put("0532", "大光銀行")
|
||||
.put("0533", "長野銀行")
|
||||
.put("0534", "富山第一銀行")
|
||||
.put("0537", "福邦銀行")
|
||||
.put("0538", "静岡中央銀行")
|
||||
.put("0542", "愛知銀行")
|
||||
.put("0543", "名古屋銀行")
|
||||
.put("0544", "中京銀行")
|
||||
.put("0546", "第三銀行")
|
||||
.put("0555", "大正銀行")
|
||||
.put("0562", "みなと銀行")
|
||||
.put("0565", "島根銀行")
|
||||
.put("0566", "トマト銀行")
|
||||
.put("0569", "もみじ銀行")
|
||||
.put("0570", "西京銀行")
|
||||
.put("0572", "徳島銀行")
|
||||
.put("0573", "香川銀行")
|
||||
.put("0576", "愛媛銀行")
|
||||
.put("0578", "高知銀行")
|
||||
.put("0582", "福岡中央銀行")
|
||||
.put("0583", "佐賀共栄銀行")
|
||||
.put("0585", "長崎銀行")
|
||||
.put("0587", "熊本銀行")
|
||||
.put("0590", "豊和銀行")
|
||||
.put("0591", "宮崎太陽銀行")
|
||||
.put("0594", "南日本銀行")
|
||||
.put("0596", "沖縄海邦銀行")
|
||||
// }}}
|
||||
// {{{ more foreign banks (0600 ~ 0999)
|
||||
.put("0603", "韓国産業")
|
||||
.put("0607", "彰化商業")
|
||||
.put("0608", "ウエルズフアゴ")
|
||||
.put("0611", "第一商業")
|
||||
.put("0612", "台湾")
|
||||
.put("0615", "交通")
|
||||
.put("0616", "メトロポリタン")
|
||||
.put("0617", "フイリピン")
|
||||
.put("0619", "中国工商")
|
||||
.put("0621", "中國信託商業")
|
||||
.put("0623", "インテーザ")
|
||||
.put("0624", "國民")
|
||||
.put("0625", "中国建設")
|
||||
.put("0626", "イタウウニ")
|
||||
.put("0627", "BBVA")
|
||||
.put("0630", "中国農業")
|
||||
.put("0631", "台新")
|
||||
.put("0632", "玉山")
|
||||
.put("0633", "台湾企銀")
|
||||
.put("0808", "ドイツ証券")
|
||||
.put("0813", "ソシエテ証券")
|
||||
.put("0821", "ビーピー証券")
|
||||
.put("0822", "バークレイ証券")
|
||||
.put("0831", "アグリコル証券")
|
||||
.put("0832", "ジエイピー証券")
|
||||
.put("0842", "ゴルドマン証券")
|
||||
.put("0845", "ナツトウエ証券")
|
||||
.put("0900", "日本相互証券")
|
||||
.put("0905", "東京金融取引所")
|
||||
.put("0909", "日本クリア機構")
|
||||
.put("0910", "ほふりクリア")
|
||||
.put("0964", "しんきん証券")
|
||||
.put("0966", "HSBC証券")
|
||||
.put("0968", "セント東短証券")
|
||||
.put("0971", "UBS証券")
|
||||
.put("0972", "メリル日本証券")
|
||||
// }}}
|
||||
.build();
|
||||
|
||||
// minor ~280 lesser known banks
|
||||
private static final Map<String, String> minorBanksJapanese = ImmutableMap.<String, String> builder()
|
||||
// {{{ 信用金庫 (1001 ~ 1996)
|
||||
.put("1000", "信金中央金庫")
|
||||
.put("1001", "北海道信金")
|
||||
.put("1003", "室蘭信金")
|
||||
.put("1004", "空知信金")
|
||||
.put("1006", "苫小牧信金")
|
||||
.put("1008", "北門信金")
|
||||
.put("1009", "伊達信金")
|
||||
.put("1010", "北空知信金")
|
||||
.put("1011", "日高信金")
|
||||
.put("1013", "渡島信金")
|
||||
.put("1014", "道南うみ街信金")
|
||||
.put("1020", "旭川信金")
|
||||
.put("1021", "稚内信金")
|
||||
.put("1022", "留萌信金")
|
||||
.put("1024", "北星信金")
|
||||
.put("1026", "帯広信金")
|
||||
.put("1027", "釧路信金")
|
||||
.put("1028", "大地みらい信金")
|
||||
.put("1030", "北見信金")
|
||||
.put("1031", "網走信金")
|
||||
.put("1033", "遠軽信金")
|
||||
.put("1104", "東奥信金")
|
||||
.put("1105", "青い森信金")
|
||||
.put("1120", "秋田信金")
|
||||
.put("1123", "羽後信金")
|
||||
.put("1140", "山形信金")
|
||||
.put("1141", "米沢信金")
|
||||
.put("1142", "鶴岡信金")
|
||||
.put("1143", "新庄信金")
|
||||
.put("1150", "盛岡信金")
|
||||
.put("1152", "宮古信金")
|
||||
.put("1153", "一関信金")
|
||||
.put("1154", "北上信金")
|
||||
.put("1155", "花巻信金")
|
||||
.put("1156", "水沢信金")
|
||||
.put("1170", "杜の都信金")
|
||||
.put("1171", "宮城第一信金")
|
||||
.put("1172", "石巻信金")
|
||||
.put("1174", "仙南信金")
|
||||
.put("1181", "会津信金")
|
||||
.put("1182", "郡山信金")
|
||||
.put("1184", "白河信金")
|
||||
.put("1185", "須賀川信金")
|
||||
.put("1186", "ひまわり信金")
|
||||
.put("1188", "あぶくま信金")
|
||||
.put("1189", "二本松信金")
|
||||
.put("1190", "福島信金")
|
||||
.put("1203", "高崎信金")
|
||||
.put("1204", "桐生信金")
|
||||
.put("1206", "アイオー信金")
|
||||
.put("1208", "利根郡信金")
|
||||
.put("1209", "館林信金")
|
||||
.put("1210", "北群馬信金")
|
||||
.put("1211", "しののめ信金")
|
||||
.put("1221", "足利小山信金")
|
||||
.put("1222", "栃木信金")
|
||||
.put("1223", "鹿沼相互信金")
|
||||
.put("1224", "佐野信金")
|
||||
.put("1225", "大田原信金")
|
||||
.put("1227", "烏山信金")
|
||||
.put("1240", "水戸信金")
|
||||
.put("1242", "結城信金")
|
||||
.put("1250", "埼玉県信金")
|
||||
.put("1251", "川口信金")
|
||||
.put("1252", "青木信金")
|
||||
.put("1253", "飯能信金")
|
||||
.put("1260", "千葉信金")
|
||||
.put("1261", "銚子信金")
|
||||
.put("1262", "東京ベイ信金")
|
||||
.put("1264", "館山信金")
|
||||
.put("1267", "佐原信金")
|
||||
.put("1280", "横浜信金")
|
||||
.put("1281", "かながわ信金")
|
||||
.put("1282", "湘南信金")
|
||||
.put("1283", "川崎信金")
|
||||
.put("1286", "平塚信金")
|
||||
.put("1288", "さがみ信金")
|
||||
.put("1289", "中栄信金")
|
||||
.put("1290", "中南信金")
|
||||
.put("1303", "朝日信金")
|
||||
.put("1305", "興産信金")
|
||||
.put("1310", "さわやか信金")
|
||||
.put("1311", "東京シテイ信金")
|
||||
.put("1319", "芝信金")
|
||||
.put("1320", "東京東信金")
|
||||
.put("1321", "東栄信金")
|
||||
.put("1323", "亀有信金")
|
||||
.put("1326", "小松川信金")
|
||||
.put("1327", "足立成和信金")
|
||||
.put("1333", "東京三協信金")
|
||||
.put("1336", "西京信金")
|
||||
.put("1341", "西武信金")
|
||||
.put("1344", "城南信金")
|
||||
.put("1345", "東京)昭和信金")
|
||||
.put("1346", "目黒信金")
|
||||
.put("1348", "世田谷信金")
|
||||
.put("1349", "東京信金")
|
||||
.put("1351", "城北信金")
|
||||
.put("1352", "滝野川信金")
|
||||
.put("1356", "巣鴨信金")
|
||||
.put("1358", "青梅信金")
|
||||
.put("1360", "多摩信金")
|
||||
.put("1370", "新潟信金")
|
||||
.put("1371", "長岡信金")
|
||||
.put("1373", "三条信金")
|
||||
.put("1374", "新発田信金")
|
||||
.put("1375", "柏崎信金")
|
||||
.put("1376", "上越信金")
|
||||
.put("1377", "新井信金")
|
||||
.put("1379", "村上信金")
|
||||
.put("1380", "加茂信金")
|
||||
.put("1385", "甲府信金")
|
||||
.put("1386", "山梨信金")
|
||||
.put("1390", "長野信金")
|
||||
.put("1391", "松本信金")
|
||||
.put("1392", "上田信金")
|
||||
.put("1393", "諏訪信金")
|
||||
.put("1394", "飯田信金")
|
||||
.put("1396", "アルプス信金")
|
||||
.put("1401", "富山信金")
|
||||
.put("1402", "高岡信金")
|
||||
.put("1405", "にいかわ信金")
|
||||
.put("1406", "氷見伏木信金")
|
||||
.put("1412", "砺波信金")
|
||||
.put("1413", "石動信金")
|
||||
.put("1440", "金沢信金")
|
||||
.put("1442", "のと共栄信金")
|
||||
.put("1444", "北陸信金")
|
||||
.put("1445", "鶴来信金")
|
||||
.put("1448", "興能信金")
|
||||
.put("1470", "福井信金")
|
||||
.put("1471", "敦賀信金")
|
||||
.put("1473", "小浜信金")
|
||||
.put("1475", "越前信金")
|
||||
.put("1501", "しず焼津信金")
|
||||
.put("1502", "静清信金")
|
||||
.put("1503", "浜松磐田信金")
|
||||
.put("1505", "沼津信金")
|
||||
.put("1506", "三島信金")
|
||||
.put("1507", "富士宮信金")
|
||||
.put("1513", "島田掛川信金")
|
||||
.put("1515", "静岡)富士信金")
|
||||
.put("1517", "遠州信金")
|
||||
.put("1530", "岐阜信金")
|
||||
.put("1531", "大垣西濃信金")
|
||||
.put("1532", "高山信金")
|
||||
.put("1533", "東濃信金")
|
||||
.put("1534", "関信金")
|
||||
.put("1538", "八幡信金")
|
||||
.put("1550", "愛知信金")
|
||||
.put("1551", "豊橋信金")
|
||||
.put("1552", "岡崎信金")
|
||||
.put("1553", "いちい信金")
|
||||
.put("1554", "瀬戸信金")
|
||||
.put("1555", "半田信金")
|
||||
.put("1556", "知多信金")
|
||||
.put("1557", "豊川信金")
|
||||
.put("1559", "豊田信金")
|
||||
.put("1560", "碧海信金")
|
||||
.put("1561", "西尾信金")
|
||||
.put("1562", "蒲郡信金")
|
||||
.put("1563", "尾西信金")
|
||||
.put("1565", "中日信金")
|
||||
.put("1566", "東春信金")
|
||||
.put("1580", "津信金")
|
||||
.put("1581", "北伊勢上野信金")
|
||||
.put("1583", "桑名三重信金")
|
||||
.put("1585", "紀北信金")
|
||||
.put("1602", "滋賀中央信金")
|
||||
.put("1603", "長浜信金")
|
||||
.put("1604", "湖東信金")
|
||||
.put("1610", "京都信金")
|
||||
.put("1611", "京都中央信金")
|
||||
.put("1620", "京都北都信金")
|
||||
.put("1630", "大阪信金")
|
||||
.put("1633", "大阪厚生信金")
|
||||
.put("1635", "大阪シテイ信金")
|
||||
.put("1636", "大阪商工信金")
|
||||
.put("1643", "永和信金")
|
||||
.put("1645", "北おおさか信金")
|
||||
.put("1656", "枚方信金")
|
||||
.put("1666", "奈良信金")
|
||||
.put("1667", "大和信金")
|
||||
.put("1668", "奈良中央信金")
|
||||
.put("1671", "新宮信金")
|
||||
.put("1674", "きのくに信金")
|
||||
.put("1680", "神戸信金")
|
||||
.put("1685", "姫路信金")
|
||||
.put("1686", "播州信金")
|
||||
.put("1687", "兵庫信金")
|
||||
.put("1688", "尼崎信金")
|
||||
.put("1689", "日新信金")
|
||||
.put("1691", "淡路信金")
|
||||
.put("1692", "但馬信金")
|
||||
.put("1694", "西兵庫信金")
|
||||
.put("1695", "中兵庫信金")
|
||||
.put("1696", "但陽信金")
|
||||
.put("1701", "鳥取信金")
|
||||
.put("1702", "米子信金")
|
||||
.put("1703", "倉吉信金")
|
||||
.put("1710", "しまね信金")
|
||||
.put("1711", "日本海信金")
|
||||
.put("1712", "島根中央信金")
|
||||
.put("1732", "おかやま信金")
|
||||
.put("1734", "水島信金")
|
||||
.put("1735", "津山信金")
|
||||
.put("1738", "玉島信金")
|
||||
.put("1740", "備北信金")
|
||||
.put("1741", "吉備信金")
|
||||
.put("1742", "日生信金")
|
||||
.put("1743", "備前信金")
|
||||
.put("1750", "広島信金")
|
||||
.put("1752", "呉信金")
|
||||
.put("1756", "しまなみ信金")
|
||||
.put("1758", "広島みどり信金")
|
||||
.put("1780", "萩山口信金")
|
||||
.put("1781", "西中国信金")
|
||||
.put("1789", "東山口信金")
|
||||
.put("1801", "徳島信金")
|
||||
.put("1803", "阿南信金")
|
||||
.put("1830", "高松信金")
|
||||
.put("1833", "観音寺信金")
|
||||
.put("1860", "愛媛信金")
|
||||
.put("1862", "宇和島信金")
|
||||
.put("1864", "東予信金")
|
||||
.put("1866", "川之江信金")
|
||||
.put("1880", "幡多信金")
|
||||
.put("1881", "高知信金")
|
||||
.put("1901", "福岡信金")
|
||||
.put("1903", "福岡ひびき信金")
|
||||
.put("1908", "大牟田柳川信金")
|
||||
.put("1909", "筑後信金")
|
||||
.put("1910", "飯塚信金")
|
||||
.put("1917", "大川信金")
|
||||
.put("1920", "遠賀信金")
|
||||
.put("1930", "唐津信金")
|
||||
.put("1931", "佐賀信金")
|
||||
.put("1933", "九州ひぜん信金")
|
||||
.put("1942", "たちばな信金")
|
||||
.put("1951", "熊本信金")
|
||||
.put("1952", "熊本第一信金")
|
||||
.put("1954", "熊本中央信金")
|
||||
.put("1960", "大分信金")
|
||||
.put("1962", "大分みらい信金")
|
||||
.put("1980", "宮崎都城信金")
|
||||
.put("1985", "高鍋信金")
|
||||
.put("1990", "鹿児島信金")
|
||||
.put("1991", "鹿児島相互信金")
|
||||
.put("1993", "奄美大島信金")
|
||||
.put("1996", "コザ信金")
|
||||
// }}}
|
||||
// {{{ 信用組合 (2011 ~ 2895)
|
||||
.put("2004", "商工組合中央金庫")
|
||||
.put("2010", "全国信用協同組合連合会")
|
||||
.put("2213", "整理回収機構")
|
||||
// }}}
|
||||
// {{{ 労働金庫 (2951 ~ 2997)
|
||||
.put("2950", "労働金庫連合会")
|
||||
// }}}
|
||||
// {{{ 農林中央金庫 (3000)
|
||||
.put("3000", "農林中央金庫")
|
||||
// }}}
|
||||
// {{{ 信用農業協同組合連合会 (3001 ~ 3046)
|
||||
.put("3001", "北海道信用農業協同組合連合会")
|
||||
.put("3003", "岩手県信用農業協同組合連合会")
|
||||
.put("3008", "茨城県信用農業協同組合連合会")
|
||||
.put("3011", "埼玉県信用農業協同組合連合会")
|
||||
.put("3013", "東京都信用農業協同組合連合会")
|
||||
.put("3014", "神奈川県信用農業協同組合連合会")
|
||||
.put("3015", "山梨県信用農業協同組合連合会")
|
||||
.put("3016", "長野県信用農業協同組合連合会")
|
||||
.put("3017", "新潟県信用農業協同組合連合会")
|
||||
.put("3019", "石川県信用農業協同組合連合会")
|
||||
.put("3020", "岐阜県信用農業協同組合連合会")
|
||||
.put("3021", "静岡県信用農業協同組合連合会")
|
||||
.put("3022", "愛知県信用農業協同組合連合会")
|
||||
.put("3023", "三重県信用農業協同組合連合会")
|
||||
.put("3024", "福井県信用農業協同組合連合会")
|
||||
.put("3025", "滋賀県信用農業協同組合連合会")
|
||||
.put("3026", "京都府信用農業協同組合連合会")
|
||||
.put("3027", "大阪府信用農業協同組合連合会")
|
||||
.put("3028", "兵庫県信用農業協同組合連合会")
|
||||
.put("3030", "和歌山県信用農業協同組合連合会")
|
||||
.put("3031", "鳥取県信用農業協同組合連合会")
|
||||
.put("3034", "広島県信用農業協同組合連合会")
|
||||
.put("3035", "山口県信用農業協同組合連合会")
|
||||
.put("3036", "徳島県信用農業協同組合連合会")
|
||||
.put("3037", "香川県信用農業協同組合連合会")
|
||||
.put("3038", "愛媛県信用農業協同組合連合会")
|
||||
.put("3039", "高知県信用農業協同組合連合会")
|
||||
.put("3040", "福岡県信用農業協同組合連合会")
|
||||
.put("3041", "佐賀県信用農業協同組合連合会")
|
||||
.put("3044", "大分県信用農業協同組合連合会")
|
||||
.put("3045", "宮崎県信用農業協同組合連合会")
|
||||
.put("3046", "鹿児島県信用農業協同組合連合会")
|
||||
// }}}
|
||||
// {{{ "JA Bank" agricultural cooperative associations (3056 ~ 9375)
|
||||
// REMOVED: the farmers should use a real bank if they want to sell bitcoin
|
||||
// }}}
|
||||
// {{{ 信用漁業協同組合連合会 (9450 ~ 9496)
|
||||
.put("9450", "北海道信用漁業協同組合連合会")
|
||||
.put("9451", "青森県信用漁業協同組合連合会")
|
||||
.put("9452", "岩手県信用漁業協同組合連合会")
|
||||
.put("9453", "宮城県漁業協同組合")
|
||||
.put("9456", "福島県信用漁業協同組合連合会")
|
||||
.put("9457", "茨城県信用漁業協同組合連合会")
|
||||
.put("9461", "千葉県信用漁業協同組合連合会")
|
||||
.put("9462", "東京都信用漁業協同組合連合会")
|
||||
.put("9466", "新潟県信用漁業協同組合連合会")
|
||||
.put("9467", "富山県信用漁業協同組合連合会")
|
||||
.put("9468", "石川県信用漁業協同組合連合会")
|
||||
.put("9470", "静岡県信用漁業協同組合連合会")
|
||||
.put("9471", "愛知県信用漁業協同組合連合会")
|
||||
.put("9472", "三重県信用漁業協同組合連合会")
|
||||
.put("9473", "福井県信用漁業協同組合連合会")
|
||||
.put("9475", "京都府信用漁業協同組合連合会")
|
||||
.put("9477", "なぎさ信用漁業協同組合連合会")
|
||||
.put("9480", "鳥取県信用漁業協同組合連合会")
|
||||
.put("9481", "JFしまね漁業協同組合")
|
||||
.put("9483", "広島県信用漁業協同組合連合会")
|
||||
.put("9484", "山口県漁業協同組合")
|
||||
.put("9485", "徳島県信用漁業協同組合連合会")
|
||||
.put("9486", "香川県信用漁業協同組合連合会")
|
||||
.put("9487", "愛媛県信用漁業協同組合連合会")
|
||||
.put("9488", "高知県信用漁業協同組合連合会")
|
||||
.put("9489", "福岡県信用漁業協同組合連合会")
|
||||
.put("9490", "佐賀県信用漁業協同組合連合会")
|
||||
.put("9491", "長崎県信用漁業協同組合連合会")
|
||||
.put("9493", "大分県漁業協同組合")
|
||||
.put("9494", "宮崎県信用漁業協同組合連合会")
|
||||
.put("9495", "鹿児島県信用漁業協同組合連合会")
|
||||
.put("9496", "沖縄県信用漁業協同組合連合会")
|
||||
// }}}
|
||||
// {{{ securities firms
|
||||
.put("9500", "東京短資")
|
||||
.put("9501", "セントラル短資")
|
||||
.put("9507", "上田八木短資")
|
||||
.put("9510", "日本証券金融")
|
||||
.put("9520", "野村証券")
|
||||
.put("9521", "日興証券")
|
||||
.put("9523", "大和証券")
|
||||
.put("9524", "みずほ証券")
|
||||
.put("9528", "岡三証券")
|
||||
.put("9530", "岩井コスモ証券")
|
||||
.put("9532", "三菱UFJ証券")
|
||||
.put("9534", "丸三証券")
|
||||
.put("9535", "東洋証券")
|
||||
.put("9537", "水戸証券")
|
||||
.put("9539", "東海東京証券")
|
||||
.put("9542", "むさし証券")
|
||||
.put("9545", "いちよし証券")
|
||||
.put("9573", "極東証券")
|
||||
.put("9574", "立花証券")
|
||||
.put("9579", "光世証券")
|
||||
.put("9584", "ちばぎん証券")
|
||||
.put("9589", "シテイ証券")
|
||||
.put("9594", "CS証券")
|
||||
.put("9595", "スタンレー証券")
|
||||
.put("9930", "日本政策投資")
|
||||
.put("9932", "政策金融公庫")
|
||||
.put("9933", "国際協力")
|
||||
.put("9945", "預金保険機構")
|
||||
// }}}
|
||||
.build();
|
||||
|
||||
private final static String ID_OPEN = "";
|
||||
private final static String ID_CLOSE = "";
|
||||
private final static String JA_OPEN = "";
|
||||
private final static String JA_CLOSE = "";
|
||||
private final static String EN_OPEN = "";
|
||||
private final static String EN_CLOSE = "";
|
||||
public final static String SPACE = " ";
|
||||
|
||||
// don't localize these strings into all languages,
|
||||
// all we want is either Japanese or English here.
|
||||
public static final String getString(String id)
|
||||
{
|
||||
boolean ja = GUIUtil.getUserLanguage().equals("ja");
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case "bank":
|
||||
if (ja) return "銀行名 ・金融機関名";
|
||||
return "Japan Bank or Financial Institution";
|
||||
case "bank.select":
|
||||
if (ja) return "金融機関 ・銀行検索 (名称入力検索)";
|
||||
return "Search for Bank or Financial Institution";
|
||||
case "bank.code":
|
||||
if (ja) return "銀行コード";
|
||||
return "Zengin Bank Code";
|
||||
case "bank.name":
|
||||
if (ja) return "金融機関名 ・銀行名";
|
||||
return "Financial Institution / Bank Name";
|
||||
|
||||
case "branch":
|
||||
if (ja) return "支店名";
|
||||
return "Bank Branch";
|
||||
case "branch.code":
|
||||
if (ja) return "支店コード";
|
||||
return "Zengin Bank Branch Code";
|
||||
case "branch.code.validation.error":
|
||||
if (ja) return "入力は3桁の支店コードでなければなりません";
|
||||
return "Input must be a 3 digit branch code";
|
||||
case "branch.name":
|
||||
if (ja) return "支店名";
|
||||
return "Bank Branch Name";
|
||||
|
||||
case "account":
|
||||
if (ja) return "銀行口座";
|
||||
return "Japan Bank Account";
|
||||
|
||||
case "account.type":
|
||||
if (ja) return "口座科目";
|
||||
return "Bank Account Type";
|
||||
case "account.type.select":
|
||||
if (ja) return "口座科目";
|
||||
return "Select Account Type";
|
||||
// displayed while creating account
|
||||
case "account.type.futsu":
|
||||
if (ja) return "普通";
|
||||
return "FUTSUU (ordinary) account";
|
||||
case "account.type.touza":
|
||||
if (ja) return "当座";
|
||||
return "TOUZA (checking) account";
|
||||
case "account.type.chochiku":
|
||||
if (ja) return "貯金";
|
||||
return "CHOCHIKU (special) account";
|
||||
// used when saving account info
|
||||
case "account.type.futsu.ja":
|
||||
return "普通";
|
||||
case "account.type.touza.ja":
|
||||
return "当座";
|
||||
case "account.type.chochiku.ja":
|
||||
return "貯金";
|
||||
|
||||
case "account.number":
|
||||
if (ja) return "口座番号";
|
||||
return "Bank Account Number";
|
||||
case "account.number.validation.error":
|
||||
if (ja) return "入力は4〜8桁の口座番号でなければなりません";
|
||||
return "Input must be 4 ~ 8 digit account number";
|
||||
case "account.name":
|
||||
if (ja) return "口座名義";
|
||||
return "Bank Account Name";
|
||||
|
||||
// for japanese-only input fields
|
||||
case "japanese.validation.error":
|
||||
if (ja) return "入力は漢字、ひらがな、またはカタカナでなければなりません";
|
||||
return "Input must be Kanji, Hiragana, or Katakana";
|
||||
case "japanese.validation.regex":
|
||||
// epic regex to only match japanese input
|
||||
return "[" + // match any of the these characters:
|
||||
// "A-z" + // full-width alphabet
|
||||
// "0-9" + // full-width numerals
|
||||
"一-龯" + // all japanese kanji (0x4e00 ~ 0x9fcf)
|
||||
"ぁ-ゔ" + // full-width hiragana (0x3041 ~ 0x3094)
|
||||
"ァ-・" + // full-width katakana (0x30a1 ~ 0x30fb)
|
||||
"ぁ-ゞ" + // half-width hiragana
|
||||
"ァ-ン゙゚" + // half-width katakana
|
||||
"ヽヾ゛゜ー" + // 0x309e, 0x309b, 0x309c, 0x30fc
|
||||
" " + // full-width space
|
||||
" " + // half-width space
|
||||
"]+"; // for any length
|
||||
}
|
||||
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4:sw=4:expandtab:foldmethod=marker:nowrap:
|
@ -24,6 +24,7 @@ import bisq.desktop.components.BusyAnimation;
|
||||
import bisq.desktop.components.TableGroupHeadline;
|
||||
import bisq.desktop.components.TextFieldWithIcon;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.arbitration.Attachment;
|
||||
@ -404,7 +405,7 @@ public class Chat extends AnchorPane {
|
||||
AnchorPane.setLeftAnchor(statusHBox, padding);
|
||||
}
|
||||
AnchorPane.setBottomAnchor(statusHBox, 7d);
|
||||
headerLabel.setText(formatter.formatDateTime(new Date(message.getDate())));
|
||||
headerLabel.setText(DisplayUtils.formatDateTime(new Date(message.getDate())));
|
||||
messageLabel.setText(message.getMessage());
|
||||
attachmentsBox.getChildren().clear();
|
||||
if (allowAttachments &&
|
||||
|
@ -37,6 +37,7 @@ import bisq.desktop.main.offer.SellOfferView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.portfolio.PortfolioView;
|
||||
import bisq.desktop.main.settings.SettingsView;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.Transitions;
|
||||
|
||||
import bisq.core.dao.monitoring.DaoStateMonitoringService;
|
||||
@ -522,14 +523,14 @@ public class MainView extends InitializableView<StackPane, MainViewModel>
|
||||
res = Res.get("mainView.marketPrice.tooltip",
|
||||
"https://bitcoinaverage.com",
|
||||
"",
|
||||
formatter.formatTime(model.getPriceFeedService().getLastRequestTimeStampBtcAverage()),
|
||||
DisplayUtils.formatTime(model.getPriceFeedService().getLastRequestTimeStampBtcAverage()),
|
||||
model.getPriceFeedService().getProviderNodeAddress());
|
||||
} else {
|
||||
String altcoinExtra = "\n" + Res.get("mainView.marketPrice.tooltip.altcoinExtra");
|
||||
res = Res.get("mainView.marketPrice.tooltip",
|
||||
"https://poloniex.com",
|
||||
altcoinExtra,
|
||||
formatter.formatTime(model.getPriceFeedService().getLastRequestTimeStampPoloniex()),
|
||||
DisplayUtils.formatTime(model.getPriceFeedService().getLastRequestTimeStampPoloniex()),
|
||||
model.getPriceFeedService().getProviderNodeAddress());
|
||||
}
|
||||
return res;
|
||||
|
@ -32,6 +32,7 @@ import bisq.desktop.main.overlays.windows.WalletPasswordWindow;
|
||||
import bisq.desktop.main.overlays.windows.downloadupdate.DisplayUpdateDownloadWindow;
|
||||
import bisq.desktop.main.presentation.DaoPresentation;
|
||||
import bisq.desktop.main.presentation.MarketPricePresentation;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
@ -218,7 +219,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList
|
||||
DontShowAgainLookup.dontShowAgain(key, true);
|
||||
new Popup<>().warning(Res.get("popup.warning.tradePeriod.halfReached",
|
||||
trade.getShortId(),
|
||||
formatter.formatDateTime(maxTradePeriodDate)))
|
||||
DisplayUtils.formatDateTime(maxTradePeriodDate)))
|
||||
.show();
|
||||
}
|
||||
break;
|
||||
@ -228,7 +229,7 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupCompleteList
|
||||
DontShowAgainLookup.dontShowAgain(key, true);
|
||||
new Popup<>().warning(Res.get("popup.warning.tradePeriod.ended",
|
||||
trade.getShortId(),
|
||||
formatter.formatDateTime(maxTradePeriodDate)))
|
||||
DisplayUtils.formatDateTime(maxTradePeriodDate)))
|
||||
.show();
|
||||
}
|
||||
break;
|
||||
|
@ -28,6 +28,7 @@ import bisq.desktop.components.paymentmethods.F2FForm;
|
||||
import bisq.desktop.components.paymentmethods.FasterPaymentsForm;
|
||||
import bisq.desktop.components.paymentmethods.HalCashForm;
|
||||
import bisq.desktop.components.paymentmethods.InteracETransferForm;
|
||||
import bisq.desktop.components.paymentmethods.JapanBankTransferForm;
|
||||
import bisq.desktop.components.paymentmethods.MoneyBeamForm;
|
||||
import bisq.desktop.components.paymentmethods.MoneyGramForm;
|
||||
import bisq.desktop.components.paymentmethods.NationalBankForm;
|
||||
@ -59,6 +60,7 @@ import bisq.desktop.util.validation.F2FValidator;
|
||||
import bisq.desktop.util.validation.HalCashValidator;
|
||||
import bisq.desktop.util.validation.IBANValidator;
|
||||
import bisq.desktop.util.validation.InteracETransferValidator;
|
||||
import bisq.desktop.util.validation.JapanBankTransferValidator;
|
||||
import bisq.desktop.util.validation.MoneyBeamValidator;
|
||||
import bisq.desktop.util.validation.PerfectMoneyValidator;
|
||||
import bisq.desktop.util.validation.PopmoneyValidator;
|
||||
@ -76,6 +78,7 @@ import bisq.core.payment.CashDepositAccount;
|
||||
import bisq.core.payment.ClearXchangeAccount;
|
||||
import bisq.core.payment.F2FAccount;
|
||||
import bisq.core.payment.HalCashAccount;
|
||||
import bisq.core.payment.JapanBankAccount;
|
||||
import bisq.core.payment.MoneyGramAccount;
|
||||
import bisq.core.payment.PaymentAccount;
|
||||
import bisq.core.payment.PaymentAccountFactory;
|
||||
@ -131,6 +134,7 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
||||
private final ClearXchangeValidator clearXchangeValidator;
|
||||
private final ChaseQuickPayValidator chaseQuickPayValidator;
|
||||
private final InteracETransferValidator interacETransferValidator;
|
||||
private final JapanBankTransferValidator japanBankTransferValidator;
|
||||
private final USPostalMoneyOrderValidator usPostalMoneyOrderValidator;
|
||||
private final WeChatPayValidator weChatPayValidator;
|
||||
private final HalCashValidator halCashValidator;
|
||||
@ -160,6 +164,7 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
||||
ClearXchangeValidator clearXchangeValidator,
|
||||
ChaseQuickPayValidator chaseQuickPayValidator,
|
||||
InteracETransferValidator interacETransferValidator,
|
||||
JapanBankTransferValidator japanBankTransferValidator,
|
||||
USPostalMoneyOrderValidator usPostalMoneyOrderValidator,
|
||||
WeChatPayValidator weChatPayValidator,
|
||||
HalCashValidator halCashValidator,
|
||||
@ -183,6 +188,7 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
||||
this.clearXchangeValidator = clearXchangeValidator;
|
||||
this.chaseQuickPayValidator = chaseQuickPayValidator;
|
||||
this.interacETransferValidator = interacETransferValidator;
|
||||
this.japanBankTransferValidator = japanBankTransferValidator;
|
||||
this.usPostalMoneyOrderValidator = usPostalMoneyOrderValidator;
|
||||
this.weChatPayValidator = weChatPayValidator;
|
||||
this.halCashValidator = halCashValidator;
|
||||
@ -436,6 +442,8 @@ public class FiatAccountsView extends PaymentAccountsView<GridPane, FiatAccounts
|
||||
return new SameBankForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.SPECIFIC_BANKS_ID:
|
||||
return new SpecificBankForm(paymentAccount, accountAgeWitnessService, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.JAPAN_BANK_ID:
|
||||
return new JapanBankTransferForm(paymentAccount, accountAgeWitnessService, japanBankTransferValidator, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.ALI_PAY_ID:
|
||||
return new AliPayForm(paymentAccount, accountAgeWitnessService, aliPayValidator, inputValidator, root, gridRow, formatter);
|
||||
case PaymentMethod.WECHAT_PAY_ID:
|
||||
|
@ -140,7 +140,7 @@ public class ManageMarketAlertsWindow extends Overlay<ManageMarketAlertsWindow>
|
||||
public void updateItem(final MarketAlertFilter item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
setText(formatter.formatPercentagePrice(item.getTriggerValue() / 10000d));
|
||||
setText(BSFormatter.formatPercentagePrice(item.getTriggerValue() / 10000d));
|
||||
} else {
|
||||
setText("");
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.user.User;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.validation.InputValidator;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
@ -347,7 +348,7 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
|
||||
private void onAddMarketAlert() {
|
||||
PaymentAccount paymentAccount = paymentAccountsComboBox.getSelectionModel().getSelectedItem();
|
||||
double percentAsDouble = formatter.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText());
|
||||
double percentAsDouble = ParsingUtils.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText());
|
||||
int triggerValue = (int) Math.round(percentAsDouble * 10000);
|
||||
boolean isBuyOffer = offerTypeRadioButtonsToggleGroup.getSelectedToggle() == buyOffersRadioButton;
|
||||
MarketAlertFilter marketAlertFilter = new MarketAlertFilter(paymentAccount, triggerValue, isBuyOffer);
|
||||
@ -510,8 +511,8 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
marketAlertTriggerFocusListener = (observable, oldValue, newValue) -> {
|
||||
if (oldValue && !newValue) {
|
||||
try {
|
||||
double percentAsDouble = formatter.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()) * 100;
|
||||
marketAlertTriggerInputTextField.setText(formatter.formatRoundedDoubleWithPrecision(percentAsDouble, 2) + "%");
|
||||
double percentAsDouble = ParsingUtils.parsePercentStringToDouble(marketAlertTriggerInputTextField.getText()) * 100;
|
||||
marketAlertTriggerInputTextField.setText(BSFormatter.formatRoundedDoubleWithPrecision(percentAsDouble, 2) + "%");
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
|
||||
@ -695,8 +696,8 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
currencyComboBox.getSelectionModel().select(optionalTradeCurrency.get());
|
||||
onSelectedTradeCurrency();
|
||||
|
||||
priceAlertHighInputTextField.setText(formatter.formatMarketPrice(priceAlertFilter.getHigh() / 10000d, currencyCode));
|
||||
priceAlertLowInputTextField.setText(formatter.formatMarketPrice(priceAlertFilter.getLow() / 10000d, currencyCode));
|
||||
priceAlertHighInputTextField.setText(BSFormatter.formatMarketPrice(priceAlertFilter.getHigh() / 10000d, currencyCode));
|
||||
priceAlertLowInputTextField.setText(BSFormatter.formatMarketPrice(priceAlertFilter.getLow() / 10000d, currencyCode));
|
||||
} else {
|
||||
currencyComboBox.getSelectionModel().clearSelection();
|
||||
}
|
||||
@ -747,15 +748,15 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
try {
|
||||
String inputValue = inputTextField.getText();
|
||||
if (inputValue != null && !inputValue.isEmpty() && selectedPriceAlertTradeCurrency != null) {
|
||||
double priceAsDouble = formatter.parseNumberStringToDouble(inputValue);
|
||||
double priceAsDouble = ParsingUtils.parseNumberStringToDouble(inputValue);
|
||||
String currencyCode = selectedPriceAlertTradeCurrency;
|
||||
int precision = CurrencyUtil.isCryptoCurrency(currencyCode) ?
|
||||
Altcoin.SMALLEST_UNIT_EXPONENT : 2;
|
||||
// We want to use the converted value not the inout value as we apply the converted value at focus out.
|
||||
// E.g. if input is 5555.5555 it will be rounded to 5555.55 and we use that as the value for comparing
|
||||
// low and high price...
|
||||
String stringValue = formatter.formatRoundedDoubleWithPrecision(priceAsDouble, precision);
|
||||
return formatter.parsePriceStringToLong(currencyCode, stringValue, precision);
|
||||
String stringValue = BSFormatter.formatRoundedDoubleWithPrecision(priceAsDouble, precision);
|
||||
return ParsingUtils.parsePriceStringToLong(currencyCode, stringValue, precision);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@ -768,11 +769,11 @@ public class MobileNotificationsView extends ActivatableView<GridPane, Void> {
|
||||
try {
|
||||
String inputValue = inputTextField.getText();
|
||||
if (inputValue != null && !inputValue.isEmpty() && selectedPriceAlertTradeCurrency != null) {
|
||||
double priceAsDouble = formatter.parseNumberStringToDouble(inputValue);
|
||||
double priceAsDouble = ParsingUtils.parseNumberStringToDouble(inputValue);
|
||||
String currencyCode = selectedPriceAlertTradeCurrency;
|
||||
int precision = CurrencyUtil.isCryptoCurrency(currencyCode) ?
|
||||
Altcoin.SMALLEST_UNIT_EXPONENT : 2;
|
||||
String stringValue = formatter.formatRoundedDoubleWithPrecision(priceAsDouble, precision);
|
||||
String stringValue = BSFormatter.formatRoundedDoubleWithPrecision(priceAsDouble, precision);
|
||||
inputTextField.setText(stringValue);
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
|
@ -113,7 +113,7 @@ public class BondingViewUtils {
|
||||
Coin miningFee = miningFeeAndTxSize.first;
|
||||
int txSize = miningFeeAndTxSize.second;
|
||||
BSFormatter formatter = new BSFormatter();
|
||||
String duration = formatter.formatDurationAsWords(lockupTime * 10 * 60 * 1000L, false, false);
|
||||
String duration = BSFormatter.formatDurationAsWords(lockupTime * 10 * 60 * 1000L, false, false);
|
||||
new Popup<>().headLine(Res.get("dao.bond.reputation.lockup.headline"))
|
||||
.confirmation(Res.get("dao.bond.reputation.lockup.details",
|
||||
bsqFormatter.formatCoinWithCode(lockupAmount),
|
||||
@ -174,7 +174,7 @@ public class BondingViewUtils {
|
||||
Coin miningFee = miningFeeAndTxSize.first;
|
||||
int txSize = miningFeeAndTxSize.second;
|
||||
BSFormatter formatter = new BSFormatter();
|
||||
String duration = formatter.formatDurationAsWords(lockTime * 10 * 60 * 1000L, false, false);
|
||||
String duration = BSFormatter.formatDurationAsWords(lockTime * 10 * 60 * 1000L, false, false);
|
||||
new Popup<>().headLine(Res.get("dao.bond.reputation.unlock.headline"))
|
||||
.confirmation(Res.get("dao.bond.reputation.unlock.details",
|
||||
bsqFormatter.formatCoinWithCode(unlockAmount),
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package bisq.desktop.main.dao.bonding.bonds;
|
||||
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.dao.governance.bond.Bond;
|
||||
import bisq.core.dao.governance.bond.BondState;
|
||||
import bisq.core.dao.governance.bond.role.BondedRole;
|
||||
@ -58,7 +60,7 @@ class BondListItem {
|
||||
bondDetails = Utilities.bytesAsHexString(bond.getBondedAsset().getHash());
|
||||
}
|
||||
lockupTxId = bond.getLockupTxId();
|
||||
lockupDateString = bond.getLockupDate() > 0 ? bsqFormatter.formatDateTime(new Date(bond.getLockupDate())) : "-";
|
||||
lockupDateString = bond.getLockupDate() > 0 ? DisplayUtils.formatDateTime(new Date(bond.getLockupDate())) : "-";
|
||||
bondState = bond.getBondState();
|
||||
bondStateString = Res.get("dao.bond.bondState." + bond.getBondState().name());
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package bisq.desktop.main.dao.bonding.reputation;
|
||||
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.dao.governance.bond.BondState;
|
||||
import bisq.core.dao.governance.bond.reputation.MyBondedReputation;
|
||||
import bisq.core.dao.governance.bond.reputation.MyReputation;
|
||||
@ -57,7 +59,7 @@ class MyReputationListItem {
|
||||
txId = myBondedReputation.getLockupTxId();
|
||||
amount = bsqFormatter.formatCoin(Coin.valueOf(myBondedReputation.getAmount()));
|
||||
lockupDate = new Date(myBondedReputation.getLockupDate());
|
||||
lockupDateString = bsqFormatter.formatDateTime(lockupDate);
|
||||
lockupDateString = DisplayUtils.formatDateTime(lockupDate);
|
||||
lockTime = Integer.toString(myBondedReputation.getLockTime());
|
||||
lockupTxId = myBondedReputation.getLockupTxId();
|
||||
bondState = myBondedReputation.getBondState();
|
||||
|
@ -38,6 +38,7 @@ import bisq.core.dao.governance.bond.reputation.MyBondedReputation;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.validation.HexStringValidator;
|
||||
import bisq.core.util.validation.IntegerValidator;
|
||||
|
||||
@ -170,7 +171,7 @@ public class MyReputationView extends ActivatableView<GridPane, Void> implements
|
||||
bsqWalletService.addBsqBalanceListener(this);
|
||||
|
||||
lockupButton.setOnAction((event) -> {
|
||||
Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText());
|
||||
Coin lockupAmount = ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter);
|
||||
int lockupTime = Integer.parseInt(timeInputTextField.getText());
|
||||
byte[] salt = Utilities.decodeFromHex(saltInputTextField.getText());
|
||||
bondingViewUtils.lockupBondForReputation(lockupAmount,
|
||||
|
@ -18,6 +18,7 @@
|
||||
package bisq.desktop.main.dao.bonding.roles;
|
||||
|
||||
import bisq.desktop.main.overlays.Overlay;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
|
||||
import bisq.core.dao.DaoFacade;
|
||||
@ -97,6 +98,6 @@ class RoleDetailsWindow extends Overlay<RoleDetailsWindow> {
|
||||
bondedRoleType.getLink(), bondedRoleType.getLink(), 0);
|
||||
|
||||
FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.get("dao.bond.details.isSingleton"),
|
||||
bsqFormatter.booleanToYesNo(bondedRoleType.isAllowMultipleHolders()));
|
||||
DisplayUtils.booleanToYesNo(bondedRoleType.isAllowMultipleHolders()));
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import bisq.core.locale.CurrencyUtil;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import bisq.common.app.DevEnv;
|
||||
|
||||
@ -273,7 +274,7 @@ public class AssetFeeView extends ActivatableView<GridPane, Void> implements Bsq
|
||||
}
|
||||
|
||||
private Coin getListingFee() {
|
||||
return bsqFormatter.parseToCoin(feeAmountInputTextField.getText());
|
||||
return ParsingUtils.parseToCoin(feeAmountInputTextField.getText(), bsqFormatter);
|
||||
}
|
||||
|
||||
private void doPublishFeeTx(Transaction transaction) {
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package bisq.desktop.main.dao.burnbsq.proofofburn;
|
||||
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.dao.governance.proofofburn.MyProofOfBurn;
|
||||
import bisq.core.dao.governance.proofofburn.ProofOfBurnService;
|
||||
import bisq.core.dao.state.model.blockchain.Tx;
|
||||
@ -52,7 +54,7 @@ class MyProofOfBurnListItem {
|
||||
if (optionalTx.isPresent()) {
|
||||
Tx tx = optionalTx.get();
|
||||
date = new Date(tx.getTime());
|
||||
dateAsString = bsqFormatter.formatDateTime(date);
|
||||
dateAsString = DisplayUtils.formatDateTime(date);
|
||||
amount = proofOfBurnService.getAmount(tx);
|
||||
amountAsString = bsqFormatter.formatCoinWithCode(Coin.valueOf(amount));
|
||||
txId = tx.getId();
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package bisq.desktop.main.dao.burnbsq.proofofburn;
|
||||
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.dao.governance.proofofburn.ProofOfBurnService;
|
||||
import bisq.core.dao.state.model.blockchain.Tx;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
@ -46,6 +48,6 @@ class ProofOfBurnListItem {
|
||||
hashAsHex = Utilities.bytesAsHexString(proofOfBurnService.getHashFromOpReturnData(tx));
|
||||
pubKey = Utilities.bytesAsHexString(proofOfBurnService.getPubKey(txId));
|
||||
date = new Date(tx.getTime());
|
||||
dateAsString = bsqFormatter.formatDateTime(date);
|
||||
dateAsString = DisplayUtils.formatDateTime(date);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ import bisq.core.locale.Res;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.validation.InputValidator;
|
||||
|
||||
import bisq.common.app.DevEnv;
|
||||
@ -273,7 +274,7 @@ public class ProofOfBurnView extends ActivatableView<GridPane, Void> implements
|
||||
}
|
||||
|
||||
private Coin getAmountFee() {
|
||||
return bsqFormatter.parseToCoin(amountInputTextField.getText());
|
||||
return ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter);
|
||||
}
|
||||
|
||||
private void doPublishFeeTx(Transaction transaction, String preImageAsString) {
|
||||
|
@ -308,7 +308,7 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
|
||||
Optional<Price> optionalBsqPrice = priceFeedService.getBsqPrice();
|
||||
if (optionalBsqPrice.isPresent()) {
|
||||
Price bsqPrice = optionalBsqPrice.get();
|
||||
marketPriceLabel.setText(bsqFormatter.formatPrice(bsqPrice) + " BSQ/BTC");
|
||||
marketPriceLabel.setText(BSFormatter.formatPrice(bsqPrice) + " BSQ/BTC");
|
||||
|
||||
marketCapTextField.setText(bsqFormatter.formatMarketCap(priceFeedService.getMarketPrice("BSQ"),
|
||||
priceFeedService.getMarketPrice(preferences.getPreferredTradeCurrency().getCode()),
|
||||
|
@ -52,6 +52,7 @@ import bisq.core.dao.state.model.governance.Role;
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import bisq.asset.Asset;
|
||||
|
||||
@ -395,13 +396,13 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
|
||||
"proposalDisplay.requestedBsqTextField must not be null");
|
||||
return daoFacade.getCompensationProposalWithTransaction(name,
|
||||
link,
|
||||
bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()));
|
||||
ParsingUtils.parseToCoin(proposalDisplay.requestedBsqTextField.getText(), bsqFormatter));
|
||||
case REIMBURSEMENT_REQUEST:
|
||||
checkNotNull(proposalDisplay.requestedBsqTextField,
|
||||
"proposalDisplay.requestedBsqTextField must not be null");
|
||||
return daoFacade.getReimbursementProposalWithTransaction(name,
|
||||
link,
|
||||
bsqFormatter.parseToCoin(proposalDisplay.requestedBsqTextField.getText()));
|
||||
ParsingUtils.parseToCoin(proposalDisplay.requestedBsqTextField.getText(), bsqFormatter));
|
||||
case CHANGE_PARAM:
|
||||
checkNotNull(proposalDisplay.paramComboBox,
|
||||
"proposalDisplay.paramComboBox must no tbe null");
|
||||
|
@ -30,6 +30,7 @@ import bisq.desktop.components.TxIdTextField;
|
||||
import bisq.desktop.main.dao.governance.PhasesView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.SelectProposalWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.Layout;
|
||||
import bisq.desktop.util.validation.BsqValidator;
|
||||
@ -54,6 +55,7 @@ import bisq.core.locale.Res;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.app.DevEnv;
|
||||
@ -462,7 +464,7 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||
}
|
||||
|
||||
private void onVote() {
|
||||
Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText());
|
||||
Coin stake = ParsingUtils.parseToCoin(stakeInputTextField.getText(), bsqFormatter);
|
||||
try {
|
||||
// We create a dummy tx to get the miningFee for displaying it at the confirmation popup
|
||||
Tuple2<Coin, Integer> miningFeeAndTxSize = daoFacade.getBlindVoteMiningFeeAndTxSize(stake);
|
||||
@ -718,7 +720,7 @@ public class ProposalsView extends ActivatableView<GridPane, Void> implements Bs
|
||||
public void updateItem(final ProposalsListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(bsqFormatter.formatDateTime(item.getProposal().getCreationDateAsDate()));
|
||||
setText(DisplayUtils.formatDateTime(item.getProposal().getCreationDateAsDate()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import bisq.desktop.components.TableGroupHeadline;
|
||||
import bisq.desktop.main.dao.governance.PhasesView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.ProposalResultsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.Layout;
|
||||
@ -637,7 +638,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
public void updateItem(final ProposalListItem item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(bsqFormatter.formatDateTime(item.getProposal().getCreationDateAsDate()));
|
||||
setText(DisplayUtils.formatDateTime(item.getProposal().getCreationDateAsDate()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ import bisq.core.locale.Res;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.CoinUtil;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.validation.BtcAddressValidator;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
@ -234,7 +235,7 @@ public class BsqSendView extends ActivatableView<GridPane, Void> implements BsqB
|
||||
// TODO break up in methods
|
||||
if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) {
|
||||
String receiversAddressString = bsqFormatter.getAddressFromBsqAddress(receiversAddressInputTextField.getText()).toString();
|
||||
Coin receiverAmount = bsqFormatter.parseToCoin(amountInputTextField.getText());
|
||||
Coin receiverAmount = ParsingUtils.parseToCoin(amountInputTextField.getText(), bsqFormatter);
|
||||
try {
|
||||
Transaction preparedSendTx = bsqWalletService.getPreparedSendBsqTx(receiversAddressString, receiverAmount);
|
||||
Transaction txWithBtcFee = btcWalletService.completePreparedSendBsqTx(preparedSendTx, true);
|
||||
|
@ -24,6 +24,7 @@ import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.AutoTooltipTableColumn;
|
||||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.main.dao.wallet.BsqBalanceUtil;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
@ -367,7 +368,7 @@ public class BsqTxView extends ActivatableView<GridPane, Void> implements BsqBal
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null && !empty) {
|
||||
setText(bsqFormatter.formatDateTime(item.getDate()));
|
||||
setText(DisplayUtils.formatDateTime(item.getDate()));
|
||||
} else {
|
||||
setText("");
|
||||
}
|
||||
@ -630,7 +631,7 @@ public class BsqTxView extends ActivatableView<GridPane, Void> implements BsqBal
|
||||
style = "dao-tx-type-issuance-icon";
|
||||
int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId);
|
||||
long blockTime = daoFacade.getBlockTime(issuanceBlockHeight);
|
||||
String formattedDate = bsqFormatter.formatDateTime(new Date(blockTime));
|
||||
String formattedDate = DisplayUtils.formatDateTime(new Date(blockTime));
|
||||
toolTipText = Res.get("dao.tx.issuanceFromCompReq.tooltip", formattedDate);
|
||||
} else {
|
||||
awesomeIcon = AwesomeIcon.FILE_TEXT;
|
||||
@ -644,7 +645,7 @@ public class BsqTxView extends ActivatableView<GridPane, Void> implements BsqBal
|
||||
style = "dao-tx-type-issuance-icon";
|
||||
int issuanceBlockHeight = daoFacade.getIssuanceBlockHeight(txId);
|
||||
long blockTime = daoFacade.getBlockTime(issuanceBlockHeight);
|
||||
String formattedDate = bsqFormatter.formatDateTime(new Date(blockTime));
|
||||
String formattedDate = DisplayUtils.formatDateTime(new Date(blockTime));
|
||||
toolTipText = Res.get("dao.tx.issuanceFromReimbursement.tooltip", formattedDate);
|
||||
} else {
|
||||
awesomeIcon = AwesomeIcon.FILE_TEXT;
|
||||
|
@ -22,6 +22,7 @@ import bisq.desktop.main.disputes.trader.TraderDisputeView;
|
||||
import bisq.desktop.main.overlays.windows.ContractWindow;
|
||||
import bisq.desktop.main.overlays.windows.DisputeSummaryWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.alert.PrivateNotificationManager;
|
||||
@ -79,7 +80,7 @@ public class ArbitratorDisputeView extends TraderDisputeView {
|
||||
// If in arbitrator view we must only display disputes where we are selected as arbitrator (must not receive others anyway)
|
||||
filteredList.setPredicate(dispute -> {
|
||||
boolean matchesTradeId = dispute.getTradeId().contains(filterString);
|
||||
boolean matchesDate = formatter.formatDate(dispute.getOpeningDate()).contains(filterString);
|
||||
boolean matchesDate = DisplayUtils.formatDate(dispute.getOpeningDate()).contains(filterString);
|
||||
boolean isBuyerOnion = dispute.getContract().getBuyerNodeAddress().getFullAddress().contains(filterString);
|
||||
boolean isSellerOnion = dispute.getContract().getSellerNodeAddress().getFullAddress().contains(filterString);
|
||||
boolean matchesBuyersPaymentAccountData = dispute.getContract().getBuyerPaymentAccountPayload().getPaymentDetails().contains(filterString);
|
||||
|
@ -30,6 +30,7 @@ import bisq.desktop.main.overlays.windows.ContractWindow;
|
||||
import bisq.desktop.main.overlays.windows.DisputeSummaryWindow;
|
||||
import bisq.desktop.main.overlays.windows.SendPrivateNotificationWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
@ -224,7 +225,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
dateColumn.setComparator(Comparator.comparing(Dispute::getOpeningDate));
|
||||
buyerOnionAddressColumn.setComparator(Comparator.comparing(this::getBuyerOnionAddressColumnLabel));
|
||||
sellerOnionAddressColumn.setComparator(Comparator.comparing(this::getSellerOnionAddressColumnLabel));
|
||||
marketColumn.setComparator((o1, o2) -> formatter.getCurrencyPair(o1.getContract().getOfferPayload().getCurrencyCode()).compareTo(o2.getContract().getOfferPayload().getCurrencyCode()));
|
||||
marketColumn.setComparator((o1, o2) -> BSFormatter.getCurrencyPair(o1.getContract().getOfferPayload().getCurrencyCode()).compareTo(o2.getContract().getOfferPayload().getCurrencyCode()));
|
||||
|
||||
dateColumn.setSortType(TableColumn.SortType.DESCENDING);
|
||||
tableView.getSortOrder().add(dateColumn);
|
||||
@ -257,7 +258,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
.append(dispute0.getTradeId())
|
||||
.append("\n")
|
||||
.append("## Date: ")
|
||||
.append(formatter.formatDateTime(dispute0.getOpeningDate()))
|
||||
.append(DisplayUtils.formatDateTime(dispute0.getOpeningDate()))
|
||||
.append("\n")
|
||||
.append("## Is support ticket: ")
|
||||
.append(dispute0.isSupportTicket())
|
||||
@ -582,7 +583,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
public void updateItem(final Dispute item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty)
|
||||
setText(formatter.formatDateTime(item.getOpeningDate()));
|
||||
setText(DisplayUtils.formatDateTime(item.getOpeningDate()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
@ -693,7 +694,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
if (buyerNodeAddress != null) {
|
||||
String nrOfDisputes = disputeManager.getNrOfDisputes(true, contract);
|
||||
long accountAge = accountAgeWitnessService.getAccountAge(contract.getBuyerPaymentAccountPayload(), contract.getBuyerPubKeyRing());
|
||||
String age = formatter.formatAccountAge(accountAge);
|
||||
String age = DisplayUtils.formatAccountAge(accountAge);
|
||||
String postFix = CurrencyUtil.isFiatCurrency(item.getContract().getOfferPayload().getCurrencyCode()) ? " / " + age : "";
|
||||
return buyerNodeAddress.getHostNameWithoutPostFix() + " (" + nrOfDisputes + postFix + ")";
|
||||
} else
|
||||
@ -710,7 +711,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
if (sellerNodeAddress != null) {
|
||||
String nrOfDisputes = disputeManager.getNrOfDisputes(false, contract);
|
||||
long accountAge = accountAgeWitnessService.getAccountAge(contract.getSellerPaymentAccountPayload(), contract.getSellerPubKeyRing());
|
||||
String age = formatter.formatAccountAge(accountAge);
|
||||
String age = DisplayUtils.formatAccountAge(accountAge);
|
||||
String postFix = CurrencyUtil.isFiatCurrency(item.getContract().getOfferPayload().getCurrencyCode()) ? " / " + age : "";
|
||||
return sellerNodeAddress.getHostNameWithoutPostFix() + " (" + nrOfDisputes + postFix + ")";
|
||||
} else
|
||||
@ -736,7 +737,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
public void updateItem(final Dispute item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty)
|
||||
setText(formatter.getCurrencyPair(item.getContract().getOfferPayload().getCurrencyCode()));
|
||||
setText(BSFormatter.getCurrencyPair(item.getContract().getOfferPayload().getCurrencyCode()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import bisq.core.locale.Res;
|
||||
import bisq.core.provider.fee.FeeService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
|
||||
import bisq.common.UserThread;
|
||||
import bisq.common.app.DevEnv;
|
||||
@ -232,7 +233,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
||||
|
||||
walletService.addBalanceListener(balanceListener);
|
||||
amountTextFieldSubscription = EasyBind.subscribe(amountTextField.textProperty(), t -> {
|
||||
addressTextField.setAmountAsCoin(formatter.parseToCoin(t));
|
||||
addressTextField.setAmountAsCoin(ParsingUtils.parseToCoin(t, formatter));
|
||||
updateQRCode();
|
||||
});
|
||||
|
||||
@ -301,7 +302,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
||||
}
|
||||
|
||||
private Coin getAmountAsCoin() {
|
||||
return formatter.parseToCoin(amountTextField.getText());
|
||||
return ParsingUtils.parseToCoin(amountTextField.getText(), formatter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -23,6 +23,7 @@ import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
@ -228,7 +229,7 @@ public class LockedView extends ActivatableView<VBox, Void> {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
if (getTradable(item).isPresent())
|
||||
setGraphic(new AutoTooltipLabel(formatter.formatDateTime(getTradable(item).get().getDate())));
|
||||
setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(getTradable(item).get().getDate())));
|
||||
else
|
||||
setGraphic(new AutoTooltipLabel(Res.get("shared.noDateAvailable")));
|
||||
} else {
|
||||
|
@ -23,6 +23,7 @@ import bisq.desktop.components.AutoTooltipLabel;
|
||||
import bisq.desktop.components.HyperlinkWithIcon;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.btc.listeners.BalanceListener;
|
||||
@ -228,7 +229,7 @@ public class ReservedView extends ActivatableView<VBox, Void> {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null && !empty) {
|
||||
if (getTradable(item).isPresent())
|
||||
setGraphic(new AutoTooltipLabel(formatter.formatDateTime(getTradable(item).get().getDate())));
|
||||
setGraphic(new AutoTooltipLabel(DisplayUtils.formatDateTime(getTradable(item).get().getDate())));
|
||||
else
|
||||
setGraphic(new AutoTooltipLabel(Res.get("shared.noDateAvailable")));
|
||||
} else {
|
||||
|
@ -18,6 +18,7 @@
|
||||
package bisq.desktop.main.funds.transactions;
|
||||
|
||||
import bisq.desktop.components.indicator.TxConfidenceIndicator;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.btc.listeners.TxConfidenceListener;
|
||||
@ -239,7 +240,7 @@ class TransactionsListItem {
|
||||
}
|
||||
// Use tx.getIncludedInBestChainAt() when available, otherwise use tx.getUpdateTime()
|
||||
date = transaction.getIncludedInBestChainAt() != null ? transaction.getIncludedInBestChainAt() : transaction.getUpdateTime();
|
||||
dateString = formatter.formatDateTime(date);
|
||||
dateString = DisplayUtils.formatDateTime(date);
|
||||
|
||||
isDustAttackTx = received && valueSentToMe.value < ignoreDustThreshold;
|
||||
if (isDustAttackTx) {
|
||||
|
@ -41,6 +41,7 @@ import bisq.core.trade.TradeManager;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.CoinUtil;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.validation.BtcAddressValidator;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
@ -246,7 +247,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||
amountListener = (observable, oldValue, newValue) -> {
|
||||
if (amountTextField.focusedProperty().get()) {
|
||||
try {
|
||||
amountAsCoin = formatter.parseToCoin(amountTextField.getText());
|
||||
amountAsCoin = ParsingUtils.parseToCoin(amountTextField.getText(), formatter);
|
||||
} catch (Throwable t) {
|
||||
log.error("Error at amountTextField input. " + t.toString());
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import bisq.desktop.main.market.trades.TradesChartsView;
|
||||
import bisq.desktop.main.offer.offerbook.OfferBook;
|
||||
import bisq.desktop.main.offer.offerbook.OfferBookListItem;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.locale.Res;
|
||||
import bisq.core.offer.OfferPayload;
|
||||
@ -183,11 +184,11 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
.map(trade -> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Trade ID: ").append(trade.getOfferId()).append("\n")
|
||||
.append("Date: ").append(formatter.formatDateTime(trade.getTradeDate())).append("\n")
|
||||
.append("Market: ").append(formatter.getCurrencyPair(trade.getCurrencyCode())).append("\n")
|
||||
.append("Price: ").append(formatter.formatPrice(trade.getTradePrice())).append("\n")
|
||||
.append("Date: ").append(DisplayUtils.formatDateTime(trade.getTradeDate())).append("\n")
|
||||
.append("Market: ").append(BSFormatter.getCurrencyPair(trade.getCurrencyCode())).append("\n")
|
||||
.append("Price: ").append(BSFormatter.formatPrice(trade.getTradePrice())).append("\n")
|
||||
.append("Amount: ").append(formatter.formatCoin(trade.getTradeAmount())).append("\n")
|
||||
.append("Volume: ").append(formatter.formatVolume(trade.getTradeVolume())).append("\n")
|
||||
.append("Volume: ").append(DisplayUtils.formatVolume(trade.getTradeVolume())).append("\n")
|
||||
.append("Payment method: ").append(Res.get(trade.getOfferPaymentMethod())).append("\n")
|
||||
.append("ReferralID: ").append(trade.getExtraDataMap().get(OfferPayload.REFERRAL_ID));
|
||||
return sb.toString();
|
||||
@ -205,9 +206,9 @@ public class MarketView extends ActivatableViewAndModel<TabPane, Activatable> {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Offer ID: ").append(offer.getId()).append("\n")
|
||||
.append("Type: ").append(offer.getDirection().name()).append("\n")
|
||||
.append("Market: ").append(formatter.getCurrencyPair(offer.getCurrencyCode())).append("\n")
|
||||
.append("Price: ").append(formatter.formatPrice(offer.getPrice())).append("\n")
|
||||
.append("Amount: ").append(formatter.formatAmount(offer)).append(" BTC\n")
|
||||
.append("Market: ").append(BSFormatter.getCurrencyPair(offer.getCurrencyCode())).append("\n")
|
||||
.append("Price: ").append(BSFormatter.formatPrice(offer.getPrice())).append("\n")
|
||||
.append("Amount: ").append(DisplayUtils.formatAmount(offer, formatter)).append(" BTC\n")
|
||||
.append("Payment method: ").append(Res.get(offer.getPaymentMethod().getId())).append("\n")
|
||||
.append("ReferralID: ").append(offer.getOfferPayload().getExtraDataMap().get(OfferPayload.REFERRAL_ID));
|
||||
return sb.toString();
|
||||
|
@ -223,15 +223,15 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||
public String toString(Number object) {
|
||||
final double doubleValue = (double) object;
|
||||
if (CurrencyUtil.isCryptoCurrency(model.getCurrencyCode())) {
|
||||
final String withCryptoPrecision = formatter.formatRoundedDoubleWithPrecision(doubleValue, cryptoPrecision);
|
||||
final String withCryptoPrecision = BSFormatter.formatRoundedDoubleWithPrecision(doubleValue, cryptoPrecision);
|
||||
if (withCryptoPrecision.equals("0.000")) {
|
||||
cryptoPrecision = 8;
|
||||
return formatter.formatRoundedDoubleWithPrecision(doubleValue, cryptoPrecision);
|
||||
return BSFormatter.formatRoundedDoubleWithPrecision(doubleValue, cryptoPrecision);
|
||||
} else {
|
||||
return withCryptoPrecision;
|
||||
}
|
||||
} else {
|
||||
return formatter.formatRoundedDoubleWithPrecision(doubleValue, 2);
|
||||
return BSFormatter.formatRoundedDoubleWithPrecision(doubleValue, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ public class OfferBookChartView extends ActivatableViewAndModel<VBox, OfferBookC
|
||||
|
||||
priceColumnLabel.set(Res.get("shared.priceWithCur", code));
|
||||
}
|
||||
xAxis.setLabel(formatter.getPriceWithCurrencyCode(code));
|
||||
xAxis.setLabel(BSFormatter.getPriceWithCurrencyCode(code));
|
||||
|
||||
seriesBuy.setName(leftHeaderLabel.getText() + " ");
|
||||
seriesSell.setName(rightHeaderLabel.getText());
|
||||
|
@ -26,6 +26,7 @@ import bisq.desktop.main.settings.SettingsView;
|
||||
import bisq.desktop.main.settings.preferences.PreferencesView;
|
||||
import bisq.desktop.util.CurrencyList;
|
||||
import bisq.desktop.util.CurrencyListItem;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
@ -254,7 +255,7 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
}
|
||||
|
||||
private String formatPrice(Offer offer, boolean decimalAligned) {
|
||||
return formatter.formatPrice(offer.getPrice(), decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyPrice.get() : maxPlacesForSellPrice.get());
|
||||
return DisplayUtils.formatPrice(offer.getPrice(), decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyPrice.get() : maxPlacesForSellPrice.get());
|
||||
}
|
||||
|
||||
public String getVolume(Offer offer) {
|
||||
@ -262,7 +263,7 @@ class OfferBookChartViewModel extends ActivatableViewModel {
|
||||
}
|
||||
|
||||
private String formatVolume(Offer offer, boolean decimalAligned) {
|
||||
return formatter.formatVolume(offer, decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyVolume.get() : maxPlacesForSellVolume.get(), false);
|
||||
return DisplayUtils.formatVolume(offer, decimalAligned, offer.isBuyOffer() ? maxPlacesForBuyVolume.get() : maxPlacesForSellVolume.get(), false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -185,7 +185,7 @@ class SpreadViewModel extends ActivatableViewModel {
|
||||
.multiply(BigDecimal.valueOf(10000))
|
||||
.divide(marketPriceAsBigDecimal, RoundingMode.HALF_UP)
|
||||
.doubleValue() / 10000;
|
||||
percentage = formatter.formatPercentagePrice(percentageValue);
|
||||
percentage = BSFormatter.formatPercentagePrice(percentageValue);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
try {
|
||||
|
@ -27,6 +27,7 @@ import bisq.desktop.components.ColoredDecimalPlacesWithZerosText;
|
||||
import bisq.desktop.main.market.trades.charts.price.CandleStickChart;
|
||||
import bisq.desktop.main.market.trades.charts.volume.VolumeChart;
|
||||
import bisq.desktop.util.CurrencyListItem;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.locale.CurrencyUtil;
|
||||
@ -239,7 +240,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
String code = selectedTradeCurrency.getCode();
|
||||
volumeColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.amountWithCur", code)));
|
||||
|
||||
priceColumnLabel.set(formatter.getPriceWithCurrencyCode(code));
|
||||
priceColumnLabel.set(BSFormatter.getPriceWithCurrencyCode(code));
|
||||
|
||||
tableView.getColumns().remove(marketColumn);
|
||||
}
|
||||
@ -345,9 +346,9 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
double doubleValue = (double) object;
|
||||
if (CurrencyUtil.isCryptoCurrency(currencyCode)) {
|
||||
final double value = MathUtils.scaleDownByPowerOf10(doubleValue, 8);
|
||||
return formatter.formatRoundedDoubleWithPrecision(value, 8);
|
||||
return BSFormatter.formatRoundedDoubleWithPrecision(value, 8);
|
||||
} else {
|
||||
return formatter.formatPrice(Price.valueOf(currencyCode, MathUtils.doubleToLong(doubleValue)));
|
||||
return BSFormatter.formatPrice(Price.valueOf(currencyCode, MathUtils.doubleToLong(doubleValue)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,9 +363,9 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
public String toString(Number object) {
|
||||
if (CurrencyUtil.isCryptoCurrency(model.getCurrencyCode())) {
|
||||
final double value = MathUtils.scaleDownByPowerOf10((long) object, 8);
|
||||
return formatter.formatRoundedDoubleWithPrecision(value, 8);
|
||||
return BSFormatter.formatRoundedDoubleWithPrecision(value, 8);
|
||||
} else {
|
||||
return formatter.formatPrice(Price.valueOf(model.getCurrencyCode(), (long) object));
|
||||
return BSFormatter.formatPrice(Price.valueOf(model.getCurrencyCode(), (long) object));
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,9 +481,9 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
long index = MathUtils.doubleToLong((double) object);
|
||||
long time = model.getTimeFromTickIndex(index);
|
||||
if (model.tickUnit.ordinal() <= TradesChartsViewModel.TickUnit.DAY.ordinal())
|
||||
return index % 4 == 0 ? formatter.formatDate(new Date(time)) : "";
|
||||
return index % 4 == 0 ? DisplayUtils.formatDate(new Date(time)) : "";
|
||||
else
|
||||
return index % 3 == 0 ? formatter.formatTime(new Date(time)) : "";
|
||||
return index % 3 == 0 ? DisplayUtils.formatTime(new Date(time)) : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -568,7 +569,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
public void updateItem(final TradeStatistics2 item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(formatter.formatDateTime(item.getTradeDate()));
|
||||
setText(DisplayUtils.formatDateTime(item.getTradeDate()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
@ -597,7 +598,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
public void updateItem(final TradeStatistics2 item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(formatter.getCurrencyPair(item.getCurrencyCode()));
|
||||
setText(BSFormatter.getCurrencyPair(item.getCurrencyCode()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
@ -621,7 +622,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
public void updateItem(final TradeStatistics2 item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(formatter.formatPrice(item.getTradePrice()));
|
||||
setText(BSFormatter.formatPrice(item.getTradePrice()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
@ -671,8 +672,8 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
super.updateItem(item, empty);
|
||||
if (item != null)
|
||||
setText(model.showAllTradeCurrenciesProperty.get() ?
|
||||
formatter.formatVolumeWithCode(item.getTradeVolume()) :
|
||||
formatter.formatVolume(item.getTradeVolume()));
|
||||
DisplayUtils.formatVolumeWithCode(item.getTradeVolume()) :
|
||||
DisplayUtils.formatVolume(item.getTradeVolume()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
@ -744,7 +745,7 @@ public class TradesChartsView extends ActivatableViewAndModel<VBox, TradesCharts
|
||||
|
||||
@NotNull
|
||||
private String getDirectionLabel(TradeStatistics2 item) {
|
||||
return formatter.getDirectionWithCode(OfferPayload.Direction.valueOf(item.getDirection().name()), item.getCurrencyCode());
|
||||
return DisplayUtils.getDirectionWithCode(OfferPayload.Direction.valueOf(item.getDirection().name()), item.getCurrencyCode());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -25,6 +25,7 @@ import bisq.desktop.main.settings.SettingsView;
|
||||
import bisq.desktop.main.settings.preferences.PreferencesView;
|
||||
import bisq.desktop.util.CurrencyList;
|
||||
import bisq.desktop.util.CurrencyListItem;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
|
||||
import bisq.core.locale.CryptoCurrency;
|
||||
@ -345,12 +346,12 @@ class TradesChartsViewModel extends ActivatableViewModel {
|
||||
final Date dateFrom = new Date(getTimeFromTickIndex(tick));
|
||||
final Date dateTo = new Date(getTimeFromTickIndex(tick + 1));
|
||||
String dateString = tickUnit.ordinal() > TickUnit.DAY.ordinal() ?
|
||||
formatter.formatDateTimeSpan(dateFrom, dateTo) :
|
||||
formatter.formatDate(dateFrom) + " - " + formatter.formatDate(dateTo);
|
||||
DisplayUtils.formatDateTimeSpan(dateFrom, dateTo) :
|
||||
DisplayUtils.formatDate(dateFrom) + " - " + DisplayUtils.formatDate(dateTo);
|
||||
return new CandleData(tick, open, close, high, low, averagePrice, medianPrice, accumulatedAmount, accumulatedVolume,
|
||||
numTrades, isBullish, dateString);
|
||||
}
|
||||
|
||||
|
||||
Long findMedian(Long[] prices) {
|
||||
int middle = prices.length / 2;
|
||||
long median;
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package bisq.desktop.main.offer;
|
||||
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
|
||||
import bisq.core.account.witness.AccountAgeRestrictions;
|
||||
import bisq.core.account.witness.AccountAgeWitnessService;
|
||||
import bisq.core.arbitration.Arbitrator;
|
||||
@ -656,7 +658,7 @@ public abstract class MutableOfferDataModel extends OfferDataModel implements Bs
|
||||
!price.get().isZero() &&
|
||||
allowAmountUpdate) {
|
||||
try {
|
||||
Coin value = btcFormatter.reduceTo4Decimals(price.get().getAmountByVolume(volume.get()));
|
||||
Coin value = DisplayUtils.reduceTo4Decimals(price.get().getAmountByVolume(volume.get()), btcFormatter);
|
||||
if (isHalCashAccount())
|
||||
value = OfferUtil.getAdjustedAmountForHalCash(value, price.get(), getMaxTradeLimit());
|
||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
||||
|
@ -567,11 +567,11 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel> extends
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void addBindings() {
|
||||
priceCurrencyLabel.textProperty().bind(createStringBinding(() -> btcFormatter.getCounterCurrency(model.tradeCurrencyCode.get()), model.tradeCurrencyCode));
|
||||
priceCurrencyLabel.textProperty().bind(createStringBinding(() -> BSFormatter.getCounterCurrency(model.tradeCurrencyCode.get()), model.tradeCurrencyCode));
|
||||
|
||||
marketBasedPriceLabel.prefWidthProperty().bind(priceCurrencyLabel.widthProperty());
|
||||
volumeCurrencyLabel.textProperty().bind(model.tradeCurrencyCode);
|
||||
priceDescriptionLabel.textProperty().bind(createStringBinding(() -> btcFormatter.getPriceWithCurrencyCode(model.tradeCurrencyCode.get(), "shared.fixedPriceInCurForCur"), model.tradeCurrencyCode));
|
||||
priceDescriptionLabel.textProperty().bind(createStringBinding(() -> BSFormatter.getPriceWithCurrencyCode(model.tradeCurrencyCode.get(), "shared.fixedPriceInCurForCur"), model.tradeCurrencyCode));
|
||||
volumeDescriptionLabel.textProperty().bind(createStringBinding(model.volumeDescriptionLabel::get, model.tradeCurrencyCode, model.volumeDescriptionLabel));
|
||||
amountTextField.textProperty().bindBidirectional(model.amount);
|
||||
minAmountTextField.textProperty().bindBidirectional(model.minAmount);
|
||||
|
@ -25,6 +25,7 @@ import bisq.desktop.main.funds.deposit.DepositView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.settings.SettingsView;
|
||||
import bisq.desktop.main.settings.preferences.PreferencesView;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.validation.AltcoinValidator;
|
||||
import bisq.desktop.util.validation.BsqValidator;
|
||||
@ -52,6 +53,7 @@ import bisq.core.provider.price.PriceFeedService;
|
||||
import bisq.core.user.Preferences;
|
||||
import bisq.core.util.BSFormatter;
|
||||
import bisq.core.util.BsqFormatter;
|
||||
import bisq.core.util.ParsingUtils;
|
||||
import bisq.core.util.validation.InputValidator;
|
||||
|
||||
import bisq.network.p2p.P2PService;
|
||||
@ -315,7 +317,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
if (marketPrice != null && marketPrice.isRecentExternalPriceAvailable()) {
|
||||
double marketPriceAsDouble = marketPrice.getPrice();
|
||||
try {
|
||||
double priceAsDouble = btcFormatter.parseNumberStringToDouble(price.get());
|
||||
double priceAsDouble = ParsingUtils.parseNumberStringToDouble(price.get());
|
||||
double relation = priceAsDouble / marketPriceAsDouble;
|
||||
final OfferPayload.Direction compareDirection = CurrencyUtil.isCryptoCurrency(currencyCode) ?
|
||||
OfferPayload.Direction.SELL :
|
||||
@ -323,7 +325,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
double percentage = dataModel.getDirection() == compareDirection ? 1 - relation : relation - 1;
|
||||
percentage = MathUtils.roundDouble(percentage, 4);
|
||||
dataModel.setMarketPriceMargin(percentage);
|
||||
marketPriceMargin.set(btcFormatter.formatToPercent(percentage));
|
||||
marketPriceMargin.set(BSFormatter.formatToPercent(percentage));
|
||||
applyMakerFee();
|
||||
} catch (NumberFormatException t) {
|
||||
marketPriceMargin.set("");
|
||||
@ -341,7 +343,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
if (inputIsMarketBasedPrice) {
|
||||
try {
|
||||
if (!newValue.isEmpty() && !newValue.equals("-")) {
|
||||
double percentage = btcFormatter.parsePercentStringToDouble(newValue);
|
||||
double percentage = ParsingUtils.parsePercentStringToDouble(newValue);
|
||||
if (percentage >= 1 || percentage <= -1) {
|
||||
new Popup<>().warning(Res.get("popup.warning.tooLargePercentageValue") + "\n" +
|
||||
Res.get("popup.warning.examplePercentageValue"))
|
||||
@ -364,7 +366,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
Altcoin.SMALLEST_UNIT_EXPONENT : Fiat.SMALLEST_UNIT_EXPONENT;
|
||||
// protect from triggering unwanted updates
|
||||
ignorePriceStringListener = true;
|
||||
price.set(btcFormatter.formatRoundedDoubleWithPrecision(targetPrice, precision));
|
||||
price.set(BSFormatter.formatRoundedDoubleWithPrecision(targetPrice, precision));
|
||||
ignorePriceStringListener = false;
|
||||
setPriceToModel();
|
||||
dataModel.setMarketPriceMargin(percentage);
|
||||
@ -441,7 +443,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
priceListener = (ov, oldValue, newValue) -> {
|
||||
ignorePriceStringListener = true;
|
||||
if (newValue != null)
|
||||
price.set(btcFormatter.formatPrice(newValue));
|
||||
price.set(BSFormatter.formatPrice(newValue));
|
||||
else
|
||||
price.set("");
|
||||
|
||||
@ -451,7 +453,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
volumeListener = (ov, oldValue, newValue) -> {
|
||||
ignoreVolumeStringListener = true;
|
||||
if (newValue != null)
|
||||
volume.set(btcFormatter.formatVolume(newValue));
|
||||
volume.set(DisplayUtils.formatVolume(newValue));
|
||||
else
|
||||
volume.set("");
|
||||
|
||||
@ -461,7 +463,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
securityDepositAsDoubleListener = (ov, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
buyerSecurityDeposit.set(btcFormatter.formatToPercent((double) newValue));
|
||||
buyerSecurityDeposit.set(BSFormatter.formatToPercent((double) newValue));
|
||||
if (dataModel.getAmount().get() != null)
|
||||
buyerSecurityDepositInBTC.set(btcFormatter.formatCoinWithCode(dataModel.getBuyerSecurityDepositAsCoin()));
|
||||
} else {
|
||||
@ -492,7 +494,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
Coin makerFeeInBtc = dataModel.getMakerFeeInBtc();
|
||||
Optional<Volume> optionalBtcFeeInFiat = OfferUtil.getFeeInUserFiatCurrency(makerFeeInBtc,
|
||||
true, preferences, priceFeedService, bsqFormatter);
|
||||
String btcFeeWithFiatAmount = OfferUtil.getFeeWithFiatAmount(makerFeeInBtc, optionalBtcFeeInFiat, btcFormatter);
|
||||
String btcFeeWithFiatAmount = DisplayUtils.getFeeWithFiatAmount(makerFeeInBtc, optionalBtcFeeInFiat, btcFormatter);
|
||||
if (DevEnv.isDaoActivated()) {
|
||||
tradeFeeInBtcWithFiat.set(btcFeeWithFiatAmount);
|
||||
} else {
|
||||
@ -502,14 +504,14 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
Coin makerFeeInBsq = dataModel.getMakerFeeInBsq();
|
||||
Optional<Volume> optionalBsqFeeInFiat = OfferUtil.getFeeInUserFiatCurrency(makerFeeInBsq,
|
||||
false, preferences, priceFeedService, bsqFormatter);
|
||||
String bsqFeeWithFiatAmount = OfferUtil.getFeeWithFiatAmount(makerFeeInBsq, optionalBsqFeeInFiat, bsqFormatter);
|
||||
String bsqFeeWithFiatAmount = DisplayUtils.getFeeWithFiatAmount(makerFeeInBsq, optionalBsqFeeInFiat, bsqFormatter);
|
||||
if (DevEnv.isDaoActivated()) {
|
||||
tradeFeeInBsqWithFiat.set(bsqFeeWithFiatAmount);
|
||||
} else {
|
||||
// Before DAO is enabled we show fee as fiat and % in second line
|
||||
String feeInFiatAsString;
|
||||
if (optionalBtcFeeInFiat != null && optionalBtcFeeInFiat.isPresent()) {
|
||||
feeInFiatAsString = btcFormatter.formatVolumeWithCode(optionalBtcFeeInFiat.get());
|
||||
feeInFiatAsString = DisplayUtils.formatVolumeWithCode(optionalBtcFeeInFiat.get());
|
||||
} else {
|
||||
feeInFiatAsString = Res.get("shared.na");
|
||||
}
|
||||
@ -520,7 +522,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
tradeFeeInBsqWithFiat.set(Res.get("createOffer.tradeFee.fiatAndPercent",
|
||||
feeInFiatAsString,
|
||||
btcFormatter.formatToPercentWithSymbol(percent)));
|
||||
BSFormatter.formatToPercentWithSymbol(percent)));
|
||||
}
|
||||
}
|
||||
tradeFeeCurrencyCode.set(dataModel.isCurrencyForMakerFeeBtc() ? Res.getBaseCurrencyCode() : "BSQ");
|
||||
@ -601,7 +603,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
isBuy ? Res.get("shared.buy") : Res.get("shared.sell"));
|
||||
|
||||
securityDepositValidator.setPaymentAccount(dataModel.paymentAccount);
|
||||
buyerSecurityDeposit.set(btcFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||
buyerSecurityDeposit.set(BSFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||
buyerSecurityDepositLabel.set(getSecurityDepositLabel());
|
||||
|
||||
applyMakerFee();
|
||||
@ -761,7 +763,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
if (dataModel.getMinVolume().get() != null) {
|
||||
InputValidator.ValidationResult minVolumeResult = isVolumeInputValid(
|
||||
btcFormatter.formatVolume(dataModel.getMinVolume().get()));
|
||||
DisplayUtils.formatVolume(dataModel.getMinVolume().get()));
|
||||
|
||||
volumeValidationResult.set(minVolumeResult);
|
||||
|
||||
@ -792,7 +794,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
setPriceToModel();
|
||||
ignorePriceStringListener = true;
|
||||
if (dataModel.getPrice().get() != null)
|
||||
price.set(btcFormatter.formatPrice(dataModel.getPrice().get()));
|
||||
price.set(BSFormatter.formatPrice(dataModel.getPrice().get()));
|
||||
ignorePriceStringListener = false;
|
||||
dataModel.calculateVolume();
|
||||
dataModel.calculateAmount();
|
||||
@ -841,7 +843,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
else if (CurrencyUtil.isFiatCurrency(tradeCurrencyCode.get()))
|
||||
volume = OfferUtil.getRoundedFiatVolume(volume);
|
||||
|
||||
this.volume.set(btcFormatter.formatVolume(volume));
|
||||
this.volume.set(DisplayUtils.formatVolume(volume));
|
||||
}
|
||||
|
||||
ignoreVolumeStringListener = false;
|
||||
@ -874,20 +876,20 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
if (result.isValid) {
|
||||
double defaultSecurityDeposit = Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount());
|
||||
String key = "buyerSecurityDepositIsLowerAsDefault";
|
||||
double depositAsDouble = btcFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get());
|
||||
double depositAsDouble = ParsingUtils.parsePercentStringToDouble(buyerSecurityDeposit.get());
|
||||
if (preferences.showAgain(key) && depositAsDouble < defaultSecurityDeposit) {
|
||||
String postfix = dataModel.isBuyOffer() ?
|
||||
Res.get("createOffer.tooLowSecDeposit.makerIsBuyer") :
|
||||
Res.get("createOffer.tooLowSecDeposit.makerIsSeller");
|
||||
new Popup<>()
|
||||
.warning(Res.get("createOffer.tooLowSecDeposit.warning",
|
||||
btcFormatter.formatToPercentWithSymbol(defaultSecurityDeposit)) + "\n\n" + postfix)
|
||||
BSFormatter.formatToPercentWithSymbol(defaultSecurityDeposit)) + "\n\n" + postfix)
|
||||
.width(800)
|
||||
.actionButtonText(Res.get("createOffer.resetToDefault"))
|
||||
.onAction(() -> {
|
||||
dataModel.setBuyerSecurityDeposit(defaultSecurityDeposit);
|
||||
ignoreSecurityDepositStringListener = true;
|
||||
buyerSecurityDeposit.set(btcFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||
buyerSecurityDeposit.set(BSFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||
ignoreSecurityDepositStringListener = false;
|
||||
})
|
||||
.closeButtonText(Res.get("createOffer.useLowerValue"))
|
||||
@ -904,7 +906,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
private void applyBuyerSecurityDepositOnFocusOut() {
|
||||
setBuyerSecurityDepositToModel();
|
||||
ignoreSecurityDepositStringListener = true;
|
||||
buyerSecurityDeposit.set(btcFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||
buyerSecurityDeposit.set(BSFormatter.formatToPercent(dataModel.getBuyerSecurityDeposit().get()));
|
||||
ignoreSecurityDepositStringListener = false;
|
||||
}
|
||||
|
||||
@ -914,7 +916,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
public boolean isPriceInRange() {
|
||||
if (marketPriceMargin.get() != null && !marketPriceMargin.get().isEmpty()) {
|
||||
if (Math.abs(btcFormatter.parsePercentStringToDouble(marketPriceMargin.get())) > preferences.getMaxPriceDistanceInPercent()) {
|
||||
if (Math.abs(ParsingUtils.parsePercentStringToDouble(marketPriceMargin.get())) > preferences.getMaxPriceDistanceInPercent()) {
|
||||
displayPriceOutOfRangePopup();
|
||||
return false;
|
||||
} else {
|
||||
@ -928,7 +930,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
private void displayPriceOutOfRangePopup() {
|
||||
Popup popup = new Popup<>();
|
||||
popup.warning(Res.get("createOffer.priceOutSideOfDeviation",
|
||||
btcFormatter.formatToPercentWithSymbol(preferences.getMaxPriceDistanceInPercent())))
|
||||
BSFormatter.formatToPercentWithSymbol(preferences.getMaxPriceDistanceInPercent())))
|
||||
.actionButtonText(Res.get("createOffer.changePrice"))
|
||||
.onAction(popup::hide)
|
||||
.closeButtonTextWithGoTo("navigation.settings.preferences")
|
||||
@ -1071,7 +1073,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
private void setAmountToModel() {
|
||||
if (amount.get() != null && !amount.get().isEmpty()) {
|
||||
Coin amount = btcFormatter.parseToCoinWith4Decimals(this.amount.get());
|
||||
Coin amount = DisplayUtils.parseToCoinWith4Decimals(this.amount.get(), btcFormatter);
|
||||
|
||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||
Price price = dataModel.getPrice().get();
|
||||
@ -1095,7 +1097,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
private void setMinAmountToModel() {
|
||||
if (minAmount.get() != null && !minAmount.get().isEmpty()) {
|
||||
Coin minAmount = btcFormatter.parseToCoinWith4Decimals(this.minAmount.get());
|
||||
Coin minAmount = DisplayUtils.parseToCoinWith4Decimals(this.minAmount.get(), btcFormatter);
|
||||
|
||||
Price price = dataModel.getPrice().get();
|
||||
long maxTradeLimit = dataModel.getMaxTradeLimit();
|
||||
@ -1138,7 +1140,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
|
||||
private void setBuyerSecurityDepositToModel() {
|
||||
if (buyerSecurityDeposit.get() != null && !buyerSecurityDeposit.get().isEmpty()) {
|
||||
dataModel.setBuyerSecurityDeposit(btcFormatter.parsePercentStringToDouble(buyerSecurityDeposit.get()));
|
||||
dataModel.setBuyerSecurityDeposit(ParsingUtils.parsePercentStringToDouble(buyerSecurityDeposit.get()));
|
||||
} else {
|
||||
dataModel.setBuyerSecurityDeposit(Restrictions.getDefaultBuyerSecurityDepositAsPercent(getPaymentAccount()));
|
||||
}
|
||||
@ -1197,7 +1199,7 @@ public abstract class MutableOfferViewModel<M extends MutableOfferDataModel> ext
|
||||
dataModel.getPrice().get() != null &&
|
||||
dataModel.getPrice().get().getValue() != 0 &&
|
||||
isVolumeInputValid(volume.get()).isValid &&
|
||||
isVolumeInputValid(btcFormatter.formatVolume(dataModel.getMinVolume().get())).isValid &&
|
||||
isVolumeInputValid(DisplayUtils.formatVolume(dataModel.getMinVolume().get())).isValid &&
|
||||
dataModel.isMinAmountLessOrEqualAmount();
|
||||
|
||||
isNextButtonDisabled.set(!inputDataValid);
|
||||
|
@ -37,6 +37,7 @@ import bisq.desktop.main.funds.withdrawal.WithdrawalView;
|
||||
import bisq.desktop.main.offer.OfferView;
|
||||
import bisq.desktop.main.overlays.popups.Popup;
|
||||
import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
|
||||
import bisq.desktop.util.DisplayUtils;
|
||||
import bisq.desktop.util.FormBuilder;
|
||||
import bisq.desktop.util.GUIUtil;
|
||||
import bisq.desktop.util.Layout;
|
||||
@ -226,8 +227,8 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
tableView.setPlaceholder(placeholder);
|
||||
|
||||
marketColumn.setComparator((o1, o2) -> {
|
||||
String str1 = formatter.getCurrencyPair(o1.getOffer().getCurrencyCode());
|
||||
String str2 = formatter.getCurrencyPair(o2.getOffer().getCurrencyCode());
|
||||
String str1 = BSFormatter.getCurrencyPair(o1.getOffer().getCurrencyCode());
|
||||
String str2 = BSFormatter.getCurrencyPair(o2.getOffer().getCurrencyCode());
|
||||
return str1 != null && str2 != null ? str1.compareTo(str2) : 0;
|
||||
});
|
||||
priceColumn.setComparator((o1, o2) -> {
|
||||
@ -324,7 +325,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
tableView.getColumns().add(0, marketColumn);
|
||||
} else {
|
||||
volumeColumn.setTitleWithHelpText(Res.get("offerbook.volume", code), Res.get("shared.amountHelp"));
|
||||
priceColumn.setTitle(formatter.getPriceWithCurrencyCode(code));
|
||||
priceColumn.setTitle(BSFormatter.getPriceWithCurrencyCode(code));
|
||||
priceColumn.getStyleClass().add("first-column");
|
||||
|
||||
tableView.getColumns().remove(marketColumn);
|
||||
@ -573,7 +574,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
final long tradeLimit = model.accountAgeWitnessService.getMyTradeLimit(account.get(), offer.getCurrencyCode());
|
||||
new Popup<>()
|
||||
.warning(Res.get("offerbook.warning.tradeLimitNotMatching",
|
||||
formatter.formatAccountAge(model.accountAgeWitnessService.getMyAccountAge(account.get().getPaymentAccountPayload())),
|
||||
DisplayUtils.formatAccountAge(model.accountAgeWitnessService.getMyAccountAge(account.get().getPaymentAccountPayload())),
|
||||
formatter.formatCoinWithCode(Coin.valueOf(tradeLimit)),
|
||||
formatter.formatCoinWithCode(offer.getMinAmount())))
|
||||
.show();
|
||||
@ -693,7 +694,7 @@ public class OfferBookView extends ActivatableViewAndModel<GridPane, OfferBookVi
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if (item != null && !empty)
|
||||
setText(formatter.getCurrencyPair(item.getOffer().getCurrencyCode()));
|
||||
setText(BSFormatter.getCurrencyPair(item.getOffer().getCurrencyCode()));
|
||||
else
|
||||
setText("");
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user