@ -13,35 +13,64 @@ var SignUtils = require('./signutils');
var BASE_URL = 'http://localhost:3001/copay/api/' ;
var clilib = { } ;
function _ getUrl ( path ) {
return BASE_URL + path ;
} ;
function _ parseError ( body ) {
if ( _ . isString ( body ) ) {
body = JSON . parse ( body ) ;
}
var code = body . code || 'ERROR' ;
var message = body . error || 'There was an unknown error processing the request' ;
log . error ( code , message ) ;
} ;
function _ signRequest ( url , args , privKey ) {
var message = url + ( args ? '|' + JSON . stringify ( args ) : '' ) ;
return SignUtils . sign ( message , privKey ) ;
} ;
function _ signRequest ( url , args ) {
function _ createXPrivKey ( ) {
return new Bitcore . HDPrivateKey ( ) . toString ( ) ;
} ;
function CliLib ( opts ) {
this . filename = opts . filename ;
} ;
function _ save ( data ) {
fs . writeFileSync ( '.bit' , JSON . stringify ( data ) ) ;
CliLib . prototype . _ save = function ( data ) {
fs . writeFileSync ( this . filename , JSON . stringify ( data ) ) ;
} ;
function _ load ( ) {
CliLib . prototype . _ load = function ( ) {
try {
return JSON . parse ( fs . readFileSync ( '.bit' ) ) ;
return JSON . parse ( fs . readFileSync ( this . filename ) ) ;
} catch ( ex ) { }
} ;
function _ createXPrivKey ( ) {
return new Bitcore . HDPrivateKey ( ) . toString ( ) ;
CliLib . prototype . _ loadAndCheck = function ( ) {
var data = this . _ load ( ) ;
if ( ! data ) {
log . error ( 'Wallet file not found.' ) ;
process . exit ( 1 ) ;
}
if ( data . n > 1 ) {
var pkrComplete = data . publicKeyRing && data . m && data . publicKeyRing . length === data . n ;
if ( ! pkrComplete ) {
log . warn ( 'The file ' + this . filename + ' is incomplete. It will allow you to operate with the wallet but it should not be trusted as a backup. Please wait for all copayers to join the wallet and run the tool with -export flag.' )
}
}
return data ;
} ;
clilib . createWallet = function ( walletName , copayerName , m , n , cb ) {
var data = _ load ( ) ;
if ( data ) return cb ( 'Only one wallet can exist' ) ;
CliLib . prototype . createWallet = function ( walletName , copayerName , m , n , network , cb ) {
var self = this ;
var data = this . _ load ( ) ;
if ( data ) return cb ( 'Only one wallet is supported in this version' ) ;
data = {
xPrivKey : _ createXPrivKey ( ) ,
@ -56,6 +85,7 @@ clilib.createWallet = function(walletName, copayerName, m, n, cb) {
m : m ,
n : n ,
pubKey : pubKey . toString ( ) ,
network : network || 'livenet' ,
} ;
request ( {
@ -65,12 +95,18 @@ clilib.createWallet = function(walletName, copayerName, m, n, cb) {
json : true ,
} , function ( err , res , body ) {
if ( err ) return cb ( err ) ;
var walletId = body ;
data . secret = walletId + '|' + privKey . toString ( ) ;
if ( res . statusCode != 200 ) {
_ parseError ( body ) ;
return cb ( 'Request error' ) ;
}
_ save ( data ) ;
var walletId = body . walletId ;
var secret = walletId + '|' + privKey . toString ( ) ;
data . secret = secret ;
clilib . joinWallet ( data . secret , copayerName , function ( err ) {
self . _ save ( data ) ;
self . _ joinWallet ( data , secret , copayerName , function ( err ) {
if ( err ) return cb ( err ) ;
return cb ( null , data . secret ) ;
@ -78,27 +114,22 @@ clilib.createWallet = function(walletName, copayerName, m, n, cb) {
} ) ;
} ;
clilib . joinWallet = function ( secret , copayerName , cb ) {
var data = _ load ( ) ;
if ( data && data . copayerId ) return cb ( 'Only one wallet can exist' ) ;
if ( ! data ) {
data = {
xPrivKey : _ createXPrivKey ( ) ,
} ;
}
CliLib . prototype . _ joinWallet = function ( data , secret , copayerName , cb ) {
var self = this ;
var secretSplit = secret . split ( '|' ) ;
var walletId = secretSplit [ 0 ] ;
var privKey = Bitcore . PrivateKey . fromString ( secretSplit [ 1 ] ) ;
var pubKey = privKey . toPublicKey ( ) ;
var xPubKey = new Bitcore . HDPublicKey ( data . xPrivKey ) . toString ( ) ;
var xPubKeySignature = SignUtils . sign ( xPubKey , privKey ) ;
var xPubKey = new Bitcore . HDPublicKey ( data . xPrivKey ) ;
var xPubKeySignature = SignUtils . sign ( xPubKey . toString ( ) , privKey ) ;
var signingPrivKey = xPubKey . derive ( 'm/1/0' ) ;
var args = {
walletId : walletId ,
name : copayerName ,
xPubKey : xPubKey ,
xPubKey : xPubKey . toString ( ) ,
xPubKeySignature : xPubKeySignature ,
} ;
@ -109,23 +140,43 @@ clilib.joinWallet = function(secret, copayerName, cb) {
json : true ,
} , function ( err , res , body ) {
if ( err ) return cb ( err ) ;
var copayerId = body ;
data . copayerId = copayerId ;
if ( res . statusCode != 200 ) {
_ parseError ( body ) ;
return cb ( 'Request error' ) ;
}
var wallet = body . wallet ;
data . copayerId = body . copayerId ;
data . signingPrivKey = signingPrivKey . toString ( ) ;
data . m = wallet . m ;
data . n = wallet . n ;
data . publicKeyRing = wallet . publicKeyRing ;
self . _ save ( data ) ;
return cb ( ) ;
} ) ;
} ;
_ save ( data ) ;
CliLib . prototype . joinWallet = function ( secret , copayerName , cb ) {
var self = this ;
// TODO: call status to retrieve wallet.m
var data = this . _ load ( ) ;
if ( data ) return cb ( 'Only one wallet is supported in this version' ) ;
return clilib . status ( cb ) ;
} ) ;
data = {
xPrivKey : _ createXPrivKey ( ) ,
} ;
self . _ joinWallet ( data , secret , copayerName , cb ) ;
} ;
clilib . status = function ( cb ) {
var data = _ load ( ) ;
if ( ! data || ! data . copayerId ) return cb ( 'Not a part of an active wallet' ) ;
CliLib . prototype . status = function ( cb ) {
var self = this ;
var data = this . _ loadAndCheck ( ) ;
var url = 'v1/dump/' ;
var signature = _ signRequest ( url ) ;
var url = 'v1/wallets /' ;
var signature = _ signRequest ( url , null , data . signingPrivKey ) ;
request ( {
headers : {
@ -134,31 +185,36 @@ clilib.status = function(cb) {
} ,
method : 'get' ,
url : _ getUrl ( url ) ,
json : true ,
} , function ( err , res , body ) {
if ( err ) return cb ( err ) ;
if ( res . statusCode != 200 ) {
_ parseError ( body ) ;
return cb ( 'Request error' ) ;
}
return cb ( null , body ) ;
} ) ;
} ;
clilib . send = function ( addressTo , amount , message , cb ) {
CliLib . prototype . send = function ( addressTo , amount , message , cb ) {
} ;
clilib . sign = function ( proposalId , cb ) {
CliLib . prototype . sign = function ( proposalId , cb ) {
} ;
clilib . reject = function ( proposalId , cb ) {
CliLib . prototype . reject = function ( proposalId , cb ) {
} ;
clilib . address = function ( cb ) {
CliLib . prototype . address = function ( cb ) {
} ;
clilib . history = function ( limit , cb ) {
CliLib . prototype . history = function ( limit , cb ) {
} ;
module . exports = clil ib;
module . exports = CliL ib;