Merge branch 'release/0.2.0' into develop
This commit is contained in:
commit
bef9ea716e
59
README.md
59
README.md
@ -1,7 +1,7 @@
|
|||||||
Jabit [![Build Status](https://travis-ci.org/Dissem/Jabit.svg?branch=master)](https://travis-ci.org/Dissem/Jabit)
|
Jabit [![Build Status](https://travis-ci.org/Dissem/Jabit.svg?branch=master)](https://travis-ci.org/Dissem/Jabit)
|
||||||
=====
|
=====
|
||||||
|
|
||||||
A Java implementation for the Bitmessage protocol. To build, use command `gradle build`. Note that for some tests to run, a standard Bitmessage client needs to run on the same system, using port 8444 (the default port).
|
A Java implementation for the Bitmessage protocol. To build, use command `gradle build` or `./gradlew build`.
|
||||||
|
|
||||||
Please note that development is still heavily in progress, and I will break the database a lot until it's ready for prime time.
|
Please note that development is still heavily in progress, and I will break the database a lot until it's ready for prime time.
|
||||||
|
|
||||||
@ -12,6 +12,7 @@ There are most probably some security issues, me programming this thing all by m
|
|||||||
|
|
||||||
Project Status
|
Project Status
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Basically, everything needed for a working Bitmessage client is there:
|
Basically, everything needed for a working Bitmessage client is there:
|
||||||
* Creating new identities (private addresses)
|
* Creating new identities (private addresses)
|
||||||
* Adding contracts and subscriptions
|
* Adding contracts and subscriptions
|
||||||
@ -22,3 +23,59 @@ Basically, everything needed for a working Bitmessage client is there:
|
|||||||
* Initialise and manage a registry of Bitmessage network nodes
|
* Initialise and manage a registry of Bitmessage network nodes
|
||||||
* An easy to use API
|
* An easy to use API
|
||||||
* A command line demo application built using the API
|
* A command line demo application built using the API
|
||||||
|
|
||||||
|
Setup
|
||||||
|
-----
|
||||||
|
|
||||||
|
Add Jabit as Gradle dependency:
|
||||||
|
```Gradle
|
||||||
|
compile 'ch.dissem.jabit:jabit-domain:0.2.0'
|
||||||
|
```
|
||||||
|
Unless you want to implement your own, also add the following:
|
||||||
|
```Gradle
|
||||||
|
compile 'ch.dissem.jabit:jabit-networking:0.2.0'
|
||||||
|
compile 'ch.dissem.jabit:jabit-repositories:0.2.0'
|
||||||
|
```
|
||||||
|
And if you want to import from or export to the Wallet Import Format (used by PyBitmessage) you might also want to add:
|
||||||
|
```Gradle
|
||||||
|
compile 'ch.dissem.jabit:jabit-wif:0.2.0'
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
First, you'll need to create a `BitmessageContext`:
|
||||||
|
```Java
|
||||||
|
JdbcConfig jdbcConfig = new JdbcConfig();
|
||||||
|
BitmessageContext ctx = new BitmessageContext.Builder()
|
||||||
|
.addressRepo(new JdbcAddressRepository(jdbcConfig))
|
||||||
|
.inventory(new JdbcInventory(jdbcConfig))
|
||||||
|
.messageRepo(new JdbcMessageRepository(jdbcConfig))
|
||||||
|
.nodeRegistry(new MemoryNodeRegistry())
|
||||||
|
.networkHandler(new NetworkNode())
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
This creates a simple context using a H2 database that will be created in the user's home directory. Next you'll need to
|
||||||
|
start the context and decide what happens if a message arrives:
|
||||||
|
```Java
|
||||||
|
ctx.startup(new BitmessageContext.Listener() {
|
||||||
|
@Override
|
||||||
|
public void receive(Plaintext plaintext) {
|
||||||
|
// TODO: Notify the user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
Then you might want to create an identity
|
||||||
|
```Java
|
||||||
|
BitmessageAddress identity = ctx.createIdentity(false, Pubkey.Feature.DOES_ACK);
|
||||||
|
```
|
||||||
|
or add some contacts
|
||||||
|
```Java
|
||||||
|
BitmessageAddress contact = new BitmessageAddress("BM-2cTarrmjMdRicKZ4qQ8A13JhoR3Uq6Zh5j");
|
||||||
|
address.setAlias("Chris");
|
||||||
|
ctx.addContact(contact);
|
||||||
|
```
|
||||||
|
to which you can send some messages
|
||||||
|
```Java
|
||||||
|
ctx.send(identity, contact, "Test", "Hello Chris, this is a message.");
|
||||||
|
```
|
||||||
|
79
build.gradle
79
build.gradle
@ -5,7 +5,9 @@ subprojects {
|
|||||||
|
|
||||||
sourceCompatibility = 1.7
|
sourceCompatibility = 1.7
|
||||||
group = 'ch.dissem.jabit'
|
group = 'ch.dissem.jabit'
|
||||||
version = '0.1.3-SNAPSHOT'
|
version = '0.2.0'
|
||||||
|
|
||||||
|
ext.isReleaseVersion = !version.endsWith("SNAPSHOT")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -25,50 +27,51 @@ subprojects {
|
|||||||
archives javadocJar, sourcesJar
|
archives javadocJar, sourcesJar
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: to build the project, you'll either need to
|
signing {
|
||||||
if (hasProperty('signing.keyId')) {
|
required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") }
|
||||||
signing {
|
sign configurations.archives
|
||||||
sign configurations.archives
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasProperty('ossrhUsername')) {
|
uploadArchives {
|
||||||
uploadArchives {
|
repositories {
|
||||||
repositories {
|
mavenDeployer {
|
||||||
mavenDeployer {
|
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
||||||
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
|
||||||
|
|
||||||
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
|
if (!hasProperty('ossrhUsername')) {
|
||||||
authentication(userName: ossrhUsername, password: ossrhPassword)
|
ext.ossrhUsername = 'dummy'
|
||||||
|
ext.ossrhPassword = 'dummy'
|
||||||
|
}
|
||||||
|
|
||||||
|
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
|
||||||
|
authentication(userName: ossrhUsername, password: ossrhPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
|
||||||
|
authentication(userName: ossrhUsername, password: ossrhPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
pom.project {
|
||||||
|
name 'Jabit'
|
||||||
|
packaging 'jar'
|
||||||
|
url 'https://github.com/Dissem/Jabit'
|
||||||
|
|
||||||
|
scm {
|
||||||
|
connection 'scm:git:https://github.com/Dissem/Jabit.git'
|
||||||
|
developerConnection 'scm:git:git@github.com:Dissem/Jabit.git'
|
||||||
|
url 'https://github.com/Dissem/Jabit.git'
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
|
licenses {
|
||||||
authentication(userName: ossrhUsername, password: ossrhPassword)
|
license {
|
||||||
|
name 'The Apache License, Version 2.0'
|
||||||
|
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pom.project {
|
developers {
|
||||||
name 'Jabit'
|
developer {
|
||||||
packaging 'jar'
|
name 'Christian Basler'
|
||||||
url 'https://github.com/Dissem/Jabit'
|
email 'chrigu.meyer@gmail.com'
|
||||||
|
|
||||||
scm {
|
|
||||||
connection 'scm:git:https://github.com/Dissem/Jabit.git'
|
|
||||||
developerConnection 'scm:git:git@github.com:Dissem/Jabit.git'
|
|
||||||
url 'https://github.com/Dissem/Jabit.git'
|
|
||||||
}
|
|
||||||
|
|
||||||
licenses {
|
|
||||||
license {
|
|
||||||
name 'The Apache License, Version 2.0'
|
|
||||||
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
developers {
|
|
||||||
developer {
|
|
||||||
name 'Christian Basler'
|
|
||||||
email 'chrigu.meyer@gmail.com'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ dependencies {
|
|||||||
compile project(':domain')
|
compile project(':domain')
|
||||||
compile project(':networking')
|
compile project(':networking')
|
||||||
compile project(':repositories')
|
compile project(':repositories')
|
||||||
|
compile project(':wif')
|
||||||
compile 'org.slf4j:slf4j-simple:1.7.12'
|
compile 'org.slf4j:slf4j-simple:1.7.12'
|
||||||
compile 'args4j:args4j:2.32'
|
compile 'args4j:args4j:2.32'
|
||||||
testCompile 'junit:junit:4.11'
|
testCompile 'junit:junit:4.11'
|
||||||
|
@ -16,6 +16,16 @@
|
|||||||
|
|
||||||
package ch.dissem.bitmessage.demo;
|
package ch.dissem.bitmessage.demo;
|
||||||
|
|
||||||
|
import ch.dissem.bitmessage.BitmessageContext;
|
||||||
|
import ch.dissem.bitmessage.networking.NetworkNode;
|
||||||
|
import ch.dissem.bitmessage.repository.*;
|
||||||
|
import ch.dissem.bitmessage.wif.WifExporter;
|
||||||
|
import ch.dissem.bitmessage.wif.WifImporter;
|
||||||
|
import org.kohsuke.args4j.CmdLineException;
|
||||||
|
import org.kohsuke.args4j.CmdLineParser;
|
||||||
|
import org.kohsuke.args4j.Option;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@ -25,6 +35,40 @@ public class Main {
|
|||||||
if (System.getProperty("org.slf4j.simpleLogger.logFile") == null)
|
if (System.getProperty("org.slf4j.simpleLogger.logFile") == null)
|
||||||
System.setProperty("org.slf4j.simpleLogger.logFile", "./jabit.log");
|
System.setProperty("org.slf4j.simpleLogger.logFile", "./jabit.log");
|
||||||
|
|
||||||
new Application();
|
CmdLineOptions options = new CmdLineOptions();
|
||||||
|
CmdLineParser parser = new CmdLineParser(options);
|
||||||
|
try {
|
||||||
|
parser.parseArgument(args);
|
||||||
|
} catch (CmdLineException e) {
|
||||||
|
parser.printUsage(System.err);
|
||||||
|
}
|
||||||
|
if (options.exportWIF != null || options.importWIF != null) {
|
||||||
|
JdbcConfig jdbcConfig = new JdbcConfig();
|
||||||
|
BitmessageContext ctx = new BitmessageContext.Builder()
|
||||||
|
.addressRepo(new JdbcAddressRepository(jdbcConfig))
|
||||||
|
.inventory(new JdbcInventory(jdbcConfig))
|
||||||
|
.nodeRegistry(new MemoryNodeRegistry())
|
||||||
|
.messageRepo(new JdbcMessageRepository(jdbcConfig))
|
||||||
|
.networkHandler(new NetworkNode())
|
||||||
|
.port(48444)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if (options.exportWIF != null) {
|
||||||
|
new WifExporter(ctx).addAll().write(options.exportWIF);
|
||||||
|
}
|
||||||
|
if (options.importWIF != null) {
|
||||||
|
new WifImporter(ctx, options.importWIF).importAll();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
new Application();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CmdLineOptions {
|
||||||
|
@Option(name = "-import", usage = "Import from keys.dat or other WIF file.")
|
||||||
|
private File importWIF;
|
||||||
|
|
||||||
|
@Option(name = "-export", usage = "Export to WIF file.")
|
||||||
|
private File exportWIF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package ch.dissem.bitmessage.entity.payload;
|
package ch.dissem.bitmessage.entity.payload;
|
||||||
|
|
||||||
import ch.dissem.bitmessage.entity.Streamable;
|
import ch.dissem.bitmessage.entity.Streamable;
|
||||||
|
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
|
||||||
import ch.dissem.bitmessage.exception.DecryptionFailedException;
|
import ch.dissem.bitmessage.exception.DecryptionFailedException;
|
||||||
import ch.dissem.bitmessage.utils.*;
|
import ch.dissem.bitmessage.utils.*;
|
||||||
import org.bouncycastle.crypto.BufferedBlockCipher;
|
import org.bouncycastle.crypto.BufferedBlockCipher;
|
||||||
@ -37,6 +38,8 @@ import java.io.*;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static ch.dissem.bitmessage.entity.valueobject.PrivateKey.PRIVATE_KEY_SIZE;
|
||||||
|
|
||||||
|
|
||||||
public class CryptoBox implements Streamable {
|
public class CryptoBox implements Streamable {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(CryptoBox.class);
|
private static final Logger LOG = LoggerFactory.getLogger(CryptoBox.class);
|
||||||
@ -59,7 +62,7 @@ public class CryptoBox implements Streamable {
|
|||||||
initializationVector = Security.randomBytes(16);
|
initializationVector = Security.randomBytes(16);
|
||||||
|
|
||||||
// 3. Generate a new random EC key pair with private key called r and public key called R.
|
// 3. Generate a new random EC key pair with private key called r and public key called R.
|
||||||
byte[] r = Security.randomBytes(64);
|
byte[] r = Security.randomBytes(PRIVATE_KEY_SIZE);
|
||||||
R = Security.createPublicKey(r);
|
R = Security.createPublicKey(r);
|
||||||
// 4. Do an EC point multiply with public key K and private key r. This gives you public key P.
|
// 4. Do an EC point multiply with public key K and private key r. This gives you public key P.
|
||||||
ECPoint P = K.multiply(Security.keyToBigInt(r)).normalize();
|
ECPoint P = K.multiply(Security.keyToBigInt(r)).normalize();
|
||||||
|
@ -32,8 +32,9 @@ import java.io.*;
|
|||||||
* Created by chris on 18.04.15.
|
* Created by chris on 18.04.15.
|
||||||
*/
|
*/
|
||||||
public class PrivateKey implements Streamable {
|
public class PrivateKey implements Streamable {
|
||||||
private final byte[] privateSigningKey; // 32 bytes
|
public static final int PRIVATE_KEY_SIZE = 32;
|
||||||
private final byte[] privateEncryptionKey; // 32 bytes
|
private final byte[] privateSigningKey;
|
||||||
|
private final byte[] privateEncryptionKey;
|
||||||
|
|
||||||
private final Pubkey pubkey;
|
private final Pubkey pubkey;
|
||||||
|
|
||||||
@ -44,8 +45,8 @@ public class PrivateKey implements Streamable {
|
|||||||
byte[] pubEK;
|
byte[] pubEK;
|
||||||
byte[] ripe;
|
byte[] ripe;
|
||||||
do {
|
do {
|
||||||
privSK = Security.randomBytes(64);
|
privSK = Security.randomBytes(PRIVATE_KEY_SIZE);
|
||||||
privEK = Security.randomBytes(64);
|
privEK = Security.randomBytes(PRIVATE_KEY_SIZE);
|
||||||
pubSK = Security.createPublicKey(privSK).getEncoded(false);
|
pubSK = Security.createPublicKey(privSK).getEncoded(false);
|
||||||
pubEK = Security.createPublicKey(privEK).getEncoded(false);
|
pubEK = Security.createPublicKey(privEK).getEncoded(false);
|
||||||
ripe = Pubkey.getRipe(pubSK, pubEK);
|
ripe = Pubkey.getRipe(pubSK, pubEK);
|
||||||
|
@ -131,7 +131,7 @@ public class JdbcInventory extends JdbcHelper implements Inventory {
|
|||||||
ps.setLong(6, object.getVersion());
|
ps.setLong(6, object.getVersion());
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
LOG.error("Error storing object of type " + object.getPayload().getClass().getSimpleName(), e);
|
LOG.debug("Error storing object of type " + object.getPayload().getClass().getSimpleName(), e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error(e.getMessage(), e);
|
LOG.error(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
CREATE TABLE Node (
|
|
||||||
ip BINARY(16) NOT NULL,
|
|
||||||
port INT NOT NULL,
|
|
||||||
stream BIGINT NOT NULL,
|
|
||||||
services BIGINT NOT NULL,
|
|
||||||
time BIGINT NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (ip, port, stream)
|
|
||||||
);
|
|
@ -34,7 +34,7 @@ CREATE TABLE Message_Label (
|
|||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO Label(label, type, color, ord) VALUES ('Inbox', 'INBOX', X'FF0000FF', 0);
|
INSERT INTO Label(label, type, color, ord) VALUES ('Inbox', 'INBOX', X'FF0000FF', 0);
|
||||||
INSERT INTO Label(label, type, color, ord) VALUES ('Drafts', 'DRAFTS', X'FFFF9900', 10);
|
INSERT INTO Label(label, type, color, ord) VALUES ('Drafts', 'DRAFT', X'FFFF9900', 10);
|
||||||
INSERT INTO Label(label, type, color, ord) VALUES ('Sent', 'SENT', X'FFFFFF00', 20);
|
INSERT INTO Label(label, type, color, ord) VALUES ('Sent', 'SENT', X'FFFFFF00', 20);
|
||||||
INSERT INTO Label(label, type, ord) VALUES ('Unread', 'UNREAD', 90);
|
INSERT INTO Label(label, type, ord) VALUES ('Unread', 'UNREAD', 90);
|
||||||
INSERT INTO Label(label, type, ord) VALUES ('Trash', 'TRASH', 100);
|
INSERT INTO Label(label, type, ord) VALUES ('Trash', 'TRASH', 100);
|
@ -1 +0,0 @@
|
|||||||
UPDATE Label SET type = 'DRAFT' WHERE type = 'DRAFTS';
|
|
@ -1 +0,0 @@
|
|||||||
DROP TABLE Node;
|
|
@ -26,6 +26,8 @@ import org.ini4j.Profile;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import static ch.dissem.bitmessage.entity.valueobject.PrivateKey.PRIVATE_KEY_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christian Basler
|
* @author Christian Basler
|
||||||
*/
|
*/
|
||||||
@ -38,19 +40,21 @@ public class WifExporter {
|
|||||||
this.ini = new Ini();
|
this.ini = new Ini();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAll() {
|
public WifExporter addAll() {
|
||||||
for (BitmessageAddress identity : ctx.addresses().getIdentities()) {
|
for (BitmessageAddress identity : ctx.addresses().getIdentities()) {
|
||||||
addIdentity(identity);
|
addIdentity(identity);
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAll(Collection<BitmessageAddress> identities) {
|
public WifExporter addAll(Collection<BitmessageAddress> identities) {
|
||||||
for (BitmessageAddress identity : identities) {
|
for (BitmessageAddress identity : identities) {
|
||||||
addIdentity(identity);
|
addIdentity(identity);
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addIdentity(BitmessageAddress identity) {
|
public WifExporter addIdentity(BitmessageAddress identity) {
|
||||||
Profile.Section section = ini.add(identity.getAddress());
|
Profile.Section section = ini.add(identity.getAddress());
|
||||||
section.add("label", identity.getAlias());
|
section.add("label", identity.getAlias());
|
||||||
section.add("enabled", true);
|
section.add("enabled", true);
|
||||||
@ -59,22 +63,26 @@ public class WifExporter {
|
|||||||
section.add("payloadlengthextrabytes", identity.getPubkey().getExtraBytes());
|
section.add("payloadlengthextrabytes", identity.getPubkey().getExtraBytes());
|
||||||
section.add("privsigningkey", exportSecret(identity.getPrivateKey().getPrivateSigningKey()));
|
section.add("privsigningkey", exportSecret(identity.getPrivateKey().getPrivateSigningKey()));
|
||||||
section.add("privencryptionkey", exportSecret(identity.getPrivateKey().getPrivateEncryptionKey()));
|
section.add("privencryptionkey", exportSecret(identity.getPrivateKey().getPrivateEncryptionKey()));
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String exportSecret(byte[] privateKey) {
|
private String exportSecret(byte[] privateKey) {
|
||||||
if (privateKey.length != 32) {
|
if (privateKey.length != PRIVATE_KEY_SIZE) {
|
||||||
throw new IllegalArgumentException("Private key of length 32 expected, but was " + privateKey.length);
|
throw new IllegalArgumentException("Private key of length 32 expected, but was " + privateKey.length);
|
||||||
}
|
}
|
||||||
byte[] result = new byte[37];
|
byte[] result = new byte[37];
|
||||||
result[0] = (byte) 0x80;
|
result[0] = (byte) 0x80;
|
||||||
System.arraycopy(privateKey, 0, result, 1, 32);
|
System.arraycopy(privateKey, 0, result, 1, PRIVATE_KEY_SIZE);
|
||||||
byte[] hash = Security.doubleSha256(result, 33);
|
byte[] hash = Security.doubleSha256(result, PRIVATE_KEY_SIZE + 1);
|
||||||
System.arraycopy(hash, 0, result, 33, 4);
|
System.arraycopy(hash, 0, result, PRIVATE_KEY_SIZE + 1, 4);
|
||||||
return Base58.encode(result);
|
return Base58.encode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(File file) throws IOException {
|
public void write(File file) throws IOException {
|
||||||
write(new FileOutputStream(file));
|
file.createNewFile();
|
||||||
|
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||||
|
write(out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(OutputStream out) throws IOException {
|
public void write(OutputStream out) throws IOException {
|
||||||
|
@ -95,19 +95,22 @@ public class WifImporter {
|
|||||||
return identities;
|
return identities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importAll() {
|
public WifImporter importAll() {
|
||||||
for (BitmessageAddress identity : identities) {
|
for (BitmessageAddress identity : identities) {
|
||||||
ctx.addresses().save(identity);
|
ctx.addresses().save(identity);
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importAll(Collection<BitmessageAddress> identities) {
|
public WifImporter importAll(Collection<BitmessageAddress> identities) {
|
||||||
for (BitmessageAddress identity : identities) {
|
for (BitmessageAddress identity : identities) {
|
||||||
ctx.addresses().save(identity);
|
ctx.addresses().save(identity);
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importIdentity(BitmessageAddress identity) {
|
public WifImporter importIdentity(BitmessageAddress identity) {
|
||||||
ctx.addresses().save(identity);
|
ctx.addresses().save(identity);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,8 @@ public class WifImporterTest {
|
|||||||
assertEquals(320, identity.getPubkey().getNonceTrialsPerByte());
|
assertEquals(320, identity.getPubkey().getNonceTrialsPerByte());
|
||||||
assertEquals(14000, identity.getPubkey().getExtraBytes());
|
assertEquals(14000, identity.getPubkey().getExtraBytes());
|
||||||
assertNotNull("Private key", identity.getPrivateKey());
|
assertNotNull("Private key", identity.getPrivateKey());
|
||||||
|
assertEquals(32, identity.getPrivateKey().getPrivateEncryptionKey().length);
|
||||||
|
assertEquals(32, identity.getPrivateKey().getPrivateSigningKey().length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user