mirror of https://github.com/BTCPrivate/copay.git
WIP: ledger P2PKH
This commit is contained in:
parent
c4964c1929
commit
78e6120e55
|
@ -106,13 +106,15 @@
|
|||
<span translate>Use Ledger hardware wallet</span>
|
||||
<switch id="hw-ledger" name="hwLedger" ng-model="hwLedger" ng-change="isTestnet=false" class="green right m5t m10b"></switch>
|
||||
</label>
|
||||
<!-- account
|
||||
<div ng-show="hwLedger">
|
||||
<label class="oh"><span translate>Ledger Slot</span>
|
||||
<select class="m10t" ng-model="externalIndex" ng-options="externalIndex as externalIndex for externalIndex in create.externalIndexValues">
|
||||
</select>
|
||||
</label>
|
||||
<div class="oh text-gray line-b size-12 p10b m20b"><span translate>Ledger supports up to 20 Copay wallets simultaneously. Select which slot should be used to host this wallet</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<label for="network-name" class="oh" ng-show="!hwLedger">
|
||||
<span translate>Testnet</span>
|
||||
<switch id="network-name" name="isTestnet" ng-model="isTestnet" class="green right m5t m10b"></switch>
|
||||
|
|
|
@ -174,20 +174,20 @@
|
|||
{{import.error|translate}}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="large-12 columns">
|
||||
<!-- TODO: account
|
||||
<label class=" oh">
|
||||
<span translate>Ledger Slot</span>
|
||||
<select class="m10t" ng-model="externalIndex" ng-options="externalIndex as externalIndex for externalIndex in import.externalIndexValues">
|
||||
</select>
|
||||
</label>
|
||||
<div class="oh text-gray line-b size-12 p10b m20b"><span translate>Ledger supports up to 20 Copay wallets simultaneously. Select which slot to import</div>
|
||||
-->
|
||||
<button translate type="submit" class="button round expand black"
|
||||
ng-disabled="import.loading || import.ledger">
|
||||
Import backup
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
<switch id="hw-ledger" name="hwLedger" ng-model="hwLedger" class="green right m5t m10b"></switch>
|
||||
</label>
|
||||
</div>
|
||||
<!-- TODO account
|
||||
<div class="large-12 columns" ng-hide="!hwLedger">
|
||||
<label class="oh">
|
||||
<span translate>Ledger Slot</span>
|
||||
|
@ -98,7 +99,8 @@
|
|||
</select>
|
||||
</label>
|
||||
<div class="oh text-gray line-b size-12 p10b m20b"><span translate>Ledger supports up to 20 Copay wallets simultaneously. Select which slot should be used to host this wallet</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="large-12 columns">
|
||||
|
||||
<label ng-show="!hwLedger" for="seed" class="oh">
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<span translate>Hardware wallet</span>
|
||||
<span class="right text-gray">
|
||||
{{preferences.externalSource}}
|
||||
(index {{preferences.externalIndex}})
|
||||
<!-- (Accont {{preferences.externalAccount}}) -->
|
||||
</span>
|
||||
</li>
|
||||
<li class="line-b p20" ng-click="$root.go('backup')" ng-hide="index.isPrivKeyExternal">
|
||||
|
|
|
@ -35,8 +35,6 @@ angular.module('copayApp.controllers').controller('createController',
|
|||
$scope.requiredCopayers = Math.min(parseInt(n / 2 + 1), maxReq);
|
||||
};
|
||||
|
||||
this.externalIndexValues = lodash.range(0, ledger.MAX_SLOT);
|
||||
$scope.externalIndex = 0;
|
||||
this.TCValues = lodash.range(2, defaults.limits.totalCopayers + 1);
|
||||
$scope.totalCopayers = defaults.wallet.totalCopayers;
|
||||
|
||||
|
@ -80,7 +78,8 @@ angular.module('copayApp.controllers').controller('createController',
|
|||
|
||||
if (form.hwLedger.$modelValue) {
|
||||
self.ledger = true;
|
||||
ledger.getInfoForNewWallet($scope.externalIndex, function(err, lopts) {
|
||||
// TODO : account
|
||||
ledger.getInfoForNewWallet(0, function(err, lopts) {
|
||||
self.ledger = false;
|
||||
if (err) {
|
||||
self.error = err;
|
||||
|
|
|
@ -7,8 +7,6 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
|
||||
this.isSafari = isMobile.Safari();
|
||||
this.isCordova = isCordova;
|
||||
this.externalIndexValues = lodash.range(0, ledger.MAX_SLOT);
|
||||
$scope.externalIndex = 0;
|
||||
var reader = new FileReader();
|
||||
|
||||
window.ignoreMobilePause = true;
|
||||
|
@ -199,7 +197,8 @@ angular.module('copayApp.controllers').controller('importController',
|
|||
return;
|
||||
}
|
||||
self.ledger = true;
|
||||
ledger.getInfoForNewWallet($scope.externalIndex, function(err, lopts) {
|
||||
// TODO account
|
||||
ledger.getInfoForNewWallet(0, function(err, lopts) {
|
||||
self.ledger = false;
|
||||
if (err) {
|
||||
self.error = err;
|
||||
|
|
|
@ -4,8 +4,6 @@ angular.module('copayApp.controllers').controller('joinController',
|
|||
function($scope, $rootScope, $timeout, go, isMobile, notification, profileService, isCordova, isChromeApp, $modal, gettext, lodash, ledger) {
|
||||
|
||||
var self = this;
|
||||
this.externalIndexValues = lodash.range(0,ledger.MAX_SLOT);
|
||||
$scope.externalIndex = 0;
|
||||
|
||||
this.isChromeApp = function() {
|
||||
return isChromeApp;
|
||||
|
@ -176,7 +174,8 @@ angular.module('copayApp.controllers').controller('joinController',
|
|||
|
||||
if (form.hwLedger.$modelValue) {
|
||||
self.ledger = true;
|
||||
ledger.getInfoForNewWallet($scope.externalIndex, function(err, lopts) {
|
||||
// TODO account
|
||||
ledger.getInfoForNewWallet(0, function(err, lopts) {
|
||||
self.ledger = false;
|
||||
if (err) {
|
||||
self.error = err;
|
||||
|
|
|
@ -17,7 +17,8 @@ angular.module('copayApp.controllers').controller('preferencesController',
|
|||
if (fc) {
|
||||
$scope.encrypt = fc.hasPrivKeyEncrypted();
|
||||
this.externalSource = fc.getPrivKeyExternalSourceName() == 'ledger' ? "Ledger" : null;
|
||||
this.externalIndex = fc.getExternalIndex();
|
||||
// TODO externalAccount
|
||||
//this.externalIndex = fc.getExternalIndex();
|
||||
}
|
||||
|
||||
var unwatchSpendUnconfirmed = $scope.$watch('spendUnconfirmed', function(newVal, oldVal) {
|
||||
|
|
|
@ -264,7 +264,8 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
self.setOngoingProcess(gettext('Requesting Ledger Wallet to sign'));
|
||||
$scope.loading = true;
|
||||
$scope.error = null;
|
||||
ledger.signTx(txp, fc.getExternalIndex(), function(result) {
|
||||
// TODO account
|
||||
ledger.signTx(txp, 0, function(result) {
|
||||
if (result.success) {
|
||||
txp.signatures = [];
|
||||
for (var i=0; i<result.signatures.length; i++) {
|
||||
|
@ -836,7 +837,8 @@ angular.module('copayApp.controllers').controller('walletHomeController', functi
|
|||
if (fc.getPrivKeyExternalSourceName() == 'ledger') {
|
||||
$log.debug('Requesting Ledger Chrome app to sign the transaction');
|
||||
self.setOngoingProcess(gettext('Requesting Ledger Wallet to sign'));
|
||||
ledger.signTx(txp, fc.getExternalIndex(), function(result) {
|
||||
// TODO account
|
||||
ledger.signTx(txp, 0, function(result) {
|
||||
if (result.success) {
|
||||
txp.signatures = [];
|
||||
for (var i=0; i<result.signatures.length; i++) {
|
||||
|
|
|
@ -4,7 +4,6 @@ angular.module('copayApp.services')
|
|||
.factory('ledger', function($log, bwcService, gettext) {
|
||||
var root = {};
|
||||
var LEDGER_CHROME_ID = "kkdpmhnladdopljabkgpacgpliggeeaf";
|
||||
root.MAX_SLOT = 20;
|
||||
|
||||
// Ledger magic number to get xPub without user confirmation
|
||||
root.ENTROPY_INDEX_PATH = "0xb11e/";
|
||||
|
@ -17,8 +16,8 @@ angular.module('copayApp.services')
|
|||
});
|
||||
}
|
||||
|
||||
root.getEntropySource = function(index, callback) {
|
||||
var path = root.ENTROPY_INDEX_PATH + index + "'";
|
||||
root.getEntropySource = function(account, callback) {
|
||||
var path = root.ENTROPY_INDEX_PATH + account + "'";
|
||||
var xpub = root.getXPubKey(path, function(data) {
|
||||
if (!data.success) {
|
||||
$log.warn(data.message);
|
||||
|
@ -33,8 +32,8 @@ angular.module('copayApp.services')
|
|||
});
|
||||
};
|
||||
|
||||
root.getXPubKeyForAddresses = function(index, callback) {
|
||||
return root.getXPubKey(root._getPath(index), callback);
|
||||
root.getXPubKeyForAddresses = function(account, callback) {
|
||||
return root.getXPubKey(root._getPath(account), callback);
|
||||
};
|
||||
|
||||
root.getXPubKey = function(path, callback) {
|
||||
|
@ -48,36 +47,37 @@ angular.module('copayApp.services')
|
|||
};
|
||||
|
||||
|
||||
root.getInfoForNewWallet = function(slot, callback) {
|
||||
root.getInfoForNewWallet = function(account, callback) {
|
||||
var opts = {};
|
||||
root.getEntropySource(slot, function(data) {
|
||||
root.getEntropySource(account, function(data) {
|
||||
if (!data.success) {
|
||||
$log.warn(data.message);
|
||||
return callback(data.message);
|
||||
}
|
||||
opts.entropySource = data.entropySource;
|
||||
root.getXPubKeyForAddresses(slot, function(data) {
|
||||
root.getXPubKeyForAddresses(account, function(data) {
|
||||
if (!data.success) {
|
||||
$log.warn(data.message);
|
||||
return callback(data);
|
||||
}
|
||||
opts.extendedPublicKey = data.xpubkey;
|
||||
opts.externalSource = 'ledger';
|
||||
opts.externalIndex = slot;
|
||||
opts.externalIndex = account;
|
||||
return callback(null, opts);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
root.signTx = function(txp, index, callback) {
|
||||
|
||||
root._signP2PKH = function(txp, account, callback) {
|
||||
root.callbacks["sign_p2sh"] = callback;
|
||||
var redeemScripts = [];
|
||||
var paths = [];
|
||||
var tx = bwcService.getUtils().buildTx(txp);
|
||||
for (var i = 0; i < tx.inputs.length; i++) {
|
||||
redeemScripts.push(new ByteString(tx.inputs[i].redeemScript.toBuffer().toString('hex'), GP.HEX).toString());
|
||||
paths.push(root._getPath(index) + txp.inputs[i].path.substring(1));
|
||||
paths.push(root._getPath(account) + txp.inputs[i].path.substring(1));
|
||||
}
|
||||
var splitTransaction = root._splitTransaction(new ByteString(tx.toString(), GP.HEX));
|
||||
var inputs = [];
|
||||
|
@ -97,6 +97,44 @@ angular.module('copayApp.services')
|
|||
outputs_script: splitTransaction.outputScript.toString(),
|
||||
paths: paths
|
||||
});
|
||||
};
|
||||
|
||||
root._signP2SH = function(txp, account, callback) {
|
||||
root.callbacks["sign_p2sh"] = callback;
|
||||
var redeemScripts = [];
|
||||
var paths = [];
|
||||
var tx = bwcService.getUtils().buildTx(txp);
|
||||
for (var i = 0; i < tx.inputs.length; i++) {
|
||||
redeemScripts.push(new ByteString(tx.inputs[i].redeemScript.toBuffer().toString('hex'), GP.HEX).toString());
|
||||
paths.push(root._getPath(account) + txp.inputs[i].path.substring(1));
|
||||
}
|
||||
var splitTransaction = root._splitTransaction(new ByteString(tx.toString(), GP.HEX));
|
||||
var inputs = [];
|
||||
for (var i = 0; i < splitTransaction.inputs.length; i++) {
|
||||
var input = splitTransaction.inputs[i];
|
||||
inputs.push([
|
||||
root._reverseBytestring(input.prevout.bytes(0, 32)).toString(),
|
||||
root._reverseBytestring(input.prevout.bytes(32)).toString()
|
||||
]);
|
||||
}
|
||||
$log.debug('Ledger signing paths:', paths);
|
||||
root._messageAfterSession({
|
||||
command: "sign_p2sh",
|
||||
inputs: inputs,
|
||||
scripts: redeemScripts,
|
||||
outputs_number: splitTransaction.outputs.length,
|
||||
outputs_script: splitTransaction.outputScript.toString(),
|
||||
paths: paths
|
||||
});
|
||||
};
|
||||
|
||||
root.signTx = function(txp, account, callback) {
|
||||
console.log('[ledger.js.72:txp:]', txp, account); //TODO
|
||||
if (txp.addressType == 'P2PKH') {
|
||||
root._signP2PKH(txp, account, callback);
|
||||
} else {
|
||||
root._signP2SH(txp, account, callback);
|
||||
}
|
||||
}
|
||||
|
||||
root._message = function(data) {
|
||||
|
@ -146,8 +184,8 @@ angular.module('copayApp.services')
|
|||
}
|
||||
}
|
||||
|
||||
root._getPath = function(index) {
|
||||
return index + "'/45'";
|
||||
root._getPath = function(account) {
|
||||
return "44'/0'/" + account + "'";
|
||||
}
|
||||
|
||||
root._splitTransaction = function(transaction) {
|
||||
|
|
|
@ -193,7 +193,7 @@ angular.module('copayApp.services')
|
|||
}
|
||||
} else if (opts.extendedPublicKey) {
|
||||
try {
|
||||
walletClient.seedFromExtendedPublicKey(opts.extendedPublicKey, opts.externalSource, opts.externalIndex, opts.entropySource);
|
||||
walletClient.seedFromExtendedPublicKey(opts.extendedPublicKey, opts.externalSource, opts.entropySource);
|
||||
} catch (ex) {
|
||||
$log.warn(ex);
|
||||
return cb(gettext('Could not create using the specified extended public key'));
|
||||
|
@ -411,7 +411,7 @@ angular.module('copayApp.services')
|
|||
var walletClient = bwcService.getClient();
|
||||
$log.debug('Importing Wallet XPubKey');
|
||||
|
||||
walletClient.importFromExtendedPublicKey(opts.extendedPublicKey, opts.externalSource, opts.externalIndex, opts.entropySource, function(err) {
|
||||
walletClient.importFromExtendedPublicKey(opts.extendedPublicKey, opts.externalSource, opts.entropySource, function(err) {
|
||||
if (err) {
|
||||
|
||||
// in HW wallets, req key is always the same. They can't addAccess.
|
||||
|
|
Loading…
Reference in New Issue