wallet-http: modify account lookahead.

This commit is contained in:
Nodari Chkuaselidze 2023-01-17 16:13:12 +04:00
parent 2664a7ed4c
commit 49cf96a9c3
No known key found for this signature in database
GPG key ID: B018A7BB437D1F05
7 changed files with 142 additions and 55 deletions

View file

@ -6,17 +6,21 @@
Validation and request paremeter errors will no longer return (and log) `500`
status code, instead will return `400`.
### Wallet configuration
`hsd.conf` can now be used to define wallet options, when wallet is running as a plugin.
Configurations with `wallet-` prefix will be passed to the wallet. `hsd.conf` wont be used
if the wallet is running in standalone mode.
### Wallet Changes
#### Configuration
`hsd.conf` can now be used to define wallet options, when wallet is running as
a plugin. Configurations with `wallet-` prefix will be passed to the wallet.
`hsd.conf` wont be used if the wallet is running in standalone mode.
### Wallet API
- Remove `check-lookahead` option from walletdb.
#### Wallet API
- HTTP Changes:
- `/wallet/:id/open` no longer accepts `force` flag. (it was not used)
- RPC Changes:
- `createopen` and `sendopen` no longer accept `force` as an argument. (was not used)
- Introduce new API to modify account: `PATCH /wallet/:id/account/:account`.
## v5.0.0
@ -28,10 +32,10 @@ you run it for the first time.**
- HTTP API endpoint `/` (`hsd-cli getinfo`) now includes "public" networking settings.
- RPCs `getnameinfo` `getnameresource` `verifymessagewithname` and `getnamebyhash`
now accept an additional boolean parameter `safe` which will resolve the name from the Urkel
tree at the last "safe height" (committed tree root with > 12 confirmations). SPV
nodes can use this option and retrieve Urkel proofs from the p2p network to respond
to these calls.
now accept an additional boolean parameter `safe` which will resolve the name
from the Urkel tree at the last "safe height" (committed tree root with > 12
confirmations). SPV nodes can use this option and retrieve Urkel proofs from the
p2p network to respond to these calls.
- New RPC methods:
- `decoderesource` like `decodescript` accepts hex string as input and returns
@ -47,13 +51,15 @@ to these calls.
of outputs with any combination of covenants.
- Updates related to nonces and blinds
- Multisig wallets will compute nonces based on the LOWEST public key in the group.
This makes multiparty bidding and revealing more deteministic. Older versions would
always use the wallet's OWN public key. To preserve compatability with older software:
- RPC method `importnonce` now returns an array of blinds instead of a single blind.
- HTTP endpoint `/wallet/:id/nonce/:name`'s response replaces 2 string fields (`nonce`, `blind`) with arrays of the same type (`nonces`, `blinds`)
- Remove `check-lookahead` option from walletdb.
- Multisig wallets will compute nonces based on the LOWEST public key in the
group.
This makes multiparty bidding and revealing more deteministic. Older versions
would always use the wallet's OWN public key. To preserve compatability with
older software:
- RPC method `importnonce` now returns an array of blinds instead of a
single blind.
- HTTP endpoint `/wallet/:id/nonce/:name`'s response replaces 2 string
fields (`nonce`, `blind`) with arrays of the same type (`nonces`, `blinds`)
## v4.0.0

View file

@ -21,6 +21,7 @@ const HELP = `
Commands:
$ abandon [hash]: Abandon a transaction.
$ account create [account-name]: Create account.
$ account modify [account-name]: Set account options.
$ account get [account-name]: Get account details.
$ account list: List account names.
$ address [account-name]: Derive new address.
@ -233,6 +234,18 @@ class CLI {
this.log(account);
}
async modifyAccount() {
const name = this.config.str([0, 'name']);
const options = {
lookahead: this.config.uint('lookahead')
};
const account = await this.wallet.modifyAccount(name, options);
this.log(account);
}
async createAddress() {
const account = this.config.str([0, 'account']);
const addr = await this.wallet.createAddress(account);
@ -579,6 +592,11 @@ class CLI {
await this.createAccount();
break;
}
if (this.argv[0] === 'modify') {
this.argv.shift();
await this.modifyAccount();
break;
}
if (this.argv[0] === 'get')
this.argv.shift();
await this.getAccount();

View file

@ -682,9 +682,24 @@ class WalletClient extends Client {
*/
createAccount(id, name, options) {
if (name == null)
throw new Error('Account name is required.');
return this.put(`/wallet/${id}/account/${name}`, options);
}
/**
* Modify account.
* @param {String} id
* @param {String} name
* @param {Object} options
* @returns {Promise<Object>}
*/
modifyAccount(id, name, options) {
return this.patch(`/wallet/${id}/account/${name}`, options);
}
/**
* Create address.
* @param {Object} options
@ -1363,12 +1378,20 @@ class Wallet extends EventEmitter {
*/
createAccount(name, options) {
if (name == null)
throw new Error('Account name is required.');
return this.client.createAccount(this.id, name, options);
}
/**
* Modify account.
* @param {String} name
* @param {Object} options
* @returns {Promise<Object>}
*/
modifyAccount(name, options) {
return this.client.modifyAccount(this.id, name, options);
}
/**
* Create address.
* @param {Object} options

View file

@ -563,6 +563,8 @@ class Account extends bio.Struct {
*/
async setLookahead(b, lookahead) {
assert((lookahead >>> 0) === lookahead, 'Lookahead must be a number.');
if (lookahead === this.lookahead)
return;

View file

@ -362,6 +362,22 @@ class HTTP extends Server {
res.json(200, account.getJSON(balance));
});
// Modify account
this.patch('/wallet/:id/account/:account', async (req, res) => {
const valid = Validator.fromRequest(req);
const passphrase = valid.str('passphrase');
const acct = valid.str('account');
const options = {
lookahead: valid.u32('lookahead')
};
const account = await req.wallet.modifyAccount(acct, options, passphrase);
const balance = await req.wallet.getBalance(account.accountIndex);
res.json(200, account.getJSON(balance));
});
// Change passphrase
this.post('/wallet/:id/passphrase', async (req, res) => {
const valid = Validator.fromRequest(req);

View file

@ -659,6 +659,50 @@ class Wallet extends EventEmitter {
return account;
}
/**
* Modify an account. Requires passphrase if master key is encrypted.
* @param {String|Number} acct
* @param {Object} options
* @param {String} [passphrase]
* @returns {Promise<Account>}
*/
async modifyAccount(acct, options, passphrase) {
const unlock = await this.writeLock.lock();
try {
return await this._modifyAccount(acct, options, passphrase);
} finally {
unlock();
}
}
/**
* Create an account without a lock.
* @param {String|Number} acct
* @param {Object} options
* @param {String} [passphrase]
* @returns {Promise<Account>}
*/
async _modifyAccount(acct, options, passphrase) {
if (!await this.hasAccount(acct))
throw new Error(`Account ${acct} does not exist.`);
await this.unlock(passphrase);
const account = await this.getAccount(acct);
assert(account);
const b = this.db.batch();
if (options.lookahead != null)
await account.setLookahead(b, options.lookahead);
await b.write();
return account;
}
/**
* Ensure an account. Requires passphrase if master key is encrypted.
* @param {Object} options - See {@link Account} options.
@ -714,7 +758,7 @@ class Wallet extends EventEmitter {
/**
* Retrieve an account from the database.
* @param {Number|String} acct
* @returns {Promise} - Returns {@link Account}.
* @returns {Promise<Account>}
*/
async getAccount(acct) {
@ -4328,41 +4372,6 @@ class Wallet extends EventEmitter {
return paths;
}
/**
* Increase lookahead for account.
* @param {(Number|String)?} account
* @param {Number} lookahead
* @returns {Promise}
*/
async setLookahead(acct, lookahead) {
const unlock = await this.writeLock.lock();
try {
return this._setLookahead(acct, lookahead);
} finally {
unlock();
}
}
/**
* Increase lookahead for account (without a lock).
* @private
* @param {(Number|String)?} account
* @param {Number} lookahead
* @returns {Promise}
*/
async _setLookahead(acct, lookahead) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
const b = this.db.batch();
await account.setLookahead(b, lookahead);
await b.write();
}
/**
* Sync address depths based on a transaction's outputs.
* This is used for deriving new addresses when

View file

@ -124,6 +124,19 @@ describe('Wallet HTTP', function() {
assert.strictEqual(getNewAccount.lookahead, 1001);
});
it('should modify account lookahead to 1000', async () => {
const wname = 'lookahead2';
await wclient.createWallet(wname);
const defAccount = await wclient.getAccount(wname, 'default');
assert.strictEqual(defAccount.lookahead, 200);
const modified = await wclient.modifyAccount(wname, 'default', {
lookahead: 1000
});
assert.strictEqual(modified.lookahead, 1000);
});
it('should get key by address from watch-only', async () => {
const phrase = 'abandon abandon abandon abandon abandon abandon '
+ 'abandon abandon abandon abandon abandon about';