Code Duplication    Length = 105-108 lines in 2 locations

lib/api_client.js 2 locations

@@ 1140-1247 (lines=108) @@
1137
1138
    // avoid modifying passed options
1139
    options = _.merge({}, options);
1140
1141
    var network = self.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
1142
1143
    determineDataStorageV2_3(options)
1144
        .then(function(options) {
1145
            options.passphrase = options.passphrase || options.password;
1146
            delete options.password;
1147
1148
            // avoid deprecated options
1149
            if (options.primaryPrivateKey) {
1150
                throw new blocktrail.WalletInitError("Can't specify; Primary PrivateKey");
1151
            }
1152
1153
            // seed should be provided or generated
1154
            options.primarySeed = options.primarySeed || randomBytes(Wallet.WALLET_ENTROPY_BITS / 8);
1155
1156
            return options;
1157
        })
1158
        .then(function(options) {
1159
            return produceEncryptedDataV2(options, deferred.notify.bind(deferred));
1160
        })
1161
        .then(function(options) {
1162
            return doRemainingWalletDataV2_3(options, network, deferred.notify.bind(deferred));
1163
        })
1164
        .then(function(options) {
1165
            // create a checksum of our private key which we'll later use to verify we used the right password
1166
            var checksum = options.primaryPrivateKey.getAddress();
1167
            var keyIndex = options.keyIndex;
1168
1169
            // send the public keys and encrypted data to server
1170
            return self.storeNewWalletV2(
1171
                options.identifier,
1172
                [options.primaryPublicKey.toBase58(), "M/" + keyIndex + "'"],
1173
                [options.backupPublicKey.toBase58(), "M"],
1174
                options.storeDataOnServer ? options.encryptedPrimarySeed : false,
1175
                options.storeDataOnServer ? options.encryptedSecret : false,
1176
                options.storeDataOnServer ? options.recoverySecret : false,
1177
                checksum,
1178
                keyIndex,
1179
                options.support_secret || null
1180
            )
1181
                .then(
1182
                function(result) {
1183
                    deferred.notify(APIClient.CREATE_WALLET_PROGRESS_INIT);
1184
1185
                    var blocktrailPublicKeys = _.mapValues(result.blocktrail_public_keys, function(blocktrailPublicKey) {
1186
                        return bitcoin.HDNode.fromBase58(blocktrailPublicKey[0], self.network);
1187
                    });
1188
1189
                    var wallet = new Wallet(
1190
                        self,
1191
                        options.identifier,
1192
                        Wallet.WALLET_VERSION_V2,
1193
                        null,
1194
                        options.storeDataOnServer ? options.encryptedPrimarySeed : null,
1195
                        options.storeDataOnServer ? options.encryptedSecret : null,
1196
                        {keyIndex: options.primaryPublicKey},
1197
                        options.backupPublicKey,
1198
                        blocktrailPublicKeys,
1199
                        keyIndex,
1200
                        result.chain || 0,
1201
                        result.segwit || 0,
1202
                        self.testnet,
1203
                        checksum,
1204
                        result.upgrade_key_index,
1205
                        options.bypassNewAddressCheck
1206
                    );
1207
1208
                    // pass along decrypted data to avoid extra work
1209
                    return wallet.unlock({
1210
                        walletVersion: Wallet.WALLET_VERSION_V2,
1211
                        passphrase: options.passphrase,
1212
                        primarySeed: options.primarySeed,
1213
                        secret: options.secret
1214
                    }).then(function() {
1215
                        deferred.notify(APIClient.CREATE_WALLET_PROGRESS_DONE);
1216
                        return [
1217
                            wallet,
1218
                            {
1219
                                walletVersion: wallet.walletVersion,
1220
                                encryptedPrimarySeed: options.encryptedPrimarySeed ?
1221
                                    bip39.entropyToMnemonic(blocktrail.convert(options.encryptedPrimarySeed, 'base64', 'hex')) :
1222
                                    null,
1223
                                backupSeed: options.backupSeed ? bip39.entropyToMnemonic(options.backupSeed.toString('hex')) : null,
1224
                                recoveryEncryptedSecret: options.recoveryEncryptedSecret ?
1225
                                    bip39.entropyToMnemonic(blocktrail.convert(options.recoveryEncryptedSecret, 'base64', 'hex')) :
1226
                                    null,
1227
                                encryptedSecret: options.encryptedSecret ?
1228
                                    bip39.entropyToMnemonic(blocktrail.convert(options.encryptedSecret, 'base64', 'hex')) :
1229
                                    null,
1230
                                blocktrailPublicKeys: blocktrailPublicKeys
1231
                            }
1232
                        ];
1233
                    });
1234
                }
1235
            );
1236
        })
1237
       .then(function(r) { deferred.resolve(r); }, function(e) { deferred.reject(e); });
1238
1239
    return deferred.promise;
1240
};
1241
1242
APIClient.prototype._createNewWalletV3 = function(options) {
1243
    var self = this;
1244
1245
    var deferred = q.defer();
1246
1247
    // avoid modifying passed options
1248
    options = _.merge({}, options);
1249
1250
    var network = self.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
@@ 1249-1353 (lines=105) @@
1246
1247
    // avoid modifying passed options
1248
    options = _.merge({}, options);
1249
1250
    var network = self.testnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
1251
1252
    determineDataStorageV2_3(options)
1253
        .then(function(options) {
1254
            options.passphrase = options.passphrase || options.password;
1255
            delete options.password;
1256
1257
            // avoid deprecated options
1258
            if (options.primaryPrivateKey) {
1259
                throw new blocktrail.WalletInitError("Can't specify; Primary PrivateKey");
1260
            }
1261
1262
            // seed should be provided or generated
1263
            options.primarySeed = options.primarySeed || randomBytes(Wallet.WALLET_ENTROPY_BITS / 8);
1264
1265
            return options;
1266
        })
1267
        .then(function(options) {
1268
            return self.produceEncryptedDataV3(options, deferred.notify.bind(deferred));
1269
        })
1270
        .then(function(options) {
1271
            return doRemainingWalletDataV2_3(options, network, deferred.notify.bind(deferred));
1272
        })
1273
        .then(function(options) {
1274
1275
            // create a checksum of our private key which we'll later use to verify we used the right password
1276
            var checksum = options.primaryPrivateKey.getAddress();
1277
            var keyIndex = options.keyIndex;
1278
1279
            // send the public keys and encrypted data to server
1280
            return self.storeNewWalletV3(
1281
                options.identifier,
1282
                [options.primaryPublicKey.toBase58(), "M/" + keyIndex + "'"],
1283
                [options.backupPublicKey.toBase58(), "M"],
1284
                options.storeDataOnServer ? options.encryptedPrimarySeed : false,
1285
                options.storeDataOnServer ? options.encryptedSecret : false,
1286
                options.storeDataOnServer ? options.recoverySecret : false,
1287
                checksum,
1288
                keyIndex,
1289
                options.support_secret || null
1290
            )
1291
                .then(
1292
                    // result, deferred, self(apiclient)
1293
                    function(result) {
1294
                        deferred.notify(APIClient.CREATE_WALLET_PROGRESS_INIT);
1295
1296
                        var blocktrailPublicKeys = _.mapValues(result.blocktrail_public_keys, function(blocktrailPublicKey) {
1297
                            return bitcoin.HDNode.fromBase58(blocktrailPublicKey[0], self.network);
1298
                        });
1299
1300
                        var wallet = new Wallet(
1301
                            self,
1302
                            options.identifier,
1303
                            Wallet.WALLET_VERSION_V3,
1304
                            null,
1305
                            options.storeDataOnServer ? options.encryptedPrimarySeed : null,
1306
                            options.storeDataOnServer ? options.encryptedSecret : null,
1307
                            {keyIndex: options.primaryPublicKey},
1308
                            options.backupPublicKey,
1309
                            blocktrailPublicKeys,
1310
                            keyIndex,
1311
                            result.chain || 0,
1312
                            result.segwit || 0,
1313
                            self.testnet,
1314
                            checksum,
1315
                            result.upgrade_key_index,
1316
                            options.bypassNewAddressCheck
1317
                        );
1318
1319
                        // pass along decrypted data to avoid extra work
1320
                        return wallet.unlock({
1321
                            walletVersion: Wallet.WALLET_VERSION_V3,
1322
                            passphrase: options.passphrase,
1323
                            primarySeed: options.primarySeed,
1324
                            secret: options.secret
1325
                        }).then(function() {
1326
                            deferred.notify(APIClient.CREATE_WALLET_PROGRESS_DONE);
1327
                            return [
1328
                                wallet,
1329
                                {
1330
                                    walletVersion: wallet.walletVersion,
1331
                                    encryptedPrimarySeed: options.encryptedPrimarySeed ? EncryptionMnemonic.encode(options.encryptedPrimarySeed) : null,
1332
                                    backupSeed: options.backupSeed ? bip39.entropyToMnemonic(options.backupSeed) : null,
1333
                                    recoveryEncryptedSecret: options.recoveryEncryptedSecret ?
1334
                                        EncryptionMnemonic.encode(options.recoveryEncryptedSecret) : null,
1335
                                    encryptedSecret: options.encryptedSecret ? EncryptionMnemonic.encode(options.encryptedSecret) : null,
1336
                                    blocktrailPublicKeys: blocktrailPublicKeys
1337
                                }
1338
                            ];
1339
                        });
1340
                    }
1341
                );
1342
        })
1343
        .then(function(r) { deferred.resolve(r); }, function(e) { deferred.reject(e); });
1344
1345
    return deferred.promise;
1346
};
1347
1348
function verifyPublicBip32Key(bip32Key, network) {
1349
    var hk = bitcoin.HDNode.fromBase58(bip32Key[0], network);
1350
    if (typeof hk.keyPair.d !== "undefined") {
1351
        throw new Error('BIP32Key contained private key material - abort');
1352
    }
1353
1354
    if (bip32Key[1].slice(0, 1) !== "M") {
1355
        throw new Error("BIP32Key contained non-public path - abort");
1356
    }