fcoin/lib/http/wallet.js
2018-03-29 21:56:44 -07:00

592 lines
11 KiB
JavaScript

/*!
* wallet.js - http wallet for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
'use strict';
const assert = require('assert');
const {Client} = require('bcurl');
class HTTPWallet extends Client {
/**
* HTTPWallet
* @alias module:http.Wallet
* @constructor
* @param {String} uri
*/
constructor(options) {
super(options);
}
/**
* Open the client, wait for socket to connect.
* @returns {Promise}
*/
async init() {
await super.open();
this.listen('wallet tx', (details) => {
this.emit('tx', details);
});
this.listen('wallet confirmed', (details) => {
this.emit('confirmed', details);
});
this.listen('wallet unconfirmed', (details) => {
this.emit('unconfirmed', details);
});
this.listen('wallet conflict', (details) => {
this.emit('conflict', details);
});
this.listen('wallet updated', (details) => {
this.emit('updated', details);
});
this.listen('wallet address', (receive) => {
this.emit('address', receive);
});
this.listen('wallet balance', (balance) => {
this.emit('balance', balance);
});
}
/**
* Open the client and get a wallet.
* @returns {Promise}
*/
async open(options = {}) {
if (options.id != null) {
assert(typeof options.id === 'string');
this.id = options.id;
}
if (options.token != null) {
assert(typeof options.token === 'string');
this.token = options.token;
}
if (!this.id)
throw new Error('No ID provided.');
await this.init();
await this.call('wallet join', this.id, this.token);
}
/**
* Open the client and create a wallet.
* @returns {Promise}
*/
async create(options) {
const wallet = await this.createWallet(options);
assert(wallet);
assert(typeof wallet.id === 'string');
assert(typeof wallet.token === 'string');
this.id = wallet.id;
this.token = wallet.token;
await this.init();
await this.call('wallet join', this.id, this.token);
return wallet;
}
/**
* Auth with server.
* @returns {Promise}
*/
async auth() {
return this.call('wallet auth', this.password);
}
/**
* Make an RPC call.
* @returns {Promise}
*/
execute(name, params) {
return super.execute('/', name, params);
}
/**
* Rescan the chain.
* @param {Number} height
* @returns {Promise}
*/
rescan(height) {
return this.post('/wallet/_admin/rescan', { height });
}
/**
* Resend pending transactions.
* @returns {Promise}
*/
resend() {
return this.post('/wallet/_admin/resend');
}
/**
* Backup the walletdb.
* @param {String} path
* @returns {Promise}
*/
backup(path) {
return this.post('/wallet/_admin/backup', { path });
}
/**
* Get list of all wallet IDs.
* @returns {Promise}
*/
getWallets() {
return this.get('/wallet/_admin/wallets');
}
/**
* Create a wallet.
* @param {Object} options
* @returns {Promise}
*/
createWallet(options) {
assert(options.id, 'Must pass an id parameter');
return this.put(`/wallet/${options.id}`, options);
}
/**
* Get wallet transaction history.
* @returns {Promise}
*/
getHistory(account) {
return this.get(`/wallet/${this.id}/tx/history`, { account });
}
/**
* Get wallet coins.
* @returns {Promise}
*/
getCoins(account) {
return this.get(`/wallet/${this.id}/coin`, { account });
}
/**
* Get all unconfirmed transactions.
* @returns {Promise}
*/
getPending(account) {
return this.get(`/wallet/${this.id}/tx/unconfirmed`, { account });
}
/**
* Calculate wallet balance.
* @returns {Promise}
*/
getBalance(account) {
return this.get(`/wallet/${this.id}/balance`, { account });
}
/**
* Get last N wallet transactions.
* @param {Number} limit - Max number of transactions.
* @returns {Promise}
*/
getLast(account, limit) {
return this.get(`/wallet/${this.id}/tx/last`, { account, limit });
}
/**
* Get wallet transactions by timestamp range.
* @param {Object} options
* @param {Number} options.start - Start time.
* @param {Number} options.end - End time.
* @param {Number?} options.limit - Max number of records.
* @param {Boolean?} options.reverse - Reverse order.
* @returns {Promise}
*/
getRange(account, options) {
return this.get(`/wallet/${this.id}/tx/range`, {
account: account,
start: options.start,
end: options.end ,
limit: options.limit,
reverse: options.reverse
});
}
/**
* Get transaction (only possible if the transaction
* is available in the wallet history).
* @param {Hash} hash
* @returns {Promise}
*/
getTX(hash) {
return this.get(`/wallet/${this.id}/tx/${hash}`);
}
/**
* Get wallet blocks.
* @param {Number} height
* @returns {Promise}
*/
getBlocks() {
return this.get(`/wallet/${this.id}/block`);
}
/**
* Get wallet block.
* @param {Number} height
* @returns {Promise}
*/
getBlock(height) {
return this.get(`/wallet/${this.id}/block/${height}`);
}
/**
* Get unspent coin (only possible if the transaction
* is available in the wallet history).
* @param {Hash} hash
* @param {Number} index
* @returns {Promise}
*/
getCoin(hash, index) {
return this.get(`/wallet/${this.id}/coin/${hash}/${index}`);
}
/**
* @param {Number} now - Current time.
* @param {Number} age - Age delta (delete transactions older than `now - age`).
* @returns {Promise}
*/
zap(account, age) {
return this.post(`/wallet/${this.id}/zap`, { account, age });
}
/**
* Create a transaction, fill.
* @param {Object} options
* @returns {Promise}
*/
createTX(options) {
return this.post(`/wallet/${this.id}/create`, options);
}
/**
* Create a transaction, fill, sign, and broadcast.
* @param {Object} options
* @param {String} options.address
* @param {Amount} options.value
* @returns {Promise}
*/
send(options) {
return this.post(`/wallet/${this.id}/send`, options);
}
/**
* Sign a transaction.
* @param {Object} options
* @returns {Promise}
*/
sign(options) {
return this.post(`/wallet/${this.id}/sign`, options);
}
/**
* Get the raw wallet JSON.
* @returns {Promise}
*/
getInfo() {
return this.get(`/wallet/${this.id}`);
}
/**
* Get wallet accounts.
* @returns {Promise} - Returns Array.
*/
getAccounts() {
return this.get(`/wallet/${this.id}/account`);
}
/**
* Get wallet master key.
* @returns {Promise}
*/
getMaster() {
return this.get(`/wallet/${this.id}/master`);
}
/**
* Get wallet account.
* @param {String} account
* @returns {Promise}
*/
getAccount(account) {
return this.get(`/wallet/${this.id}/account/${account}`);
}
/**
* Create account.
* @param {String} name
* @param {Object} options
* @returns {Promise}
*/
createAccount(name, options) {
return this.put(`/wallet/${this.id}/account/${name}`, options);
}
/**
* Create address.
* @param {Object} options
* @returns {Promise}
*/
createAddress(account) {
return this.post(`/wallet/${this.id}/address`, { account });
}
/**
* Create change address.
* @param {Object} options
* @returns {Promise}
*/
createChange(account) {
return this.post(`/wallet/${this.id}/change`, { account });
}
/**
* Create nested address.
* @param {Object} options
* @returns {Promise}
*/
createNested(account) {
return this.post(`/wallet/${this.id}/nested`, { account });
}
/**
* Change or set master key's passphrase.
* @param {String|Buffer} passphrase
* @param {(String|Buffer)?} old
* @returns {Promise}
*/
setPassphrase(passphrase, old) {
return this.post(`/wallet/${this.id}/passphrase`, { passphrase, old });
}
/**
* Generate a new token.
* @param {(String|Buffer)?} passphrase
* @returns {Promise}
*/
async retoken(passphrase) {
const body = await this.post(`/wallet/${this.id}/retoken`, {
passphrase
});
assert(body);
assert(typeof body.token === 'string');
this.token = body.token;
return body.token;
}
/**
* Import private key.
* @param {Number|String} account
* @param {String} key
* @returns {Promise}
*/
importPrivate(account, privateKey, passphrase) {
return this.post(`/wallet/${this.id}/import`, {
account,
privateKey,
passphrase
});
}
/**
* Import public key.
* @param {Number|String} account
* @param {String} key
* @returns {Promise}
*/
importPublic(account, publicKey) {
return this.post(`/wallet/${this.id}/import`, {
account,
publicKey
});
}
/**
* Import address.
* @param {Number|String} account
* @param {String} address
* @returns {Promise}
*/
importAddress(account, address) {
return this.post(`/wallet/${this.id}/import`, { account, address });
}
/**
* Lock a coin.
* @param {String} hash
* @param {Number} index
* @returns {Promise}
*/
lockCoin(hash, index) {
return this.put(`/wallet/${this.id}/locked/${hash}/${index}`);
}
/**
* Unlock a coin.
* @param {String} hash
* @param {Number} index
* @returns {Promise}
*/
unlockCoin(hash, index) {
return this.del(`/wallet/${this.id}/locked/${hash}/${index}`);
}
/**
* Get locked coins.
* @returns {Promise}
*/
getLocked() {
return this.get(`/wallet/${this.id}/locked`);
}
/**
* Lock wallet.
* @returns {Promise}
*/
lock() {
return this.post(`/wallet/${this.id}/lock`);
}
/**
* Unlock wallet.
* @param {String} passphrase
* @param {Number} timeout
* @returns {Promise}
*/
unlock(passphrase, timeout) {
return this.post(`/wallet/${this.id}/unlock`, {
passphrase,
timeout
});
}
/**
* Get wallet key.
* @param {String} address
* @returns {Promise}
*/
getKey(address) {
return this.get(`/wallet/${this.id}/key/${address}`);
}
/**
* Get wallet key WIF dump.
* @param {String} address
* @param {String?} passphrase
* @returns {Promise}
*/
getWIF(address, passphrase) {
return this.get(`/wallet/${this.id}/wif/${address}`, { passphrase });
}
/**
* Add a public account/purpose key to the wallet for multisig.
* @param {(String|Number)?} account
* @param {Base58String} key - Account (bip44) or
* Purpose (bip45) key (can be in base58 form).
* @returns {Promise}
*/
addSharedKey(account, accountKey) {
return this.put(`/wallet/${this.id}/shared-key`, {
account,
accountKey
});
}
/**
* Remove a public account/purpose key to the wallet for multisig.
* @param {(String|Number)?} account
* @param {Base58String} key - Account (bip44) or Purpose
* (bip45) key (can be in base58 form).
* @returns {Promise}
*/
removeSharedKey(account, accountKey) {
return this.del(`/wallet/${this.id}/shared-key`, {
account,
accountKey
});
}
/**
* Resend wallet transactions.
* @returns {Promise}
*/
resend() {
return this.post(`/wallet/${this.id}/resend`);
}
}
/*
* Expose
*/
module.exports = HTTPWallet;