package co.gem.round; import co.gem.round.coinop.MultiWallet; import co.gem.round.coinop.util.Network; import co.gem.round.crypto.EncryptedMessage; import co.gem.round.crypto.PassphraseBox; import co.gem.round.patchboard.Client; import co.gem.round.patchboard.Resource; import com.google.gson.JsonObject; import org.spongycastle.crypto.InvalidCipherTextException; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; /** * WalletCollection provides access to a users collection of wallets as well as the create method to add additional * wallets to a user. * @author Julian Vergel de Dios (julian@gem.co) on 12/18/14. */ public class WalletCollection extends BaseCollection<Wallet> { private Application app; public WalletCollection(Resource resource, Round round, Application app) { super(resource, round); this.app = app; } public WalletCollection(Resource resource, Round round) { super(resource, round); } /** * Creates an additional wallet on the authenticated user. * @param name of the wallet * @param passphrase to encrypt the primary seed * @return Wallet.Wrapper were you can get the user object to initiate begin/complete device authentication. This is * depricated and will be replaced with returning only a Wallet object. * @throws Client.UnexpectedStatusCodeException * @throws IOException * @throws InvalidKeySpecException * @throws NoSuchAlgorithmException */ public Wallet.Wrapper create(String name, String passphrase) throws IOException, Client.UnexpectedStatusCodeException, InvalidKeySpecException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidAlgorithmParameterException, BadPaddingException, NoSuchPaddingException, InvalidKeyException, NoSuchProviderException, InvalidCipherTextException { MultiWallet multiWallet = MultiWallet.generate(Network.blockchainNetwork("bitcoin")); String primaryPrivateSeed = multiWallet.serializedPrimaryPrivateSeed(); EncryptedMessage encryptedPrivateSeed = PassphraseBox.encrypt(passphrase, primaryPrivateSeed); JsonObject wallet = new JsonObject(); wallet.addProperty("name", name); wallet.addProperty("backup_public_seed", multiWallet.serializedBackupPublicKey()); wallet.addProperty("primary_public_seed", multiWallet.serializedPrimaryPublicKey()); wallet.add("primary_private_seed", encryptedPrivateSeed.asJsonObject()); Resource resource = this.resource.action("create", wallet); Wallet gemWallet = new Wallet(resource, round, app); Wallet.Wrapper wrapper = new Wallet.Wrapper(gemWallet, multiWallet.serializedBackupPrivateSeed()); multiWallet.purgeSeeds(); return wrapper; } @Override public void populateCollection(Iterable<Resource> collection) { for (Resource resource : collection) { Wallet wallet = new Wallet(resource, round, app); add(wallet.getString("name"), wallet); } } }