Skip to content

Commit

Permalink
wallet config uses MoneroRpcConnection for server model
Browse files Browse the repository at this point in the history
  • Loading branch information
woodser committed Sep 1, 2023
1 parent 5579cd2 commit d09260d
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 28 deletions.
4 changes: 2 additions & 2 deletions index.js
Expand Up @@ -205,11 +205,11 @@ module.exports.connectToWalletRpc = function() { return module.exports.MoneroWal
* @param {string} config.language - language of the wallet's seed (defaults to "English" or auto-detected)
* @param {number} config.accountLookahead - number of accounts to scan (optional)
* @param {number} config.subaddressLookahead - number of subaddresses to scan per account (optional)
* @param {MoneroRpcConnection|object} config.server - MoneroRpcConnection or equivalent JS object providing daemon configuration (optional)
* @param {string} config.serverUri - uri of the wallet's daemon (optional)
* @param {string} config.serverUsername - username to authenticate with the daemon (optional)
* @param {string} config.serverPassword - password to authenticate with the daemon (optional)
* @param {boolean} config.rejectUnauthorized - reject self-signed server certificates if true (defaults to true)
* @param {MoneroRpcConnection|object} config.server - MoneroRpcConnection or equivalent JS object providing daemon configuration (optional)
* @param {boolean} config.proxyToWorker - proxies wallet operations to a web worker in order to not block the main thread (default true)
* @param {fs} config.fs - Node.js compatible file system to use (defaults to disk or in-memory FS if browser)
* @return {MoneroWalletFull} the created wallet
Expand Down Expand Up @@ -245,11 +245,11 @@ module.exports.createWalletFull = function() { return module.exports.MoneroWalle
* @param {string|number} configOrPath.networkType - network type of the wallet to open (one of "mainnet", "testnet", "stagenet" or MoneroNetworkType.MAINNET|TESTNET|STAGENET)
* @param {Uint8Array} configOrPath.keysData - wallet keys data to open (optional if path provided)
* @param {Uint8Array} configOrPath.cacheData - wallet cache data to open (optional)
* @param {MoneroRpcConnection|object} configOrPath.server - MoneroRpcConnection or equivalent JS object configuring the daemon connection (optional)
* @param {string} configOrPath.serverUri - uri of the wallet's daemon (optional)
* @param {string} configOrPath.serverUsername - username to authenticate with the daemon (optional)
* @param {string} configOrPath.serverPassword - password to authenticate with the daemon (optional)
* @param {boolean} configOrPath.rejectUnauthorized - reject self-signed server certificates if true (defaults to true)
* @param {MoneroRpcConnection|object} configOrPath.server - MoneroRpcConnection or equivalent JS object configuring the daemon connection (optional)
* @param {boolean} configOrPath.proxyToWorker - proxies wallet operations to a web worker in order to not block the main thread (default true)
* @param {fs} configOrPath.fs - Node.js compatible file system to use (defaults to disk or in-memory FS if browser)
* @param {string} password - password of the wallet to open
Expand Down
13 changes: 13 additions & 0 deletions src/main/js/common/GenUtils.js
Expand Up @@ -1510,6 +1510,19 @@ class GenUtils {
}
});
}

/**
* Normalize a URI.
*
* @param {string} uri - the URI to normalize
* @return {string} the normalized URI
*/
static normalizeUri(uri) {
if (!uri) throw Error("Must provide URI to normalize");
uri = uri.replace(/\/$/, ""); // strip trailing slash
if (!new RegExp("^\\w+://.+").test(uri)) uri= "http://" + uri; // assume http if protocol not given
return uri;
}
}

module.exports = GenUtils;
9 changes: 5 additions & 4 deletions src/main/js/common/MoneroRpcConnection.js
Expand Up @@ -58,10 +58,7 @@ class MoneroRpcConnection {
this._config = Object.assign({}, MoneroRpcConnection.DEFAULT_CONFIG, this._config);

// normalize uri
if (this._config.uri) {
this._config.uri = this._config.uri.replace(/\/$/, ""); // strip trailing slash
if (!new RegExp("^\\w+://.+").test(this._config.uri)) this._config.uri = "http://" + this._config.uri; // assume http if protocol not given
}
if (this._config.uri) this._config.uri = GenUtils.normalizeUri(this._config.uri);

// fail with friendly message if using old api
if (this._config.user || this._config.pass) throw new MoneroError("Authentication fields 'user' and 'pass' have been renamed to 'username' and 'password'. Please update to the new api");
Expand Down Expand Up @@ -368,6 +365,10 @@ class MoneroRpcConnection {
else throw new MoneroRpcError(err, err.statusCode, path, params);
}
}

toJson() {
return this._config;
}

toString() {
return this.getUri() + " (username=" + this.getUsername() + ", password=" + (this.getPassword() ? "***" : this.getPassword()) + ", priority=" + this.getPriority() + ", isOnline=" + this.isOnline() + ", isAuthenticated=" + this.isAuthenticated() + ")";
Expand Down
4 changes: 2 additions & 2 deletions src/main/js/wallet/MoneroWalletFull.js
Expand Up @@ -87,11 +87,11 @@ class MoneroWalletFull extends MoneroWalletKeys {
* @param {string|number} configOrPath.networkType - network type of the wallet to open (one of "mainnet", "testnet", "stagenet" or MoneroNetworkType.MAINNET|TESTNET|STAGENET)
* @param {Uint8Array} configOrPath.keysData - wallet keys data to open (optional if path provided)
* @param {Uint8Array} configOrPath.cacheData - wallet cache data to open (optional)
* @param {MoneroRpcConnection|object} configOrPath.server - MoneroRpcConnection or equivalent JS object configuring the daemon connection (optional)
* @param {string} configOrPath.serverUri - uri of the wallet's daemon (optional)
* @param {string} configOrPath.serverUsername - username to authenticate with the daemon (optional)
* @param {string} configOrPath.serverPassword - password to authenticate with the daemon (optional)
* @param {boolean} configOrPath.rejectUnauthorized - reject self-signed server certificates if true (default true)
* @param {MoneroRpcConnection|object} configOrPath.server - MoneroRpcConnection or equivalent JS object configuring the daemon connection (optional)
* @param {boolean} configOrPath.proxyToWorker - proxies wallet operations to a worker in order to not block the main thread (default true)
* @param {fs} configOrPath.fs - Node.js compatible file system to use (defaults to disk or in-memory FS if browser)
* @param {string} password - password of the wallet to open
Expand Down Expand Up @@ -166,11 +166,11 @@ class MoneroWalletFull extends MoneroWalletKeys {
* @param {string} config.language - language of the wallet's seed phrase (defaults to "English" or auto-detected)
* @param {number} config.accountLookahead - number of accounts to scan (optional)
* @param {number} config.subaddressLookahead - number of subaddresses to scan per account (optional)
* @param {MoneroRpcConnection|object} config.server - MoneroRpcConnection or equivalent JS object providing daemon configuration (optional)
* @param {string} config.serverUri - uri of the wallet's daemon (optional)
* @param {string} config.serverUsername - username to authenticate with the daemon (optional)
* @param {string} config.serverPassword - password to authenticate with the daemon (optional)
* @param {boolean} config.rejectUnauthorized - reject self-signed server certificates if true (defaults to true)
* @param {MoneroRpcConnection|object} config.server - MoneroRpcConnection or equivalent JS object providing daemon configuration (optional)
* @param {boolean} config.proxyToWorker - proxies wallet operations to a worker in order to not block the main thread (default true)
* @param {fs} config.fs - Node.js compatible file system to use (defaults to disk or in-memory FS if browser)
* @return {MoneroWalletFull} the created wallet
Expand Down
29 changes: 19 additions & 10 deletions src/main/js/wallet/model/MoneroWalletConfig.js
Expand Up @@ -25,11 +25,11 @@ class MoneroWalletConfig {
* @param {string} config.language - language of the wallet's seed phrase (defaults to "English" or auto-detected)
* @param {number} config.accountLookahead - number of accounts to scan (optional)
* @param {number} config.subaddressLookahead - number of subaddresses to scan per account (optional)
* @param {MoneroRpcConnection|object} config.server - MoneroRpcConnection or equivalent JS object configuring the server connection (optional)
* @param {string} config.serverUri - uri of the wallet's server (optional)
* @param {string} config.serverUsername - username of the wallet's server (optional)
* @param {string} config.serverPassword - password of the wallet's server (optional)
* @param {boolean} config.rejectUnauthorized - reject self-signed server certificates if true (default true)
* @param {MoneroRpcConnection|object} config.server - MoneroRpcConnection or equivalent JS object configuring the server connection (optional)
* @param {Uint8Array} config.keysData - wallet keys data to open (optional)
* @param {Uint8Array} config.cacheData - wallet cache data to open (optional)
* @param {boolean} config.proxyToWorker - proxies wallet operations to a worker in order to not block the main thread (default true)
Expand All @@ -50,7 +50,12 @@ class MoneroWalletConfig {
// normalize config
this.setNetworkType(config.networkType);
if (config.server) this.setServer(config.server);
delete this.config.server;
else if (config.serverUri) this.setServer({uri: config.serverUri, username: config.serverUsername, password: config.serverPassword, rejectUnauthorized: config.rejectUnauthorized});
this.setProxyToWorker(config.proxyToWorker);
this.config.serverUri = undefined;
this.config.serverUsername = undefined;
this.config.serverPassword = undefined;
this.config.rejectUnauthorized = undefined;

// check for unsupported fields
for (let key of Object.keys(this.config)) {
Expand All @@ -66,6 +71,7 @@ class MoneroWalletConfig {

toJson() {
let json = Object.assign({}, this.config);
if (json.server) json.server = json.server.toJson();
json.fs = undefined; // remove filesystem
return json;
}
Expand Down Expand Up @@ -98,42 +104,44 @@ class MoneroWalletConfig {
}

getServer() {
return !this.config.serverUri ? undefined : new MoneroRpcConnection({uri: this.config.serverUri, username: this.config.serverUsername, password: this.config.serverPassword, rejectUnauthorized: this.config.rejectUnauthorized})
return this.config.server;
}

setServer(server) {
if (server && !(server instanceof MoneroRpcConnection)) server = new MoneroRpcConnection(server);
this.config.serverUri = server === undefined ? undefined : server.getUri();
this.config.server = server;
this.config.serverUsername = server === undefined ? undefined : server.getUsername();
this.config.serverPassword = server === undefined ? undefined : server.getPassword();
this.config.rejectUnauthorized = server === undefined ? undefined : server.getRejectUnauthorized();
return this;
}

getServerUri() {
return this.config.serverUri;
return this.config.server ? this.config.server.getUri() : undefined;
}

setServerUri(serverUri) {
this.config.serverUri = serverUri;
if (!this.config.server) this.setServer(new MoneroRpcConnection(serverUri));
else this.config.server.setUri(serverUri);
return this;
}

getServerUsername() {
return this.config.serverUsername;
return this.server ? server.getUsername() : undefined;
}

setServerUsername(serverUsername) {
this.config.serverUsername = serverUsername;
if (this.config.serverUsername && this.config.serverPassword) this.config.server.setCredentials(this.config.serverUsername, this.config.serverPassword);
return this;
}

getServerPassword() {
return this.config.serverPassword;
return this.server ? server.getPassword() : undefined;
}

setServerPassword(serverPassword) {
this.config.serverPassword = serverPassword;
if (this.config.serverUsername && this.config.serverPassword) this.config.server.setCredentials(this.config.serverUsername, this.config.serverPassword);
return this;
}

Expand Down Expand Up @@ -233,6 +241,7 @@ class MoneroWalletConfig {

setProxyToWorker(proxyToWorker) {
this.config.proxyToWorker = proxyToWorker;
if (this.config.server) this.config.server.setProxyToWorker(proxyToWorker);
return this;
}

Expand Down Expand Up @@ -282,6 +291,6 @@ class MoneroWalletConfig {
}
}

MoneroWalletConfig.SUPPORTED_FIELDS = ["path", "password", "networkType", "serverUri", "serverUsername", "serverPassword", "rejectUnauthorized", "seed", "seedOffset", "isMultisig", "primaryAddress", "privateViewKey", "privateSpendKey", "restoreHeight", "language", "saveCurrent", "proxyToWorker", "fs", "keysData", "cacheData", "accountLookahead", "subaddressLookahead"];
MoneroWalletConfig.SUPPORTED_FIELDS = ["path", "password", "networkType", "server", "serverUri", "serverUsername", "serverPassword", "rejectUnauthorized", "seed", "seedOffset", "isMultisig", "primaryAddress", "privateViewKey", "privateSpendKey", "restoreHeight", "language", "saveCurrent", "proxyToWorker", "fs", "keysData", "cacheData", "accountLookahead", "subaddressLookahead"];

module.exports = MoneroWalletConfig;
13 changes: 4 additions & 9 deletions src/test/TestMoneroWalletCommon.js
Expand Up @@ -422,14 +422,9 @@ class TestMoneroWalletCommon {
try {

// create random wallet with default daemon connection
wallet = await that.createWallet({serverUri: ""});
if (wallet instanceof MoneroWalletRpc) {
assert.deepEqual(await wallet.getDaemonConnection(), new MoneroRpcConnection(TestUtils.DAEMON_RPC_CONFIG));
assert.equal(await wallet.isConnectedToDaemon(), true);
} else {
assert.equal(await wallet.getDaemonConnection(), undefined);
assert(!await wallet.isConnectedToDaemon());
}
wallet = await that.createWallet();
assert.deepEqual(await wallet.getDaemonConnection(), new MoneroRpcConnection(TestUtils.DAEMON_RPC_CONFIG));
assert.equal(await wallet.isConnectedToDaemon(), true);

// set empty server uri
await wallet.setDaemonConnection("");
Expand Down Expand Up @@ -3610,7 +3605,7 @@ class TestMoneroWalletCommon {
assert(txs.length > 0);
let feeSum = new BigInteger(0);
let outgoingSum = new BigInteger(0);
that._testTxsWallet(txs, ctx);
await that._testTxsWallet(txs, ctx);
for (let tx of txs) {
feeSum = feeSum.add(tx.getFee());
outgoingSum = outgoingSum.add(tx.getOutgoingAmount());
Expand Down
2 changes: 1 addition & 1 deletion src/test/TestMoneroWalletRpc.js
Expand Up @@ -87,7 +87,7 @@ class TestMoneroWalletRpc extends TestMoneroWalletCommon {
if (!config.getServer()) config.setServer(await this.daemon.getRpcConnection());

// create client connected to internal monero-wallet-rpc executable
let offline = TestUtils.OFFLINE_SERVER_URI === config.getServerUri();
let offline = config.getServerUri() === GenUtils.normalizeUri(TestUtils.OFFLINE_SERVER_URI);
let wallet = await TestUtils.startWalletRpcProcess(offline);

// create wallet
Expand Down
2 changes: 2 additions & 0 deletions src/test/utils/TestUtils.js
Expand Up @@ -172,11 +172,13 @@ class TestUtils {
// create wallet with connection
TestUtils.walletFull = await monerojs.createWalletFull({path: TestUtils.WALLET_FULL_PATH, password: TestUtils.WALLET_PASSWORD, networkType: TestUtils.NETWORK_TYPE, seed: TestUtils.SEED, server: TestUtils.getDaemonRpcConnection(), restoreHeight: TestUtils.FIRST_RECEIVE_HEIGHT, proxyToWorker: TestUtils.PROXY_TO_WORKER, fs: fs});
assert.equal(await TestUtils.walletFull.getRestoreHeight(), TestUtils.FIRST_RECEIVE_HEIGHT);
assert.deepEqual(await TestUtils.walletFull.getDaemonConnection(), TestUtils.getDaemonRpcConnection());
}

// otherwise open existing wallet
else {
TestUtils.walletFull = await monerojs.openWalletFull({path: TestUtils.WALLET_FULL_PATH, password: TestUtils.WALLET_PASSWORD, networkType: TestUtils.NETWORK_TYPE, server: TestUtils.getDaemonRpcConnection(), proxyToWorker: TestUtils.PROXY_TO_WORKER, fs: TestUtils.getDefaultFs()});
await TestUtils.walletFull.setDaemonConnection(TestUtils.getDaemonRpcConnection());
}
}

Expand Down

0 comments on commit d09260d

Please sign in to comment.