mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2026-08-10 16:43:14 +00:00
wallet import and export - coldcard and electrum
This commit is contained in:
@@ -210,7 +210,7 @@ public class AppController implements Initializable {
|
||||
Optional<String> walletName = dlg.showAndWait();
|
||||
if(walletName.isPresent()) {
|
||||
File walletFile = Storage.getStorage().getWalletFile(walletName.get());
|
||||
Wallet wallet = new Wallet(PolicyType.SINGLE, ScriptType.P2WPKH);
|
||||
Wallet wallet = new Wallet(walletName.get(), PolicyType.SINGLE, ScriptType.P2WPKH);
|
||||
Tab tab = addWalletTab(walletFile, null, wallet);
|
||||
tabs.getSelectionModel().select(tab);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.gson.Gson;
|
||||
import com.sparrowwallet.drongo.ExtendedPublicKey;
|
||||
import com.sparrowwallet.drongo.KeyDerivation;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.policy.Policy;
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
import com.sparrowwallet.sparrow.storage.Storage;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ColdcardMultisig implements MultisigWalletImport, KeystoreImport, WalletExport {
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Coldcard (Multisig)";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PolicyType getPolicyType() {
|
||||
return PolicyType.MULTI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Keystore getKeystore(ScriptType scriptType, InputStream inputStream) throws ImportException {
|
||||
InputStreamReader reader = new InputStreamReader(inputStream);
|
||||
ColdcardKeystore cck = Storage.getStorage().getGson().fromJson(reader, ColdcardKeystore.class);
|
||||
|
||||
Keystore keystore = new Keystore("Coldcard " + cck.xfp);
|
||||
|
||||
if(scriptType.equals(ScriptType.P2SH)) {
|
||||
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2sh_deriv));
|
||||
keystore.setExtendedPublicKey(ExtendedPublicKey.fromDescriptor(cck.p2sh));
|
||||
} else if(scriptType.equals(ScriptType.P2SH_P2WSH)) {
|
||||
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2wsh_p2sh_deriv));
|
||||
keystore.setExtendedPublicKey(ExtendedPublicKey.fromDescriptor(cck.p2wsh_p2sh));
|
||||
} else if(scriptType.equals(ScriptType.P2WSH)) {
|
||||
keystore.setKeyDerivation(new KeyDerivation(cck.xfp, cck.p2wsh_deriv));
|
||||
keystore.setExtendedPublicKey(ExtendedPublicKey.fromDescriptor(cck.p2wsh));
|
||||
} else {
|
||||
throw new ImportException("Correct derivation not found for script type: " + scriptType);
|
||||
}
|
||||
|
||||
return keystore;
|
||||
}
|
||||
|
||||
public static class ColdcardKeystore {
|
||||
public String p2sh_deriv;
|
||||
public String p2sh;
|
||||
public String p2wsh_p2sh_deriv;
|
||||
public String p2wsh_p2sh;
|
||||
public String p2wsh_deriv;
|
||||
public String p2wsh;
|
||||
public String xfp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKeystoreImportDescription() {
|
||||
return "Import file created by using the Settings > Multisig Wallets > Export XPUB feature on your Coldcard";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wallet importWallet(InputStream inputStream) throws ImportException {
|
||||
Wallet wallet = new Wallet();
|
||||
wallet.setPolicyType(PolicyType.MULTI);
|
||||
|
||||
int threshold = 2;
|
||||
ScriptType scriptType = null;
|
||||
String derivation = null;
|
||||
|
||||
try {
|
||||
List<String> lines = CharStreams.readLines(new InputStreamReader(inputStream));
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] keyValue = line.split(":");
|
||||
if (keyValue.length == 2) {
|
||||
String key = keyValue[0].trim();
|
||||
String value = keyValue[1].trim();
|
||||
|
||||
switch (key) {
|
||||
case "Name":
|
||||
wallet.setName(value.trim());
|
||||
break;
|
||||
case "Policy":
|
||||
threshold = Integer.parseInt(value.split(" ")[0]);
|
||||
break;
|
||||
case "Derivation":
|
||||
case "# derivation":
|
||||
derivation = value;
|
||||
break;
|
||||
case "Format":
|
||||
scriptType = ScriptType.valueOf(value.replace("P2WSH-P2SH", "P2SH_P2WSH"));
|
||||
break;
|
||||
default:
|
||||
if (key.length() == 8 && Utils.isHex(key)) {
|
||||
Keystore keystore = new Keystore("Coldcard " + key);
|
||||
keystore.setKeyDerivation(new KeyDerivation(key, derivation));
|
||||
keystore.setExtendedPublicKey(ExtendedPublicKey.fromDescriptor(value));
|
||||
wallet.getKeystores().add(keystore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Policy policy = Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), threshold);
|
||||
wallet.setDefaultPolicy(policy);
|
||||
wallet.setScriptType(scriptType);
|
||||
|
||||
return wallet;
|
||||
} catch(Exception e) {
|
||||
throw new ImportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWalletImportDescription() {
|
||||
return "Import file created by using the Settings > Multisig Wallets > [Wallet Detail] > Coldcard Export feature on your Coldcard";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException {
|
||||
if(!wallet.isValid()) {
|
||||
throw new ExportException("Cannot export an incomplete wallet");
|
||||
}
|
||||
|
||||
if(!wallet.getPolicyType().equals(PolicyType.MULTI)) {
|
||||
throw new ExportException("Coldcard multisig import requires a multisig wallet");
|
||||
}
|
||||
|
||||
boolean multipleDerivations = false;
|
||||
Set<String> derivationSet = new HashSet<>();
|
||||
for(Keystore keystore : wallet.getKeystores()) {
|
||||
derivationSet.add(keystore.getKeyDerivation().getDerivationPath());
|
||||
}
|
||||
if(derivationSet.size() > 1) {
|
||||
multipleDerivations = true;
|
||||
}
|
||||
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
|
||||
writer.append("# Coldcard Multisig setup file (created by Sparrow)\n");
|
||||
writer.append("#\n");
|
||||
writer.append("Name: ").append(wallet.getName()).append("\n");
|
||||
writer.append("Policy: ").append(Integer.toString(wallet.getDefaultPolicy().getNumSignaturesRequired())).append(" of ").append(Integer.toString(wallet.getKeystores().size())).append("\n");
|
||||
if(!multipleDerivations) {
|
||||
writer.append("Derivation: ").append(wallet.getKeystores().get(0).getKeyDerivation().getDerivationPath()).append("\n");
|
||||
}
|
||||
writer.append("Format: ").append(wallet.getScriptType().toString().replace("P2SH-P2WSH", "P2WSH-P2SH")).append("\n");
|
||||
writer.append("\n");
|
||||
|
||||
for(Keystore keystore : wallet.getKeystores()) {
|
||||
if(multipleDerivations) {
|
||||
writer.append("# derivation: ").append(keystore.getKeyDerivation().getDerivationPath()).append("\n");
|
||||
}
|
||||
writer.append(keystore.getKeyDerivation().getMasterFingerprint().toUpperCase()).append(": ").append(keystore.getExtendedPublicKey().toString()).append("\n");
|
||||
if(multipleDerivations) {
|
||||
writer.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch(Exception e) {
|
||||
throw new ExportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWalletExportDescription() {
|
||||
return "Export file that can be read by your Coldcard using the Settings > Multisig Wallets > Import from SD feature";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.sparrowwallet.drongo.ExtendedPublicKey;
|
||||
import com.sparrowwallet.drongo.KeyDerivation;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.policy.Policy;
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
import static com.sparrowwallet.drongo.protocol.ScriptType.*;
|
||||
|
||||
public class ColdcardSinglesig implements SinglesigWalletImport {
|
||||
public static final List<ScriptType> ALLOWED_SCRIPT_TYPES = List.of(P2PKH, P2SH_P2WPKH, P2WPKH);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Coldcard";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wallet importWallet(InputStream inputStream, ScriptType scriptType) throws ImportException {
|
||||
if(!ALLOWED_SCRIPT_TYPES.contains(scriptType)) {
|
||||
throw new ImportException("Script type of " + scriptType + " is not allowed");
|
||||
}
|
||||
|
||||
Wallet wallet = new Wallet();
|
||||
wallet.setPolicyType(PolicyType.SINGLE);
|
||||
wallet.setScriptType(scriptType);
|
||||
String masterFingerprint = null;
|
||||
|
||||
try {
|
||||
List<String> lines = CharStreams.readLines(new InputStreamReader(inputStream));
|
||||
|
||||
for (String line : lines) {
|
||||
line = line.trim();
|
||||
if (line.isEmpty() || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(line.startsWith("xpub")) {
|
||||
ExtendedPublicKey masterXpub = ExtendedPublicKey.fromDescriptor(line);
|
||||
masterFingerprint = Utils.bytesToHex(masterXpub.getPubKey().getFingerprint()).toUpperCase();
|
||||
wallet.setName("Coldcard " + masterFingerprint);
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] keyValue = line.split("=>");
|
||||
if(keyValue.length == 2) {
|
||||
String key = keyValue[0].trim();
|
||||
String value = keyValue[1].trim();
|
||||
|
||||
if(!key.equals("m") && scriptType.getDefaultDerivation().startsWith(key)) {
|
||||
ExtendedPublicKey extPubKey = ExtendedPublicKey.fromDescriptor(value);
|
||||
Keystore keystore = new Keystore();
|
||||
keystore.setKeyDerivation(new KeyDerivation(masterFingerprint, key));
|
||||
keystore.setExtendedPublicKey(extPubKey);
|
||||
wallet.getKeystores().add(keystore);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), 1));
|
||||
return wallet;
|
||||
} catch(Exception e) {
|
||||
throw new ImportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWalletImportDescription() {
|
||||
return "Import file created by using the Advanced > Dump Summary feature on your Coldcard";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.sparrowwallet.drongo.ExtendedPublicKey;
|
||||
import com.sparrowwallet.drongo.KeyDerivation;
|
||||
import com.sparrowwallet.drongo.Utils;
|
||||
import com.sparrowwallet.drongo.policy.Policy;
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Electrum implements SinglesigWalletImport, MultisigWalletImport, WalletExport {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Electrum";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wallet importWallet(InputStream inputStream) throws ImportException {
|
||||
InputStreamReader reader = new InputStreamReader(inputStream);
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
Type stringStringMap = new TypeToken<Map<String, JsonElement>>(){}.getType();
|
||||
Map<String,JsonElement> map = gson.fromJson(reader, stringStringMap);
|
||||
|
||||
ElectrumJsonWallet ew = new ElectrumJsonWallet();
|
||||
ew.wallet_type = map.get("wallet_type").getAsString();
|
||||
|
||||
for(String key : map.keySet()) {
|
||||
if(key.startsWith("x") || key.equals("keystore")) {
|
||||
ElectrumKeystore ek = gson.fromJson(map.get(key), ElectrumKeystore.class);
|
||||
if(ek.root_fingerprint == null && ek.ckcc_xfp != null) {
|
||||
byte[] le = new byte[4];
|
||||
Utils.uint32ToByteArrayLE(Long.parseLong(ek.ckcc_xfp), le, 0);
|
||||
ek.root_fingerprint = Utils.bytesToHex(le).toUpperCase();
|
||||
}
|
||||
ew.keystores.put(key, ek);
|
||||
}
|
||||
}
|
||||
|
||||
Wallet wallet = new Wallet();
|
||||
ScriptType scriptType = null;
|
||||
|
||||
for(ElectrumKeystore ek : ew.keystores.values()) {
|
||||
Keystore keystore = new Keystore(ek.label);
|
||||
keystore.setKeyDerivation(new KeyDerivation(ek.root_fingerprint, ek.derivation));
|
||||
keystore.setExtendedPublicKey(ExtendedPublicKey.fromDescriptor(ek.xpub));
|
||||
wallet.getKeystores().add(keystore);
|
||||
|
||||
ExtendedPublicKey.XpubHeader xpubHeader = ExtendedPublicKey.XpubHeader.fromXpub(ek.xpub);
|
||||
scriptType = xpubHeader.getDefaultScriptType();
|
||||
}
|
||||
|
||||
wallet.setScriptType(scriptType);
|
||||
|
||||
if(ew.wallet_type.equals("standard")) {
|
||||
wallet.setPolicyType(PolicyType.SINGLE);
|
||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.SINGLE, scriptType, wallet.getKeystores(), 1));
|
||||
} else if(ew.wallet_type.contains("of")) {
|
||||
wallet.setPolicyType(PolicyType.MULTI);
|
||||
String[] mOfn = ew.wallet_type.split("of");
|
||||
int threshold = Integer.parseInt(mOfn[0]);
|
||||
wallet.setDefaultPolicy(Policy.getPolicy(PolicyType.MULTI, scriptType, wallet.getKeystores(), threshold));
|
||||
} else {
|
||||
throw new ImportException("Unknown Electrum wallet type of " + ew.wallet_type);
|
||||
}
|
||||
|
||||
if(!wallet.isValid()) {
|
||||
throw new IllegalStateException("Electrum wallet is in an inconsistent state");
|
||||
}
|
||||
|
||||
return wallet;
|
||||
} catch (Exception e) {
|
||||
throw new ImportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWalletImportDescription() {
|
||||
return "Import an Electrum wallet";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wallet importWallet(InputStream inputStream, ScriptType scriptType) throws ImportException {
|
||||
Wallet wallet = importWallet(inputStream);
|
||||
wallet.setScriptType(scriptType);
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException {
|
||||
try {
|
||||
ElectrumJsonWallet ew = new ElectrumJsonWallet();
|
||||
if(wallet.getPolicyType().equals(PolicyType.SINGLE)) {
|
||||
ew.wallet_type = "standard";
|
||||
} else if(wallet.getPolicyType().equals(PolicyType.MULTI)) {
|
||||
ew.wallet_type = wallet.getDefaultPolicy().getNumSignaturesRequired() + "of" + wallet.getKeystores().size();
|
||||
} else {
|
||||
throw new ExportException("Could not export a wallet with a " + wallet.getPolicyType() + " policy");
|
||||
}
|
||||
|
||||
ExtendedPublicKey.XpubHeader xpubHeader = ExtendedPublicKey.XpubHeader.fromScriptType(wallet.getScriptType());
|
||||
|
||||
int index = 1;
|
||||
for(Keystore keystore : wallet.getKeystores()) {
|
||||
ElectrumKeystore ek = new ElectrumKeystore();
|
||||
ek.xpub = keystore.getExtendedPublicKey().toString(xpubHeader);
|
||||
ek.derivation = keystore.getKeyDerivation().getDerivationPath();
|
||||
ek.root_fingerprint = keystore.getKeyDerivation().getMasterFingerprint();
|
||||
ek.label = keystore.getLabel();
|
||||
|
||||
if(wallet.getPolicyType().equals(PolicyType.SINGLE)) {
|
||||
ew.keystores.put("keystore", ek);
|
||||
} else if(wallet.getPolicyType().equals(PolicyType.MULTI)) {
|
||||
ew.keystores.put("x" + index + "/", ek);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
Gson gson = new Gson();
|
||||
JsonObject eJson = gson.toJsonTree(ew.keystores).getAsJsonObject();
|
||||
eJson.addProperty("wallet_type", ew.wallet_type);
|
||||
|
||||
gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
String json = gson.toJson(eJson);
|
||||
outputStream.write(json.getBytes(StandardCharsets.UTF_8));
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
throw new ExportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWalletExportDescription() {
|
||||
return "Export this wallet as an Electrum wallet file";
|
||||
}
|
||||
|
||||
private static class ElectrumJsonWallet {
|
||||
public Map<String, ElectrumKeystore> keystores = new LinkedHashMap<>();
|
||||
public String wallet_type;
|
||||
}
|
||||
|
||||
public static class ElectrumKeystore {
|
||||
public String xpub;
|
||||
public String hw_type;
|
||||
public String ckcc_xfp;
|
||||
public String root_fingerprint;
|
||||
public String label;
|
||||
public String soft_device_id;
|
||||
public String type;
|
||||
public String derivation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
public interface Export {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
public class ExportException extends Throwable {
|
||||
public ExportException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ExportException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ExportException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ExportException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
public interface Import {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
public class ImportException extends Exception {
|
||||
public ImportException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ImportException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ImportException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ImportException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.sparrowwallet.drongo.policy.PolicyType;
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface KeystoreImport extends Import {
|
||||
PolicyType getPolicyType();
|
||||
Keystore getKeystore(ScriptType scriptType, InputStream inputStream) throws ImportException;
|
||||
String getKeystoreImportDescription();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface MultisigWalletImport extends Import {
|
||||
String getWalletImportDescription();
|
||||
Wallet importWallet(InputStream inputStream) throws ImportException;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.sparrowwallet.drongo.protocol.ScriptType;
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface SinglesigWalletImport extends Import {
|
||||
String getWalletImportDescription();
|
||||
Wallet importWallet(InputStream inputStream, ScriptType scriptType) throws ImportException;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.sparrowwallet.sparrow.external;
|
||||
|
||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface WalletExport extends Export {
|
||||
void exportWallet(Wallet wallet, OutputStream outputStream) throws ExportException;
|
||||
String getWalletExportDescription();
|
||||
}
|
||||
@@ -36,6 +36,10 @@ public class Storage {
|
||||
return SINGLETON;
|
||||
}
|
||||
|
||||
public Gson getGson() {
|
||||
return gson;
|
||||
}
|
||||
|
||||
public Wallet loadWallet(File file) throws IOException {
|
||||
Reader reader = new FileReader(file);
|
||||
Wallet wallet = gson.fromJson(reader, Wallet.class);
|
||||
@@ -44,18 +48,6 @@ public class Storage {
|
||||
return wallet;
|
||||
}
|
||||
|
||||
public static final void main(String[] args) throws Exception {
|
||||
File file = new File("/Users/scy/.electrum-latest/wallets/scyone");
|
||||
ECKey pubKey = ECKey.createKeyPbkdf2HmacSha512("***REMOVED***");
|
||||
|
||||
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
byte[] encrypted = ByteStreams.toByteArray(inputStream);
|
||||
byte[] decrypted = pubKey.decryptEcies(encrypted, getEncryptionMagic());
|
||||
String jsonWallet = inflate(decrypted);
|
||||
|
||||
System.out.println(jsonWallet);
|
||||
}
|
||||
|
||||
public Wallet loadWallet(File file, ECKey encryptionKey) throws IOException {
|
||||
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
byte[] encrypted = ByteStreams.toByteArray(inputStream);
|
||||
|
||||
Reference in New Issue
Block a user