rpc: better error codes.
This commit is contained in:
parent
5ee8a9b306
commit
3ae417795f
420
lib/http/rpc.js
420
lib/http/rpc.js
File diff suppressed because it is too large
Load Diff
@ -106,7 +106,7 @@ RPCBase.prototype.call = co(function* call(body, query) {
|
||||
var cmds = body;
|
||||
var out = [];
|
||||
var array = true;
|
||||
var i, cmd, result;
|
||||
var i, cmd, result, code;
|
||||
|
||||
if (!Array.isArray(cmds)) {
|
||||
cmds = [cmds];
|
||||
@ -116,19 +116,56 @@ RPCBase.prototype.call = co(function* call(body, query) {
|
||||
for (i = 0; i < cmds.length; i++) {
|
||||
cmd = cmds[i];
|
||||
|
||||
assert(cmd && typeof cmd === 'object', 'Command must be an object.');
|
||||
assert(typeof cmd.method === 'string', 'Method must be a string.');
|
||||
if (!cmd || typeof cmd !== 'object') {
|
||||
out.push({
|
||||
result: null,
|
||||
error: {
|
||||
message: 'Invalid request.',
|
||||
code: RPCBase.errors.INVALID_REQUEST
|
||||
},
|
||||
id: null
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmd.id && typeof cmd.id === 'object') {
|
||||
out.push({
|
||||
result: null,
|
||||
error: {
|
||||
message: 'Invalid ID.',
|
||||
code: RPCBase.errors.INVALID_REQUEST
|
||||
},
|
||||
id: null
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof cmd.method !== 'string') {
|
||||
out.push({
|
||||
result: null,
|
||||
error: {
|
||||
message: 'Method not found.',
|
||||
code: RPCBase.errors.METHOD_NOT_FOUND
|
||||
},
|
||||
id: cmd.id
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cmd.params)
|
||||
cmd.params = [];
|
||||
|
||||
assert(Array.isArray(cmd.params), 'Params must be an array.');
|
||||
|
||||
assert(!cmd.id || typeof cmd.id !== 'object', 'Invalid ID.');
|
||||
}
|
||||
|
||||
for (i = 0; i < cmds.length; i++) {
|
||||
cmd = cmds[i];
|
||||
if (!Array.isArray(cmd.params)) {
|
||||
out.push({
|
||||
result: null,
|
||||
error: {
|
||||
message: 'Invalid params.',
|
||||
code: RPCBase.errors.INVALID_PARAMS
|
||||
},
|
||||
id: cmd.id
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmd.method !== 'getwork'
|
||||
&& cmd.method !== 'getblocktemplate'
|
||||
@ -148,25 +185,25 @@ RPCBase.prototype.call = co(function* call(body, query) {
|
||||
try {
|
||||
result = yield this.execute(cmd);
|
||||
} catch (err) {
|
||||
if (err.type === 'RPCError') {
|
||||
out.push({
|
||||
result: null,
|
||||
error: {
|
||||
message: err.message,
|
||||
code: -1
|
||||
},
|
||||
id: cmd.id
|
||||
});
|
||||
continue;
|
||||
switch (err.type) {
|
||||
case 'RPCError':
|
||||
code = err.code;
|
||||
break;
|
||||
case 'ValidationError':
|
||||
code = RPCBase.errors.TYPE_ERROR;
|
||||
break;
|
||||
default:
|
||||
code = RPCBase.errors.INTERNAL_ERROR;
|
||||
this.logger.error('RPC internal error.');
|
||||
this.logger.error(err);
|
||||
break;
|
||||
}
|
||||
|
||||
this.logger.error(err);
|
||||
|
||||
out.push({
|
||||
result: null,
|
||||
error: {
|
||||
message: err.message,
|
||||
code: 1
|
||||
code: code
|
||||
},
|
||||
id: cmd.id
|
||||
});
|
||||
@ -254,15 +291,18 @@ RPCBase.prototype.attach = function attach(rpc) {
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
function RPCError(msg, code) {
|
||||
function RPCError(code, msg) {
|
||||
Error.call(this);
|
||||
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, RPCError);
|
||||
|
||||
assert(typeof code === 'number');
|
||||
assert(typeof msg === 'string');
|
||||
|
||||
this.type = 'RPCError';
|
||||
this.message = msg;
|
||||
this.code = code != null ? code : -1;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
util.inherits(RPCError, Error);
|
||||
|
||||
@ -87,7 +87,7 @@ Validator.prototype.get = function get(key, fallback) {
|
||||
map = this.data[i];
|
||||
|
||||
if (!map || typeof map !== 'object')
|
||||
throw new Error('Data is not an object.');
|
||||
throw new ValidationError('Data is not an object.');
|
||||
|
||||
value = map[key];
|
||||
|
||||
@ -115,7 +115,7 @@ Validator.prototype.str = function str(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string')
|
||||
throw new Error(fmt(key) + ' must be a string.');
|
||||
throw new ValidationError(fmt(key) + ' must be a string.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -138,17 +138,17 @@ Validator.prototype.num = function num(key, fallback) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(fmt(key) + ' must be a number.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number.');
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!/^\d+$/.test(value))
|
||||
throw new Error(fmt(key) + ' must be a number.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number.');
|
||||
|
||||
value = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(value))
|
||||
throw new Error(fmt(key) + ' must be a number.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -170,7 +170,7 @@ Validator.prototype.u32 = function u32(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (value % 1 !== 0 || value < 0 || value > 0xffffffff)
|
||||
throw new Error(fmt(key) + ' must be a uint32.');
|
||||
throw new ValidationError(fmt(key) + ' must be a uint32.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -192,7 +192,7 @@ Validator.prototype.u64 = function u64(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (value % 1 !== 0 || value < 0 || value > 0x1fffffffffffff)
|
||||
throw new Error(fmt(key) + ' must be a uint64.');
|
||||
throw new ValidationError(fmt(key) + ' must be a uint64.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -214,7 +214,7 @@ Validator.prototype.i32 = function i32(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (value % 1 !== 0 || Math.abs(value) > 0x7fffffff)
|
||||
throw new Error(fmt(key) + ' must be an int32.');
|
||||
throw new ValidationError(fmt(key) + ' must be an int32.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -236,7 +236,7 @@ Validator.prototype.i64 = function i64(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (value % 1 !== 0 || Math.abs(value) > 0x1fffffffffffff)
|
||||
throw new Error(fmt(key) + ' must be an int64.');
|
||||
throw new ValidationError(fmt(key) + ' must be an int64.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -259,22 +259,22 @@ Validator.prototype.amt = function amt(key, fallback) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(fmt(key) + ' must be a number.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number.');
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!/^\d+(\.\d{0,8})?$/.test(value))
|
||||
throw new Error(fmt(key) + ' must be a number.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number.');
|
||||
|
||||
value = parseFloat(value);
|
||||
|
||||
if (!isFinite(value))
|
||||
throw new Error(fmt(key) + ' must be a number.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number.');
|
||||
|
||||
value *= 1e8;
|
||||
|
||||
if (value % 1 !== 0 || value < 0 || value > 0x1fffffffffffff)
|
||||
throw new Error(fmt(key) + ' must be a uint64.');
|
||||
throw new ValidationError(fmt(key) + ' must be a uint64.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -298,7 +298,7 @@ Validator.prototype.btc = function btc(key, fallback) {
|
||||
value *= 1e8;
|
||||
|
||||
if (value % 1 !== 0 || value < 0 || value > 0x1fffffffffffff)
|
||||
throw new Error(fmt(key) + ' must be a uint64.');
|
||||
throw new ValidationError(fmt(key) + ' must be a uint64.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -323,17 +323,17 @@ Validator.prototype.hash = function hash(key, fallback) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (!Buffer.isBuffer(value))
|
||||
throw new Error(fmt(key) + ' must be a hash.');
|
||||
throw new ValidationError(fmt(key) + ' must be a hash.');
|
||||
if (value.length !== 32)
|
||||
throw new Error(fmt(key) + ' must be a hash.');
|
||||
throw new ValidationError(fmt(key) + ' must be a hash.');
|
||||
return value.toString('hex');
|
||||
}
|
||||
|
||||
if (value.length !== 64)
|
||||
throw new Error(fmt(key) + ' must be a hex string.');
|
||||
throw new ValidationError(fmt(key) + ' must be a hex string.');
|
||||
|
||||
if (!/^[0-9a-f]+$/i.test(value))
|
||||
throw new Error(fmt(key) + ' must be a hex string.');
|
||||
throw new ValidationError(fmt(key) + ' must be a hex string.');
|
||||
|
||||
for (i = 0; i < value.length; i += 2)
|
||||
out = value.slice(i, i + 2) + out;
|
||||
@ -379,7 +379,7 @@ Validator.prototype.numstr = function numstr(key, fallback) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(fmt(key) + ' must be a number or string.');
|
||||
throw new ValidationError(fmt(key) + ' must be a number or string.');
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@ Validator.prototype.bool = function bool(key, fallback) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'boolean')
|
||||
throw new Error(fmt(key) + ' must be a boolean.');
|
||||
throw new ValidationError(fmt(key) + ' must be a boolean.');
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -419,7 +419,7 @@ Validator.prototype.bool = function bool(key, fallback) {
|
||||
if (value === 'false' || value === '0')
|
||||
return false;
|
||||
|
||||
throw new Error(fmt(key) + ' must be a boolean.');
|
||||
throw new ValidationError(fmt(key) + ' must be a boolean.');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -445,14 +445,14 @@ Validator.prototype.buf = function buf(key, fallback, enc) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (!Buffer.isBuffer(value))
|
||||
throw new Error(fmt(key) + ' must be a buffer.');
|
||||
throw new ValidationError(fmt(key) + ' must be a buffer.');
|
||||
return value;
|
||||
}
|
||||
|
||||
data = new Buffer(value, enc);
|
||||
|
||||
if (data.length !== Buffer.byteLength(value, enc))
|
||||
throw new Error(fmt(key) + ' must be a ' + enc + ' string.');
|
||||
throw new ValidationError(fmt(key) + ' must be a ' + enc + ' string.');
|
||||
|
||||
return data;
|
||||
};
|
||||
@ -476,7 +476,7 @@ Validator.prototype.array = function array(key, fallback) {
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (!Array.isArray(value))
|
||||
throw new Error(fmt(key) + ' must be a list/array.');
|
||||
throw new ValidationError(fmt(key) + ' must be a list/array.');
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -512,7 +512,7 @@ Validator.prototype.obj = function obj(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (!value || typeof value !== 'object')
|
||||
throw new Error(fmt(key) + ' must be an object.');
|
||||
throw new ValidationError(fmt(key) + ' must be an object.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -534,7 +534,7 @@ Validator.prototype.func = function func(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'function')
|
||||
throw new Error(fmt(key) + ' must be a function.');
|
||||
throw new ValidationError(fmt(key) + ' must be a function.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -549,8 +549,31 @@ function fmt(key) {
|
||||
return key;
|
||||
}
|
||||
|
||||
function inherits(obj, from) {
|
||||
var f = function() {};
|
||||
f.prototype = from.prototype;
|
||||
obj.prototype = new f;
|
||||
obj.prototype.constructor = obj;
|
||||
}
|
||||
|
||||
function ValidationError(msg) {
|
||||
Error.call(this);
|
||||
|
||||
if (Error.captureStackTrace)
|
||||
Error.captureStackTrace(this, ValidationError);
|
||||
|
||||
this.type = 'ValidationError';
|
||||
this.message = msg;
|
||||
}
|
||||
|
||||
inherits(ValidationError, Error);
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = Validator;
|
||||
exports = Validator;
|
||||
exports.Validator = Validator;
|
||||
exports.Error = ValidationError;
|
||||
|
||||
module.exports = exports;
|
||||
|
||||
@ -26,6 +26,7 @@ var pkg = require('../pkg');
|
||||
var Validator = require('../utils/validator');
|
||||
var common = require('./common');
|
||||
var RPCError = RPCBase.RPCError;
|
||||
var errs = RPCBase.errors;
|
||||
var MAGIC_STRING = RPCBase.MAGIC_STRING;
|
||||
|
||||
/**
|
||||
@ -126,7 +127,7 @@ RPC.prototype.help = co(function* _help(args, help) {
|
||||
|
||||
RPC.prototype.stop = co(function* stop(args, help) {
|
||||
if (help || args.length !== 0)
|
||||
throw new RPCError('stop');
|
||||
throw new RPCError(errs.MISC_ERROR, 'stop');
|
||||
|
||||
this.wdb.close();
|
||||
|
||||
@ -141,16 +142,20 @@ RPC.prototype.fundRawTransaction = co(function* fundRawTransaction(args, help) {
|
||||
var rate = this.feeRate;
|
||||
var change, tx;
|
||||
|
||||
if (help || args.length < 1 || args.length > 2)
|
||||
throw new RPCError('fundrawtransaction "hexstring" ( options )');
|
||||
if (help || args.length < 1 || args.length > 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'fundrawtransaction "hexstring" ( options )');
|
||||
}
|
||||
|
||||
if (!data)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid hex string.');
|
||||
|
||||
tx = MTX.fromRaw(data);
|
||||
tx = fromRaw(MTX, data);
|
||||
|
||||
if (tx.outputs.length === 0)
|
||||
throw new RPCError('TX must have at least one output.');
|
||||
if (tx.outputs.length === 0) {
|
||||
throw new RPCError(errs.INVALID_PARAMETER,
|
||||
'TX must have at least one output.');
|
||||
}
|
||||
|
||||
if (options) {
|
||||
valid = new Validator([options]);
|
||||
@ -158,7 +163,7 @@ RPC.prototype.fundRawTransaction = co(function* fundRawTransaction(args, help) {
|
||||
rate = valid.btc('feeRate');
|
||||
|
||||
if (change)
|
||||
change = Address.fromBase58(change, this.network);
|
||||
change = parseAddress(change, this.network);
|
||||
}
|
||||
|
||||
options = {
|
||||
@ -166,7 +171,11 @@ RPC.prototype.fundRawTransaction = co(function* fundRawTransaction(args, help) {
|
||||
changeAddress: change
|
||||
};
|
||||
|
||||
yield wallet.fund(tx, options);
|
||||
try {
|
||||
yield wallet.fund(tx, options);
|
||||
} catch (e) {
|
||||
throw new RPCError(errs.WALLET_INSUFFICIENT_FUNDS, e.message);
|
||||
}
|
||||
|
||||
return {
|
||||
hex: tx.toRaw().toString('hex'),
|
||||
@ -185,7 +194,7 @@ RPC.prototype.resendWalletTransactions = co(function* resendWalletTransactions(a
|
||||
var i, tx, txs;
|
||||
|
||||
if (help || args.length !== 0)
|
||||
throw new RPCError('resendwallettransactions');
|
||||
throw new RPCError(errs.MISC_ERROR, 'resendwallettransactions');
|
||||
|
||||
txs = yield wallet.resend();
|
||||
|
||||
@ -199,7 +208,7 @@ RPC.prototype.resendWalletTransactions = co(function* resendWalletTransactions(a
|
||||
|
||||
RPC.prototype.addMultisigAddress = co(function* addMultisigAddress(args, help) {
|
||||
if (help || args.length < 2 || args.length > 3) {
|
||||
throw new RPCError('addmultisigaddress'
|
||||
throw new RPCError(errs.MISC_ERROR, 'addmultisigaddress'
|
||||
+ ' nrequired ["key",...] ( "account" )');
|
||||
}
|
||||
|
||||
@ -209,7 +218,7 @@ RPC.prototype.addMultisigAddress = co(function* addMultisigAddress(args, help) {
|
||||
|
||||
RPC.prototype.addWitnessAddress = co(function* addWitnessAddress(args, help) {
|
||||
if (help || args.length < 1 || args.length > 1)
|
||||
throw new RPCError('addwitnessaddress "address"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'addwitnessaddress "address"');
|
||||
|
||||
// Unlikely to be implemented.
|
||||
throw new Error('Not implemented.');
|
||||
@ -220,7 +229,7 @@ RPC.prototype.backupWallet = co(function* backupWallet(args, help) {
|
||||
var dest = valid.str(0);
|
||||
|
||||
if (help || args.length !== 1 || !dest)
|
||||
throw new RPCError('backupwallet "destination"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'backupwallet "destination"');
|
||||
|
||||
yield this.wdb.backup(dest);
|
||||
|
||||
@ -235,15 +244,15 @@ RPC.prototype.dumpPrivKey = co(function* dumpPrivKey(args, help) {
|
||||
var ring;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('dumpprivkey "bitcoinaddress"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'dumpprivkey "bitcoinaddress"');
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid address.');
|
||||
throw new RPCError(errs.INVALID_ADDRESS_OR_KEY, 'Invalid address.');
|
||||
|
||||
ring = yield wallet.getPrivateKey(hash);
|
||||
|
||||
if (!ring)
|
||||
throw new RPCError('Key not found.');
|
||||
throw new RPCError(errs.MISC_ERROR, 'Key not found.');
|
||||
|
||||
return ring.toSecret();
|
||||
});
|
||||
@ -256,10 +265,10 @@ RPC.prototype.dumpWallet = co(function* dumpWallet(args, help) {
|
||||
var i, tip, addr, fmt, str, out, hash, hashes, ring;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('dumpwallet "filename"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'dumpwallet "filename"');
|
||||
|
||||
if (!file)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
tip = yield this.wdb.getTip();
|
||||
|
||||
@ -312,15 +321,21 @@ RPC.prototype.encryptWallet = co(function* encryptWallet(args, help) {
|
||||
var passphrase = valid.str(0, '');
|
||||
|
||||
if (!wallet.master.encrypted && (help || args.length !== 1))
|
||||
throw new RPCError('encryptwallet "passphrase"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'encryptwallet "passphrase"');
|
||||
|
||||
if (wallet.master.encrypted)
|
||||
throw new RPCError('Already running with an encrypted wallet');
|
||||
if (wallet.master.encrypted) {
|
||||
throw new RPCError(errs.WALLET_WRONG_ENC_STATE,
|
||||
'Already running with an encrypted wallet.');
|
||||
}
|
||||
|
||||
if (passphrase.length < 1)
|
||||
throw new RPCError('encryptwallet "passphrase"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'encryptwallet "passphrase"');
|
||||
|
||||
yield wallet.setPassphrase(passphrase);
|
||||
try {
|
||||
yield wallet.setPassphrase(passphrase);
|
||||
} catch (e) {
|
||||
throw new RPCError(errs.WALLET_ENCRYPTION_FAILED, 'Encryption failed.');
|
||||
}
|
||||
|
||||
return 'wallet encrypted; we do not need to stop!';
|
||||
});
|
||||
@ -332,7 +347,7 @@ RPC.prototype.getAccountAddress = co(function* getAccountAddress(args, help) {
|
||||
var account;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('getaccountaddress "account"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getaccountaddress "account"');
|
||||
|
||||
if (!name)
|
||||
name = 'default';
|
||||
@ -353,10 +368,10 @@ RPC.prototype.getAccount = co(function* getAccount(args, help) {
|
||||
var path;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('getaccount "bitcoinaddress"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getaccount "bitcoinaddress"');
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid address.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid address.');
|
||||
|
||||
path = yield wallet.getPath(hash);
|
||||
|
||||
@ -373,7 +388,7 @@ RPC.prototype.getAddressesByAccount = co(function* getAddressesByAccount(args, h
|
||||
var i, path, address, addrs, paths;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('getaddressesbyaccount "account"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getaddressesbyaccount "account"');
|
||||
|
||||
if (name === '')
|
||||
name = 'default';
|
||||
@ -399,8 +414,10 @@ RPC.prototype.getBalance = co(function* getBalance(args, help) {
|
||||
var watchOnly = valid.bool(2, false);
|
||||
var value, balance;
|
||||
|
||||
if (help || args.length > 3)
|
||||
throw new RPCError('getbalance ( "account" minconf includeWatchonly )');
|
||||
if (help || args.length > 3) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'getbalance ( "account" minconf includeWatchonly )');
|
||||
}
|
||||
|
||||
if (name === '')
|
||||
name = 'default';
|
||||
@ -428,7 +445,7 @@ RPC.prototype.getNewAddress = co(function* getNewAddress(args, help) {
|
||||
var address;
|
||||
|
||||
if (help || args.length > 1)
|
||||
throw new RPCError('getnewaddress ( "account" )');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getnewaddress ( "account" )');
|
||||
|
||||
if (name === '')
|
||||
name = 'default';
|
||||
@ -443,7 +460,7 @@ RPC.prototype.getRawChangeAddress = co(function* getRawChangeAddress(args, help)
|
||||
var address;
|
||||
|
||||
if (help || args.length > 1)
|
||||
throw new RPCError('getrawchangeaddress');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getrawchangeaddress');
|
||||
|
||||
address = yield wallet.createChange();
|
||||
|
||||
@ -461,8 +478,10 @@ RPC.prototype.getReceivedByAccount = co(function* getReceivedByAccount(args, hel
|
||||
var lastConf = -1;
|
||||
var i, j, path, wtx, output, conf, hash, paths, txs;
|
||||
|
||||
if (help || args.length < 1 || args.length > 2)
|
||||
throw new RPCError('getreceivedbyaccount "account" ( minconf )');
|
||||
if (help || args.length < 1 || args.length > 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'getreceivedbyaccount "account" ( minconf )');
|
||||
}
|
||||
|
||||
if (name === '')
|
||||
name = 'default';
|
||||
@ -508,11 +527,13 @@ RPC.prototype.getReceivedByAddress = co(function* getReceivedByAddress(args, hel
|
||||
var total = 0;
|
||||
var i, j, wtx, output, txs;
|
||||
|
||||
if (help || args.length < 1 || args.length > 2)
|
||||
throw new RPCError('getreceivedbyaddress "bitcoinaddress" ( minconf )');
|
||||
if (help || args.length < 1 || args.length > 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'getreceivedbyaddress "bitcoinaddress" ( minconf )');
|
||||
}
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid address');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid address');
|
||||
|
||||
txs = yield wallet.getHistory();
|
||||
|
||||
@ -542,7 +563,7 @@ RPC.prototype._toWalletTX = co(function* _toWalletTX(wtx) {
|
||||
var i, member;
|
||||
|
||||
if (!details)
|
||||
throw new RPCError('TX not found.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'TX not found.');
|
||||
|
||||
for (i = 0; i < details.inputs.length; i++) {
|
||||
member = details.inputs[i];
|
||||
@ -613,16 +634,18 @@ RPC.prototype.getTransaction = co(function* getTransaction(args, help) {
|
||||
var watchOnly = valid.bool(1, false);
|
||||
var wtx;
|
||||
|
||||
if (help || args.length < 1 || args.length > 2)
|
||||
throw new RPCError('gettransaction "txid" ( includeWatchonly )');
|
||||
if (help || args.length < 1 || args.length > 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'gettransaction "txid" ( includeWatchonly )');
|
||||
}
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid parameter');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter');
|
||||
|
||||
wtx = yield wallet.getTX(hash);
|
||||
|
||||
if (!wtx)
|
||||
throw new RPCError('TX not found.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'TX not found.');
|
||||
|
||||
return yield this._toWalletTX(wtx, watchOnly);
|
||||
});
|
||||
@ -634,15 +657,15 @@ RPC.prototype.abandonTransaction = co(function* abandonTransaction(args, help) {
|
||||
var result;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('abandontransaction "txid"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'abandontransaction "txid"');
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
result = yield wallet.abandon(hash);
|
||||
|
||||
if (!result)
|
||||
throw new RPCError('Transaction not in wallet.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'Transaction not in wallet.');
|
||||
|
||||
return null;
|
||||
});
|
||||
@ -652,7 +675,7 @@ RPC.prototype.getUnconfirmedBalance = co(function* getUnconfirmedBalance(args, h
|
||||
var balance;
|
||||
|
||||
if (help || args.length > 0)
|
||||
throw new RPCError('getunconfirmedbalance');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getunconfirmedbalance');
|
||||
|
||||
balance = yield wallet.getBalance();
|
||||
|
||||
@ -664,7 +687,7 @@ RPC.prototype.getWalletInfo = co(function* getWalletInfo(args, help) {
|
||||
var balance;
|
||||
|
||||
if (help || args.length !== 0)
|
||||
throw new RPCError('getwalletinfo');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getwalletinfo');
|
||||
|
||||
balance = yield wallet.getBalance();
|
||||
|
||||
@ -690,10 +713,12 @@ RPC.prototype.importPrivKey = co(function* importPrivKey(args, help) {
|
||||
var rescan = valid.bool(2, false);
|
||||
var key;
|
||||
|
||||
if (help || args.length < 1 || args.length > 3)
|
||||
throw new RPCError('importprivkey "bitcoinprivkey" ( "label" rescan )');
|
||||
if (help || args.length < 1 || args.length > 3) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'importprivkey "bitcoinprivkey" ( "label" rescan )');
|
||||
}
|
||||
|
||||
key = KeyRing.fromSecret(secret, this.network);
|
||||
key = parseSecret(secret, this.network);
|
||||
|
||||
yield wallet.importKey(0, key);
|
||||
|
||||
@ -714,10 +739,10 @@ RPC.prototype.importWallet = co(function* importWallet(args, help) {
|
||||
var data, key;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('importwallet "filename" ( rescan )');
|
||||
throw new RPCError(errs.MISC_ERROR, 'importwallet "filename" ( rescan )');
|
||||
|
||||
if (fs.unsupported)
|
||||
throw new RPCError('FS not available.');
|
||||
throw new RPCError(errs.INTERNAL_ERROR, 'FS not available.');
|
||||
|
||||
data = yield fs.readFile(file, 'utf8');
|
||||
|
||||
@ -735,9 +760,9 @@ RPC.prototype.importWallet = co(function* importWallet(args, help) {
|
||||
parts = line.split(/\s+/);
|
||||
|
||||
if (parts.length < 4)
|
||||
throw new RPCError('Malformed wallet.');
|
||||
throw new RPCError(errs.DESERIALIZATION_ERROR, 'Malformed wallet.');
|
||||
|
||||
secret = KeyRing.fromSecret(parts[0], this.network);
|
||||
secret = parseSecret(parts[0], this.network);
|
||||
|
||||
time = +parts[1];
|
||||
label = parts[2];
|
||||
@ -765,21 +790,23 @@ RPC.prototype.importAddress = co(function* importAddress(args, help) {
|
||||
var p2sh = valid.bool(3, false);
|
||||
var script;
|
||||
|
||||
if (help || args.length < 1 || args.length > 4)
|
||||
throw new RPCError('importaddress "address" ( "label" rescan p2sh )');
|
||||
if (help || args.length < 1 || args.length > 4) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'importaddress "address" ( "label" rescan p2sh )');
|
||||
}
|
||||
|
||||
if (p2sh) {
|
||||
script = valid.buf(0);
|
||||
|
||||
if (!script)
|
||||
throw new RPCError('Invalid parameters.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameters.');
|
||||
|
||||
script = Script.fromRaw(script);
|
||||
script = fromRaw(Script, script);
|
||||
script = Script.fromScripthash(script.hash160());
|
||||
|
||||
addr = script.getAddress();
|
||||
} else {
|
||||
addr = Address.fromBase58(addr, this.network);
|
||||
addr = parseAddress(addr, this.network);
|
||||
}
|
||||
|
||||
yield wallet.importAddress(0, addr);
|
||||
@ -797,11 +824,13 @@ RPC.prototype.importPubkey = co(function* importPubkey(args, help) {
|
||||
var rescan = valid.bool(2, false);
|
||||
var key;
|
||||
|
||||
if (help || args.length < 1 || args.length > 4)
|
||||
throw new RPCError('importpubkey "pubkey" ( "label" rescan )');
|
||||
if (help || args.length < 1 || args.length > 4) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'importpubkey "pubkey" ( "label" rescan )');
|
||||
}
|
||||
|
||||
if (!data)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
key = KeyRing.fromPublic(data, this.network);
|
||||
|
||||
@ -815,7 +844,7 @@ RPC.prototype.importPubkey = co(function* importPubkey(args, help) {
|
||||
|
||||
RPC.prototype.keyPoolRefill = co(function* keyPoolRefill(args, help) {
|
||||
if (help || args.length > 1)
|
||||
throw new RPCError('keypoolrefill ( newsize )');
|
||||
throw new RPCError(errs.MISC_ERROR, 'keypoolrefill ( newsize )');
|
||||
return null;
|
||||
});
|
||||
|
||||
@ -827,8 +856,10 @@ RPC.prototype.listAccounts = co(function* listAccounts(args, help) {
|
||||
var map = {};
|
||||
var i, accounts, account, balance, value;
|
||||
|
||||
if (help || args.length > 2)
|
||||
throw new RPCError('listaccounts ( minconf includeWatchonly)');
|
||||
if (help || args.length > 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'listaccounts ( minconf includeWatchonly)');
|
||||
}
|
||||
|
||||
accounts = yield wallet.getAccounts();
|
||||
|
||||
@ -852,7 +883,7 @@ RPC.prototype.listAccounts = co(function* listAccounts(args, help) {
|
||||
|
||||
RPC.prototype.listAddressGroupings = co(function* listAddressGroupings(args, help) {
|
||||
if (help)
|
||||
throw new RPCError('listaddressgroupings');
|
||||
throw new RPCError(errs.MISC_ERROR, 'listaddressgroupings');
|
||||
throw new Error('Not implemented.');
|
||||
});
|
||||
|
||||
@ -861,7 +892,7 @@ RPC.prototype.listLockUnspent = co(function* listLockUnspent(args, help) {
|
||||
var i, outpoints, outpoint, out;
|
||||
|
||||
if (help || args.length > 0)
|
||||
throw new RPCError('listlockunspent');
|
||||
throw new RPCError(errs.MISC_ERROR, 'listlockunspent');
|
||||
|
||||
outpoints = wallet.getLocked();
|
||||
out = [];
|
||||
@ -884,8 +915,8 @@ RPC.prototype.listReceivedByAccount = co(function* listReceivedByAccount(args, h
|
||||
var watchOnly = valid.bool(2, false);
|
||||
|
||||
if (help || args.length > 3) {
|
||||
throw new RPCError('listreceivedbyaccount'
|
||||
+ ' ( minconf includeempty includeWatchonly )');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'listreceivedbyaccount ( minconf includeempty includeWatchonly )');
|
||||
}
|
||||
|
||||
return yield this._listReceived(minconf, includeEmpty, watchOnly, true);
|
||||
@ -898,8 +929,8 @@ RPC.prototype.listReceivedByAddress = co(function* listReceivedByAddress(args, h
|
||||
var watchOnly = valid.bool(2, false);
|
||||
|
||||
if (help || args.length > 3) {
|
||||
throw new RPCError('listreceivedbyaddress'
|
||||
+ ' ( minconf includeempty includeWatchonly )');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'listreceivedbyaddress ( minconf includeempty includeWatchonly )');
|
||||
}
|
||||
|
||||
return yield this._listReceived(minconf, includeEmpty, watchOnly, false);
|
||||
@ -1017,8 +1048,8 @@ RPC.prototype.listSinceBlock = co(function* listSinceBlock(args, help) {
|
||||
var i, entry, highest, txs, wtx, json;
|
||||
|
||||
if (help) {
|
||||
throw new RPCError('listsinceblock'
|
||||
+ ' ( "blockhash" target-confirmations includeWatchonly)');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'listsinceblock ( "blockhash" target-confirmations includeWatchonly)');
|
||||
}
|
||||
|
||||
if (wallet.watchOnly !== watchOnly)
|
||||
@ -1070,7 +1101,7 @@ RPC.prototype._toListTX = co(function* _toListTX(wtx) {
|
||||
var i, member, index;
|
||||
|
||||
if (!details)
|
||||
throw new RPCError('TX not found.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'TX not found.');
|
||||
|
||||
for (i = 0; i < details.inputs.length; i++) {
|
||||
member = details.inputs[i];
|
||||
@ -1145,7 +1176,7 @@ RPC.prototype.listTransactions = co(function* listTransactions(args, help) {
|
||||
var i, txs, wtx, json;
|
||||
|
||||
if (help || args.length > 4) {
|
||||
throw new RPCError(
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'listtransactions ( "account" count from includeWatchonly)');
|
||||
}
|
||||
|
||||
@ -1182,8 +1213,8 @@ RPC.prototype.listUnspent = co(function* listUnspent(args, help) {
|
||||
var i, depth, address, hash, coins, coin, ring;
|
||||
|
||||
if (help || args.length > 3) {
|
||||
throw new RPCError('listunspent'
|
||||
+ ' ( minconf maxconf ["address",...] )');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'listunspent ( minconf maxconf ["address",...] )');
|
||||
}
|
||||
|
||||
if (addrs) {
|
||||
@ -1193,10 +1224,10 @@ RPC.prototype.listUnspent = co(function* listUnspent(args, help) {
|
||||
hash = Address.getHash(address, 'hex');
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid address.');
|
||||
throw new RPCError(errs.INVALID_ADDRESS_OR_KEY, 'Invalid address.');
|
||||
|
||||
if (map[hash])
|
||||
throw new RPCError('Duplicate address.');
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Duplicate address.');
|
||||
|
||||
map[hash] = true;
|
||||
}
|
||||
@ -1254,8 +1285,8 @@ RPC.prototype.lockUnspent = co(function* lockUnspent(args, help) {
|
||||
var i, output, outpoint, hash, index;
|
||||
|
||||
if (help || args.length < 1 || args.length > 2) {
|
||||
throw new RPCError('lockunspent'
|
||||
+ ' unlock ([{"txid":"txid","vout":n},...])');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'lockunspent unlock ([{"txid":"txid","vout":n},...])');
|
||||
}
|
||||
|
||||
if (args.length === 1) {
|
||||
@ -1265,7 +1296,7 @@ RPC.prototype.lockUnspent = co(function* lockUnspent(args, help) {
|
||||
}
|
||||
|
||||
if (!outputs)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
for (i = 0; i < outputs.length; i++) {
|
||||
output = outputs[i];
|
||||
@ -1274,7 +1305,7 @@ RPC.prototype.lockUnspent = co(function* lockUnspent(args, help) {
|
||||
index = valid.u32('vout');
|
||||
|
||||
if (hash == null || index == null)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.');
|
||||
|
||||
outpoint = new Outpoint();
|
||||
outpoint.hash = hash;
|
||||
@ -1306,15 +1337,15 @@ RPC.prototype.sendFrom = co(function* sendFrom(args, help) {
|
||||
var options, tx;
|
||||
|
||||
if (help || args.length < 3 || args.length > 6) {
|
||||
throw new RPCError('sendfrom'
|
||||
+ ' "fromaccount" "tobitcoinaddress"'
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'sendfrom "fromaccount" "tobitcoinaddress"'
|
||||
+ ' amount ( minconf "comment" "comment-to" )');
|
||||
}
|
||||
|
||||
if (!addr || value == null)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
addr = Address.fromBase58(addr, this.network);
|
||||
addr = parseAddress(addr, this.network);
|
||||
|
||||
if (name === '')
|
||||
name = 'default';
|
||||
@ -1348,8 +1379,8 @@ RPC.prototype.sendMany = co(function* sendMany(args, help) {
|
||||
var hash, output, options;
|
||||
|
||||
if (help || args.length < 2 || args.length > 5) {
|
||||
throw new RPCError('sendmany'
|
||||
+ ' "fromaccount" {"address":amount,...}'
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'sendmany "fromaccount" {"address":amount,...}'
|
||||
+ ' ( minconf "comment" ["address",...] )');
|
||||
}
|
||||
|
||||
@ -1357,7 +1388,7 @@ RPC.prototype.sendMany = co(function* sendMany(args, help) {
|
||||
name = 'default';
|
||||
|
||||
if (!sendTo)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
keys = Object.keys(sendTo);
|
||||
valid = new Validator([sendTo]);
|
||||
@ -1365,14 +1396,14 @@ RPC.prototype.sendMany = co(function* sendMany(args, help) {
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
value = valid.btc(key);
|
||||
address = Address.fromBase58(key, this.network);
|
||||
address = parseAddress(key, this.network);
|
||||
hash = address.getHash('hex');
|
||||
|
||||
if (value == null)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.');
|
||||
|
||||
if (uniq[hash])
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter.');
|
||||
|
||||
uniq[hash] = true;
|
||||
|
||||
@ -1403,16 +1434,15 @@ RPC.prototype.sendToAddress = co(function* sendToAddress(args, help) {
|
||||
var options, tx;
|
||||
|
||||
if (help || args.length < 2 || args.length > 5) {
|
||||
throw new RPCError('sendtoaddress'
|
||||
+ ' "bitcoinaddress" amount'
|
||||
+ ' ( "comment" "comment-to"'
|
||||
+ ' subtractfeefromamount )');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'sendtoaddress "bitcoinaddress" amount'
|
||||
+ ' ( "comment" "comment-to" subtractfeefromamount )');
|
||||
}
|
||||
|
||||
addr = Address.fromBase58(addr, this.network);
|
||||
addr = parseAddress(addr, this.network);
|
||||
|
||||
if (!addr || value == null)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
options = {
|
||||
subtractFee: subtractFee,
|
||||
@ -1429,8 +1459,10 @@ RPC.prototype.sendToAddress = co(function* sendToAddress(args, help) {
|
||||
});
|
||||
|
||||
RPC.prototype.setAccount = co(function* setAccount(args, help) {
|
||||
if (help || args.length < 1 || args.length > 2)
|
||||
throw new RPCError('setaccount "bitcoinaddress" "account"');
|
||||
if (help || args.length < 1 || args.length > 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'setaccount "bitcoinaddress" "account"');
|
||||
}
|
||||
|
||||
// Impossible to implement in bcoin:
|
||||
throw new Error('Not implemented.');
|
||||
@ -1441,10 +1473,10 @@ RPC.prototype.setTXFee = co(function* setTXFee(args, help) {
|
||||
var rate = valid.btc(0);
|
||||
|
||||
if (help || args.length < 1 || args.length > 1)
|
||||
throw new RPCError('settxfee amount');
|
||||
throw new RPCError(errs.MISC_ERROR, 'settxfee amount');
|
||||
|
||||
if (rate == null)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
this.feeRate = rate;
|
||||
|
||||
@ -1458,21 +1490,23 @@ RPC.prototype.signMessage = co(function* signMessage(args, help) {
|
||||
var msg = valid.str(1, '');
|
||||
var sig, ring;
|
||||
|
||||
if (help || args.length !== 2)
|
||||
throw new RPCError('signmessage "bitcoinaddress" "message"');
|
||||
if (help || args.length !== 2) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'signmessage "bitcoinaddress" "message"');
|
||||
}
|
||||
|
||||
addr = Address.getHash(addr, 'hex');
|
||||
|
||||
if (!addr)
|
||||
throw new RPCError('Invalid address.');
|
||||
throw new RPCError(errs.INVALID_ADDRESS_OR_KEY, 'Invalid address.');
|
||||
|
||||
ring = yield wallet.getKey(addr);
|
||||
|
||||
if (!ring)
|
||||
throw new RPCError('Address not found.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'Address not found.');
|
||||
|
||||
if (!wallet.master.key)
|
||||
throw new RPCError('Wallet is locked.');
|
||||
throw new RPCError(errs.WALLET_UNLOCK_NEEDED, 'Wallet is locked.');
|
||||
|
||||
msg = new Buffer(MAGIC_STRING + msg, 'utf8');
|
||||
msg = crypto.hash256(msg);
|
||||
@ -1486,10 +1520,10 @@ RPC.prototype.walletLock = co(function* walletLock(args, help) {
|
||||
var wallet = this.wallet;
|
||||
|
||||
if (help || (wallet.master.encrypted && args.length !== 0))
|
||||
throw new RPCError('walletlock');
|
||||
throw new RPCError(errs.MISC_ERROR, 'walletlock');
|
||||
|
||||
if (!wallet.master.encrypted)
|
||||
throw new RPCError('Wallet is not encrypted.');
|
||||
throw new RPCError(errs.WALLET_WRONG_ENC_STATE, 'Wallet is not encrypted.');
|
||||
|
||||
yield wallet.lock();
|
||||
|
||||
@ -1503,15 +1537,15 @@ RPC.prototype.walletPassphraseChange = co(function* walletPassphraseChange(args,
|
||||
var new_ = valid.str(1, '');
|
||||
|
||||
if (help || (wallet.master.encrypted && args.length !== 2)) {
|
||||
throw new RPCError('walletpassphrasechange'
|
||||
throw new RPCError(errs.MISC_ERROR, 'walletpassphrasechange'
|
||||
+ ' "oldpassphrase" "newpassphrase"');
|
||||
}
|
||||
|
||||
if (!wallet.master.encrypted)
|
||||
throw new RPCError('Wallet is not encrypted.');
|
||||
throw new RPCError(errs.WALLET_WRONG_ENC_STATE, 'Wallet is not encrypted.');
|
||||
|
||||
if (old.length < 1 || new_.length < 1)
|
||||
throw new RPCError('Invalid parameter');
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter');
|
||||
|
||||
yield wallet.setPassphrase(old, new_);
|
||||
|
||||
@ -1524,17 +1558,19 @@ RPC.prototype.walletPassphrase = co(function* walletPassphrase(args, help) {
|
||||
var passphrase = valid.str(0, '');
|
||||
var timeout = valid.u32(1);
|
||||
|
||||
if (help || (wallet.master.encrypted && args.length !== 2))
|
||||
throw new RPCError('walletpassphrase "passphrase" timeout');
|
||||
if (help || (wallet.master.encrypted && args.length !== 2)) {
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'walletpassphrase "passphrase" timeout');
|
||||
}
|
||||
|
||||
if (!wallet.master.encrypted)
|
||||
throw new RPCError('Wallet is not encrypted.');
|
||||
throw new RPCError(errs.WALLET_WRONG_ENC_STATE, 'Wallet is not encrypted.');
|
||||
|
||||
if (passphrase.length < 1)
|
||||
throw new RPCError('Invalid parameter');
|
||||
throw new RPCError(errs.INVALID_PARAMETER, 'Invalid parameter');
|
||||
|
||||
if (timeout == null)
|
||||
throw new RPCError('Invalid parameter');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter');
|
||||
|
||||
yield wallet.unlock(passphrase, timeout);
|
||||
|
||||
@ -1548,27 +1584,27 @@ RPC.prototype.importPrunedFunds = co(function* importPrunedFunds(args, help) {
|
||||
var hash, height;
|
||||
|
||||
if (help || args.length < 2 || args.length > 3) {
|
||||
throw new RPCError('importprunedfunds'
|
||||
+ ' "rawtransaction" "txoutproof" ( "label" )');
|
||||
throw new RPCError(errs.MISC_ERROR,
|
||||
'importprunedfunds "rawtransaction" "txoutproof" ( "label" )');
|
||||
}
|
||||
|
||||
if (!tx || !block)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
tx = TX.fromRaw(tx);
|
||||
block = MerkleBlock.fromRaw(block);
|
||||
tx = fromRaw(TX, tx);
|
||||
block = fromRaw(MerkleBlock, block);
|
||||
hash = block.hash('hex');
|
||||
|
||||
if (!block.verify())
|
||||
throw new RPCError('Invalid proof.');
|
||||
throw new RPCError(errs.VERIFY_ERROR, 'Invalid proof.');
|
||||
|
||||
if (!block.hasTX(tx.hash('hex')))
|
||||
throw new RPCError('Invalid proof.');
|
||||
throw new RPCError(errs.VERIFY_ERROR, 'Invalid proof.');
|
||||
|
||||
height = yield this.client.getEntry(hash);
|
||||
|
||||
if (height === -1)
|
||||
throw new RPCError('Invalid proof.');
|
||||
throw new RPCError(errs.VERIFY_ERROR, 'Invalid proof.');
|
||||
|
||||
block = {
|
||||
hash: hash,
|
||||
@ -1577,7 +1613,7 @@ RPC.prototype.importPrunedFunds = co(function* importPrunedFunds(args, help) {
|
||||
};
|
||||
|
||||
if (!(yield this.wdb.addTX(tx, block)))
|
||||
throw new RPCError('No tracked address for TX.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'No tracked address for TX.');
|
||||
|
||||
return null;
|
||||
});
|
||||
@ -1588,13 +1624,13 @@ RPC.prototype.removePrunedFunds = co(function* removePrunedFunds(args, help) {
|
||||
var hash = valid.hash(0);
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('removeprunedfunds "txid"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'removeprunedfunds "txid"');
|
||||
|
||||
if (!hash)
|
||||
throw new RPCError('Invalid parameter.');
|
||||
throw new RPCError(errs.TYPE_ERROR, 'Invalid parameter.');
|
||||
|
||||
if (!(yield wallet.remove(hash)))
|
||||
throw new RPCError('Transaction not in wallet.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'Transaction not in wallet.');
|
||||
|
||||
return null;
|
||||
});
|
||||
@ -1605,12 +1641,12 @@ RPC.prototype.selectWallet = co(function* selectWallet(args, help) {
|
||||
var wallet;
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('selectwallet "id"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'selectwallet "id"');
|
||||
|
||||
wallet = yield this.wdb.get(id);
|
||||
|
||||
if (!wallet)
|
||||
throw new RPCError('Wallet not found.');
|
||||
throw new RPCError(errs.WALLET_ERROR, 'Wallet not found.');
|
||||
|
||||
this.wallet = wallet;
|
||||
|
||||
@ -1619,7 +1655,7 @@ RPC.prototype.selectWallet = co(function* selectWallet(args, help) {
|
||||
|
||||
RPC.prototype.getMemoryInfo = co(function* getMemoryInfo(args, help) {
|
||||
if (help || args.length !== 0)
|
||||
throw new RPCError('getmemoryinfo');
|
||||
throw new RPCError(errs.MISC_ERROR, 'getmemoryinfo');
|
||||
|
||||
return util.memoryUsage();
|
||||
});
|
||||
@ -1629,13 +1665,41 @@ RPC.prototype.setLogLevel = co(function* setLogLevel(args, help) {
|
||||
var level = valid.str(0, '');
|
||||
|
||||
if (help || args.length !== 1)
|
||||
throw new RPCError('setloglevel "level"');
|
||||
throw new RPCError(errs.MISC_ERROR, 'setloglevel "level"');
|
||||
|
||||
this.logger.setLevel(level);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
/*
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function fromRaw(ctor, raw) {
|
||||
try {
|
||||
return ctor.fromRaw(raw);
|
||||
} catch (e) {
|
||||
throw new RPCError(errs.DESERIALIZATION_ERROR, 'Deserialization error.');
|
||||
}
|
||||
}
|
||||
|
||||
function parseAddress(raw, network) {
|
||||
try {
|
||||
return Address.fromBase58(raw, network);
|
||||
} catch (e) {
|
||||
throw new RPCError(errs.INVALID_ADDRESS_OR_KEY, 'Invalid address.');
|
||||
}
|
||||
}
|
||||
|
||||
function parseSecret(raw, network) {
|
||||
try {
|
||||
return KeyRing.fromSecret(raw, network);
|
||||
} catch (e) {
|
||||
throw new RPCError(errs.INVALID_ADDRESS_OR_KEY, 'Invalid key.');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user