diff --git a/docs/api.md b/docs/api.md
index 649903cfa..40231ec6b 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -11,6 +11,8 @@
- [BanRequest](#xudrpc.BanRequest)
- [BanResponse](#xudrpc.BanResponse)
- [Chain](#xudrpc.Chain)
+ - [ChangePasswordRequest](#xudrpc.ChangePasswordRequest)
+ - [ChangePasswordResponse](#xudrpc.ChangePasswordResponse)
- [Channels](#xudrpc.Channels)
- [CloseChannelRequest](#xudrpc.CloseChannelRequest)
- [CloseChannelResponse](#xudrpc.CloseChannelResponse)
@@ -210,6 +212,32 @@
+
+
+### ChangePasswordRequest
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| new_password | [string](#string) | | |
+| old_password | [string](#string) | | |
+
+
+
+
+
+
+
+
+### ChangePasswordResponse
+
+
+
+
+
+
+
### Channels
@@ -1577,6 +1605,7 @@ The primary service for interacting with a running xud node.
| AddCurrency | [Currency](#xudrpc.Currency) | [AddCurrencyResponse](#xudrpc.AddCurrencyResponse) | Adds a currency to the list of supported currencies. Once added, the currency may be used for new trading pairs. shell: xucli addcurrency <currency> <swap_client> [decimal_places] [token_address] |
| AddPair | [AddPairRequest](#xudrpc.AddPairRequest) | [AddPairResponse](#xudrpc.AddPairResponse) | Adds a trading pair to the list of supported trading pairs. The newly supported pair is advertised to peers so they may begin sending orders for it. shell: xucli addpair <base_currency> <quote_currency> |
| Ban | [BanRequest](#xudrpc.BanRequest) | [BanResponse](#xudrpc.BanResponse) | Bans a node and immediately disconnects from it. This can be used to prevent any connections to a specific node. shell: xucli ban <node_identifier> |
+| ChangePassword | [ChangePasswordRequest](#xudrpc.ChangePasswordRequest) | [ChangePasswordResponse](#xudrpc.ChangePasswordResponse) | Changes the xud master password, including the wallet passwords for any underlying clients. shell: xucli changepass |
| CloseChannel | [CloseChannelRequest](#xudrpc.CloseChannelRequest) | [CloseChannelResponse](#xudrpc.CloseChannelResponse) | Closes any existing payment channels with a peer for the specified currency. shell: xucli closechannel <currency> [node_identifier ] [--force] |
| Connect | [ConnectRequest](#xudrpc.ConnectRequest) | [ConnectResponse](#xudrpc.ConnectResponse) | Attempts to connect to a node. Once connected, the node is added to the list of peers and becomes available for swaps and trading. A handshake exchanges information about the peer's supported trading and swap clients. Orders will be shared with the peer upon connection and upon new order placements. shell: xucli connect <node_uri> |
| WalletDeposit | [DepositRequest](#xudrpc.DepositRequest) | [DepositResponse](#xudrpc.DepositResponse) | Gets an address to deposit a given currency into the xud wallets. shell: xucli walletdeposit <currency> |
diff --git a/lib/Xud.ts b/lib/Xud.ts
index 9a206ce3e..490e252c0 100644
--- a/lib/Xud.ts
+++ b/lib/Xud.ts
@@ -119,16 +119,16 @@ class Xud extends EventEmitter {
const nodeKeyPath = NodeKey.getPath(this.config.xudir, this.config.instanceid);
const nodeKeyExists = await fs.access(nodeKeyPath).then(() => true).catch(() => false);
- this.swapClientManager = new SwapClientManager(this.config, loggers, this.unitConverter);
- await this.swapClientManager.init(this.db.models);
+ this.swapClientManager = new SwapClientManager(this.config, loggers, this.unitConverter, this.db.models);
+ await this.swapClientManager.init();
let nodeKey: NodeKey | undefined;
if (this.config.noencrypt) {
if (nodeKeyExists) {
nodeKey = await NodeKey.fromFile(nodeKeyPath);
} else {
- nodeKey = await NodeKey.generate();
- await nodeKey.toFile(nodeKeyPath);
+ nodeKey = await NodeKey.generate(nodeKeyPath);
+ await nodeKey.toFile();
}
// we need to initialize connext every time xud starts, even in noencrypt mode
diff --git a/lib/cli/command.ts b/lib/cli/command.ts
index 1e2af8141..ce85b7ea3 100644
--- a/lib/cli/command.ts
+++ b/lib/cli/command.ts
@@ -99,16 +99,16 @@ export const callback = (argv: Arguments, formatOutput?: Function, displayJson?:
}
} else {
const responseObj = response.toObject();
- if (Object.keys(responseObj).length === 0) {
- console.log('success');
- } else {
- if (!argv.json && formatOutput) {
- formatOutput(responseObj, argv);
+ if (argv.json || !formatOutput) {
+ if (Object.keys(responseObj).length === 0) {
+ console.log('success');
} else {
displayJson
- ? displayJson(responseObj, argv)
- : console.log(JSON.stringify(responseObj, undefined, 2));
+ ? displayJson(responseObj, argv)
+ : console.log(JSON.stringify(responseObj, undefined, 2));
}
+ } else {
+ formatOutput(responseObj, argv);
}
}
};
diff --git a/lib/cli/commands/changepass.ts b/lib/cli/commands/changepass.ts
new file mode 100644
index 000000000..cd563c35b
--- /dev/null
+++ b/lib/cli/commands/changepass.ts
@@ -0,0 +1,51 @@
+import readline from 'readline';
+import { Arguments } from 'yargs';
+import { ChangePasswordRequest } from '../../proto/xudrpc_pb';
+import { callback, loadXudClient } from '../command';
+
+export const command = 'changepass';
+
+export const describe = 'change the password for an existing xud instance';
+
+export const builder = {};
+
+const formatOutput = () => {
+ console.log('The master xud password was succesfully changed.');
+ console.log('Passwords for lnd wallets will be changed the next time xud is restarted and unlocked.');
+};
+
+export const handler = (argv: Arguments) => {
+ const rl = readline.createInterface({
+ input: process.stdin,
+ terminal: true,
+ });
+
+ console.log(`\
+You are changing the master password for xud and underlying wallets.\
+`);
+ process.stdout.write('Enter old password: ');
+ rl.question('', (oldPassword) => {
+ process.stdout.write('\nEnter new password: ');
+ rl.question('', (password1) => {
+ process.stdout.write('\nRe-enter password: ');
+ rl.question('', async (password2) => {
+ process.stdout.write('\n\n');
+ rl.close();
+ if (password1 === password2) {
+ const request = new ChangePasswordRequest();
+ request.setNewPassword(password1);
+ request.setOldPassword(oldPassword);
+
+ const client = await loadXudClient(argv);
+ // wait up to 3 seconds for rpc server to listen before call in case xud was just started
+ client.waitForReady(Date.now() + 3000, () => {
+ client.changePassword(request, callback(argv, formatOutput));
+ });
+ } else {
+ process.exitCode = 1;
+ console.error('Passwords do not match, please try again');
+ }
+ });
+ });
+ });
+};
diff --git a/lib/db/DB.ts b/lib/db/DB.ts
index 52f1a7ffa..e3a4273ef 100644
--- a/lib/db/DB.ts
+++ b/lib/db/DB.ts
@@ -1,8 +1,11 @@
-import { derivePairId } from '../utils/utils';
+import assert from 'assert';
+import { promises as fs } from 'fs';
import { ModelCtor, Sequelize } from 'sequelize';
import { XuNetwork } from '../constants/enums';
import { defaultCurrencies, defaultNodes, defaultPairs } from '../db/seeds';
import Logger from '../Logger';
+import { derivePairId } from '../utils/utils';
+import migrations from './migrations';
import * as Models from './models';
import * as db from './types';
@@ -14,6 +17,7 @@ type Models = {
ReputationEvent: ModelCtor;
Order: ModelCtor;
Trade: ModelCtor;
+ Password: ModelCtor;
};
function loadModels(sequelize: Sequelize): Models {
@@ -25,6 +29,7 @@ function loadModels(sequelize: Sequelize): Models {
ReputationEvent: Models.ReputationEvent(sequelize),
SwapDeal: Models.SwapDeal(sequelize),
Trade: Models.Trade(sequelize),
+ Password: Models.Password(sequelize),
};
models.Currency.hasMany(models.Pair, {
@@ -118,6 +123,8 @@ class DB {
public sequelize: Sequelize;
public models: Models;
+ private static VERSION = 1;
+
/**
* @param storage the file path for the sqlite database file, if ':memory:' or not specified the db is stored in memory
*/
@@ -136,6 +143,8 @@ class DB {
* @param initDb whether to intialize a new database with default values if no database exists
*/
public init = async (network = XuNetwork.SimNet, initDb = false): Promise => {
+ const isNewDb = await this.isNewDb();
+
try {
await this.sequelize.authenticate();
this.logger.info(`connected to database ${this.storage ? this.storage : 'in memory'}`);
@@ -143,12 +152,40 @@ class DB {
this.logger.error('unable to connect to the database', err);
throw err;
}
- const { Node, Currency, Pair, ReputationEvent, SwapDeal, Order, Trade } = this.models;
+
+ if (isNewDb) {
+ await this.sequelize.query(`PRAGMA user_version=${DB.VERSION};`);
+ }
+
+ // version is useful for tracking migrations & upgrades to the xud database when
+ // the database schema is modified or restructured
+ let version: number;
+ const userVersionPragma = (await this.sequelize.query('PRAGMA user_version;'));
+ assert(Array.isArray(userVersionPragma) && Array.isArray(userVersionPragma[0]));
+ const userVersion = userVersionPragma[0][0].user_version;
+ assert(typeof userVersion === 'number');
+ version = userVersion;
+ this.logger.trace(`db version is ${version}`);
+
+ if (version <= DB.VERSION) {
+ // if our db is not the latest version, we call each migration procedure necessary
+ // to bring us from our current version up to the latest version.
+ for (let n = version; n < DB.VERSION; n += 1) {
+ this.logger.info(`migrating db from version ${n} to version ${n + 1}`);
+ await migrations[n](this.sequelize);
+ await this.sequelize.query(`PRAGMA user_version=${n + 1};`);
+ this.logger.info(`migration to version ${n + 1} complete`);
+ }
+ }
+
+ const { Node, Currency, Pair, ReputationEvent, SwapDeal, Order, Trade, Password } = this.models;
// sync schemas with the database in phases, according to FKs dependencies
await Promise.all([
Node.sync(),
Currency.sync(),
+ Password.sync(),
]);
+
// Pair is dependent on Currency, ReputationEvent is dependent on Node
await Promise.all([
Pair.sync(),
@@ -199,6 +236,26 @@ class DB {
}
}
+ /**
+ * Checks whether the database is new, in other words whether we are not
+ * loading a preexisting database from disk.
+ */
+ private isNewDb = async () => {
+ if (this.storage && this.storage !== ':memory:') {
+ // check if database file exists
+ try {
+ await fs.access(this.storage);
+ return false;
+ } catch (err) {
+ if (err.code !== 'ENOENT') {
+ // we ignore errors due to file not existing, otherwise throw
+ throw err;
+ }
+ }
+ }
+ return true;
+ }
+
public close = () => {
return this.sequelize.close();
}
diff --git a/lib/db/migrations.ts b/lib/db/migrations.ts
new file mode 100644
index 000000000..49c8697cd
--- /dev/null
+++ b/lib/db/migrations.ts
@@ -0,0 +1,22 @@
+import Sequelize, { DataTypes } from 'sequelize';
+
+/**
+ * An ordered array of functions that will migrate the database from one
+ * version to the next. The 1st element (index 0) will migrate from version
+ * 0 to 1, the 2nd element will migrate from version 1 to 2, and so on...
+ * Each migration must be called in order and allowed to complete before
+ * calling the next.
+ */
+const migrations: ((sequelize: Sequelize.Sequelize) => Promise)[] = [];
+
+migrations[0] = async (sequelize: Sequelize.Sequelize) => {
+ await sequelize.getQueryInterface().createTable('passwords', {
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
+ encryptedPassword: { type: DataTypes.STRING, allowNull: false },
+ currency: { type: DataTypes.STRING(5), allowNull: true },
+ swapClient: { type: DataTypes.TINYINT, allowNull: false },
+ createdAt: { type: DataTypes.BIGINT, allowNull: false },
+ });
+};
+
+export default migrations;
diff --git a/lib/db/models/Password.ts b/lib/db/models/Password.ts
new file mode 100644
index 000000000..722739e31
--- /dev/null
+++ b/lib/db/models/Password.ts
@@ -0,0 +1,21 @@
+import { DataTypes, ModelAttributes, ModelOptions, Sequelize } from 'sequelize';
+import { PasswordInstance } from '../types';
+
+export default function Password(sequelize: Sequelize) {
+ const attributes: ModelAttributes = {
+ id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
+ encryptedPassword: { type: DataTypes.STRING, allowNull: false },
+ currency: { type: DataTypes.STRING(5), allowNull: true },
+ swapClient: { type: DataTypes.TINYINT, allowNull: false },
+ createdAt: { type: DataTypes.BIGINT, allowNull: false },
+ };
+
+ const options: ModelOptions = {
+ tableName: 'passwords',
+ timestamps: true,
+ updatedAt: false,
+ };
+
+ const Password = sequelize.define('Password', attributes, options);
+ return Password;
+}
diff --git a/lib/db/models/index.ts b/lib/db/models/index.ts
index 3db022ece..0f4f9ee4c 100644
--- a/lib/db/models/index.ts
+++ b/lib/db/models/index.ts
@@ -5,3 +5,4 @@ export { default as Pair } from './Pair';
export { default as ReputationEvent } from './ReputationEvent';
export { default as SwapDeal } from './SwapDeal';
export { default as Trade } from './Trade';
+export { default as Password } from './Password';
diff --git a/lib/db/types.ts b/lib/db/types.ts
index 275b7a8c0..e0825c1c5 100644
--- a/lib/db/types.ts
+++ b/lib/db/types.ts
@@ -1,5 +1,5 @@
import { BelongsToGetAssociationMixin, Model } from 'sequelize';
-import { ReputationEvent } from '../constants/enums';
+import { ReputationEvent, SwapClientType } from '../constants/enums';
import { Currency, Order, Pair } from '../orderbook/types';
import { Address, NodeConnectionInfo } from '../p2p/types';
import { SwapDeal } from '../swaps/types';
@@ -110,3 +110,17 @@ export type ReputationEventAttributes = ReputationEventCreationAttributes & {
};
export interface ReputationEventInstance extends Model, ReputationEventAttributes {}
+
+/* Passwords */
+export type PasswordCreationAttributes = {
+ encryptedPassword: string;
+ currency?: string;
+ swapClient: SwapClientType;
+};
+
+export type PasswordAttributes = PasswordCreationAttributes & {
+ createdAt: number;
+ id: number;
+};
+
+export interface PasswordInstance extends Model, PasswordAttributes {}
diff --git a/lib/grpc/GrpcService.ts b/lib/grpc/GrpcService.ts
index 54559d393..7a581cba5 100644
--- a/lib/grpc/GrpcService.ts
+++ b/lib/grpc/GrpcService.ts
@@ -877,6 +877,20 @@ class GrpcService {
}
}
+ public changePassword: grpc.handleUnaryCall = async (call, callback) => {
+ if (!this.isReady(this.service, callback)) {
+ return;
+ }
+ try {
+ await this.service.changePassword(call.request.toObject());
+
+ const response = new xudrpc.ChangePasswordResponse();
+ callback(null, response);
+ } catch (err) {
+ callback(getGrpcError(err), null);
+ }
+ }
+
public shutdown: grpc.handleUnaryCall = (_, callback) => {
if (!this.isReady(this.service, callback)) {
return;
diff --git a/lib/grpc/getGrpcError.ts b/lib/grpc/getGrpcError.ts
index 1ff61d687..a059de9f2 100644
--- a/lib/grpc/getGrpcError.ts
+++ b/lib/grpc/getGrpcError.ts
@@ -67,6 +67,7 @@ const getGrpcError = (err: any) => {
break;
case serviceErrorCodes.NODE_ALREADY_EXISTS:
case serviceErrorCodes.NODE_DOES_NOT_EXIST:
+ case serviceErrorCodes.NO_ENCRYPT_MODE_ENABLED:
code = status.UNIMPLEMENTED;
break;
case p2pErrorCodes.POOL_CLOSED:
diff --git a/lib/lndclient/LndClient.ts b/lib/lndclient/LndClient.ts
index 8ea03e7b4..583fca8b5 100644
--- a/lib/lndclient/LndClient.ts
+++ b/lib/lndclient/LndClient.ts
@@ -50,6 +50,7 @@ class LndClient extends SwapClient {
public readonly finalLock: number;
public config: LndClientConfig;
public currency: string;
+ public walletPassword?: string;
private lightning?: LightningClient;
private walletUnlocker?: WalletUnlockerClient;
/** The maximum time to wait for a client to be ready for making grpc calls, can be used for exponential backoff. */
@@ -418,34 +419,10 @@ class LndClient extends SwapClient {
if (isWalletInitialized) {
// admin.macaroon will not necessarily be created by the time lnd responds to a successful
// InitWallet call, so we watch the folder that we expect it to be in for it to be created
- const watchMacaroonPromise = new Promise((resolve) => {
- this.watchMacaroonResolve = resolve;
- });
- const macaroonDir = path.join(this.macaroonpath!, '..');
- const fsWatcher = watch(macaroonDir, (event, filename) => {
- if (event === 'change' && filename === 'admin.macaroon') {
- this.logger.debug('admin.macaroon was created');
- if (this.watchMacaroonResolve) {
- this.watchMacaroonResolve(true);
- }
- }
- });
- this.logger.debug(`watching ${macaroonDir} for admin.macaroon to be created`);
- const macaroonCreated = await watchMacaroonPromise;
- fsWatcher.close();
- this.watchMacaroonResolve = undefined;
-
- if (macaroonCreated) {
- try {
- await this.loadMacaroon();
+ await this.watchThenLoadMacaroon();
- // once we've loaded the macaroon we can attempt to verify the conneciton
- this.verifyConnection().catch(this.logger.error);
- } catch (err) {
- this.logger.error(`could not load macaroon from ${this.macaroonpath}`);
- this.setStatus(ClientStatus.Disabled);
- }
- }
+ // once we've loaded the macaroon we can attempt to verify the conneciton
+ this.verifyConnection().catch(this.logger.error);
}
}
@@ -950,6 +927,7 @@ class LndClient extends SwapClient {
public initWallet = async (walletPassword: string, seedMnemonic: string[], restore = false, backup?: Uint8Array):
Promise => {
+ this.walletPassword = walletPassword;
const request = new lndwalletunlocker.InitWalletRequest();
// from the master seed/mnemonic we derive a child mnemonic for this specific client
@@ -980,6 +958,7 @@ class LndClient extends SwapClient {
}
public unlockWallet = async (walletPassword: string): Promise => {
+ this.walletPassword = walletPassword;
const request = new lndwalletunlocker.UnlockWalletRequest();
request.setWalletPassword(Uint8Array.from(Buffer.from(walletPassword, 'utf8')));
await this.unaryWalletUnlockerCall(
@@ -989,6 +968,57 @@ class LndClient extends SwapClient {
this.logger.info('wallet unlocked');
}
+ /**
+ * Watches for a change in the admin.macaroon file at the configured path,
+ * then loads the macaroon.
+ */
+ private watchThenLoadMacaroon = async () => {
+ const watchMacaroonPromise = new Promise((resolve) => {
+ this.watchMacaroonResolve = resolve;
+ });
+ const macaroonDir = path.join(this.macaroonpath!, '..');
+ const fsWatcher = watch(macaroonDir, (event, filename) => {
+ if (event === 'change' && filename === 'admin.macaroon') {
+ this.logger.debug('admin.macaroon was created');
+ if (this.watchMacaroonResolve) {
+ this.watchMacaroonResolve(true);
+ }
+ }
+ });
+ this.logger.debug(`watching ${macaroonDir} for admin.macaroon to be created`);
+ const macaroonCreated = await watchMacaroonPromise;
+ fsWatcher.close();
+ this.watchMacaroonResolve = undefined;
+
+ if (macaroonCreated) {
+ try {
+ await this.loadMacaroon();
+ } catch (err) {
+ this.logger.error(`could not load macaroon from ${this.macaroonpath}`);
+ this.setStatus(ClientStatus.Disabled);
+ }
+ }
+ }
+
+ public changePassword = async (oldPassword: string, newPassword: string) => {
+ this.walletPassword = newPassword;
+ const request = new lndwalletunlocker.ChangePasswordRequest();
+ request.setCurrentPassword(Uint8Array.from(Buffer.from(oldPassword, 'utf8')));
+ request.setNewPassword(Uint8Array.from(Buffer.from(newPassword, 'utf8')));
+ await this.unaryWalletUnlockerCall(
+ 'changePassword', request,
+ );
+
+ // the macaroons change every time lnd changes its password, so we must remove the old one and reload the new one
+ this.meta.remove('macaroon');
+ // admin.macaroon will not necessarily be created by the time lnd responds to a successful
+ // ChangePassword call, so we watch the folder that we expect it to be in for it to be created
+ await this.watchThenLoadMacaroon();
+
+ this.setUnlocked();
+ this.logger.info('password changed & wallet unlocked');
+ }
+
public addInvoice = async (
{ rHash, units, expiry = this.finalLock }:
{ rHash: string, units: number, expiry?: number },
diff --git a/lib/nodekey/NodeKey.ts b/lib/nodekey/NodeKey.ts
index 3731dbdf6..2c8535241 100644
--- a/lib/nodekey/NodeKey.ts
+++ b/lib/nodekey/NodeKey.ts
@@ -1,9 +1,9 @@
-import secp256k1 from 'secp256k1';
-import { randomBytes } from '../utils/utils';
-import { promises as fs } from 'fs';
-import { createCipheriv, createDecipheriv, createHash } from 'crypto';
import { entropyToMnemonic } from 'bip39';
+import { createHash } from 'crypto';
+import { promises as fs } from 'fs';
+import secp256k1 from 'secp256k1';
import { SwapClientType } from '../constants/enums';
+import { decrypt, encrypt, randomBytes } from '../utils/cryptoUtils';
import { encipher } from '../utils/seedutil';
/**
@@ -11,31 +11,31 @@ import { encipher } from '../utils/seedutil';
* and can sign messages to prove their veracity.
*/
class NodeKey {
- private static ENCRYPTION_IV_LENGTH = 16;
+ public password?: string;
/**
* @param privKey The 32 byte private key
* @param pubKey The public key in hex string format.
*/
- constructor(public readonly privKey: Buffer, public readonly pubKey: string) { }
+ constructor(public readonly privKey: Buffer, public readonly pubKey: string, private readonly path: string) { }
/**
* Generates a random NodeKey.
*/
- public static generate = async (): Promise => {
+ public static generate = async (path?: string): Promise => {
let privKey: Buffer;
do {
privKey = await randomBytes(32);
} while (!secp256k1.privateKeyVerify(privKey));
- return NodeKey.fromBytes(privKey);
+ return NodeKey.fromBytes(privKey, path);
}
/**
* Converts a buffer of bytes to a NodeKey. Uses the first 32 bytes from the buffer to generate
* the private key. If the buffer has fewer than 32 bytes, the buffer is right-padded with zeros.
*/
- public static fromBytes = (bytes: Buffer): NodeKey => {
+ public static fromBytes = (bytes: Buffer, path?: string): NodeKey => {
let privKey: Buffer;
if (bytes.byteLength === 32) {
privKey = bytes;
@@ -48,11 +48,7 @@ class NodeKey {
const pubKeyBytes = secp256k1.publicKeyCreate(privKey);
const pubKey = pubKeyBytes.toString('hex');
- return new NodeKey(privKey, pubKey);
- }
-
- private static getCipherKey = (password: string) => {
- return createHash('sha256').update(password).digest();
+ return new NodeKey(privKey, pubKey, path ?? '');
}
/**
@@ -67,17 +63,14 @@ class NodeKey {
if (password) {
// decrypt file using the password
- // the first 16 bytes contain the initialization vector
- const iv = fileBuffer.slice(0, NodeKey.ENCRYPTION_IV_LENGTH);
- const key = NodeKey.getCipherKey(password);
- const encrypted = fileBuffer.slice(NodeKey.ENCRYPTION_IV_LENGTH);
- const decipher = createDecipheriv('aes-256-cbc', key, iv);
- privKey = Buffer.concat([decipher.update(encrypted), decipher.final()]);
+ privKey = decrypt(fileBuffer, password);
} else {
privKey = fileBuffer;
}
if (secp256k1.privateKeyVerify(privKey)) {
- return NodeKey.fromBytes(privKey);
+ const nodeKey = NodeKey.fromBytes(privKey, path);
+ nodeKey.password = password;
+ return nodeKey;
} else {
throw new Error(`${path} does not contain a valid ECDSA private key`);
}
@@ -103,17 +96,15 @@ class NodeKey {
* @param path the path at which to save the file
* @param password an optional password parameter for encrypting the private key
*/
- public toFile = async (path: string, password?: string): Promise => {
+ public toFile = async (password?: string): Promise => {
let buf: Buffer;
if (password) {
- const iv = await randomBytes(NodeKey.ENCRYPTION_IV_LENGTH);
- const key = NodeKey.getCipherKey(password);
- const cipher = createCipheriv('aes-256-cbc', key, iv);
- buf = Buffer.concat([iv, cipher.update(this.privKey), cipher.final()]);
+ this.password = password;
+ buf = await encrypt(this.privKey, password);
} else {
buf = this.privKey;
}
- await fs.writeFile(path, buf);
+ await fs.writeFile(this.path, buf);
}
/**
diff --git a/lib/p2p/Framer.ts b/lib/p2p/Framer.ts
index b8434c088..d03a4ddf3 100644
--- a/lib/p2p/Framer.ts
+++ b/lib/p2p/Framer.ts
@@ -1,10 +1,10 @@
import assert from 'assert';
import { createCipheriv, createDecipheriv } from 'crypto';
+import { magicValsXuNetwork } from '../constants/enums';
+import { randomBytes } from '../utils/cryptoUtils';
+import errors from './errors';
import Network from './Network';
import Packet from './packets/Packet';
-import errors from './errors';
-import { magicValsXuNetwork } from '../constants/enums';
-import { randomBytes } from '../utils/utils';
type WireMsgHeader = {
magic?: number,
diff --git a/lib/proto/xudrpc.swagger.json b/lib/proto/xudrpc.swagger.json
index 53128eda3..ccdc5b3dc 100644
--- a/lib/proto/xudrpc.swagger.json
+++ b/lib/proto/xudrpc.swagger.json
@@ -122,6 +122,23 @@
]
}
},
+ "/v1/changepass": {
+ "post": {
+ "summary": "Changes the xud master password, including the wallet passwords for any underlying clients.\nshell: xucli changepass",
+ "operationId": "ChangePassword",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/xudrpcChangePasswordResponse"
+ }
+ }
+ },
+ "tags": [
+ "Xud"
+ ]
+ }
+ },
"/v1/closechannel": {
"post": {
"summary": "Closes any existing payment channels with a peer for the specified currency.\nshell: xucli closechannel \u003ccurrency\u003e [node_identifier ] [--force]",
@@ -986,6 +1003,9 @@
}
}
},
+ "xudrpcChangePasswordResponse": {
+ "type": "object"
+ },
"xudrpcChannels": {
"type": "object",
"properties": {
diff --git a/lib/proto/xudrpc_grpc_pb.d.ts b/lib/proto/xudrpc_grpc_pb.d.ts
index 9469240a3..22051652c 100644
--- a/lib/proto/xudrpc_grpc_pb.d.ts
+++ b/lib/proto/xudrpc_grpc_pb.d.ts
@@ -78,6 +78,7 @@ interface IXudService extends grpc.ServiceDefinition;
responseDeserialize: grpc.deserialize;
}
+interface IXudService_IChangePassword extends grpc.MethodDefinition {
+ path: string; // "/xudrpc.Xud/ChangePassword"
+ requestStream: boolean; // false
+ responseStream: boolean; // false
+ requestSerialize: grpc.serialize;
+ requestDeserialize: grpc.deserialize;
+ responseSerialize: grpc.serialize;
+ responseDeserialize: grpc.deserialize;
+}
interface IXudService_ICloseChannel extends grpc.MethodDefinition {
path: string; // "/xudrpc.Xud/CloseChannel"
requestStream: boolean; // false
@@ -414,6 +424,7 @@ export interface IXudServer {
addCurrency: grpc.handleUnaryCall;
addPair: grpc.handleUnaryCall;
ban: grpc.handleUnaryCall;
+ changePassword: grpc.handleUnaryCall;
closeChannel: grpc.handleUnaryCall;
connect: grpc.handleUnaryCall;
walletDeposit: grpc.handleUnaryCall;
@@ -456,6 +467,9 @@ export interface IXudClient {
ban(request: xudrpc_pb.BanRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.BanResponse) => void): grpc.ClientUnaryCall;
ban(request: xudrpc_pb.BanRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.BanResponse) => void): grpc.ClientUnaryCall;
ban(request: xudrpc_pb.BanRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.BanResponse) => void): grpc.ClientUnaryCall;
+ changePassword(request: xudrpc_pb.ChangePasswordRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ChangePasswordResponse) => void): grpc.ClientUnaryCall;
+ changePassword(request: xudrpc_pb.ChangePasswordRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ChangePasswordResponse) => void): grpc.ClientUnaryCall;
+ changePassword(request: xudrpc_pb.ChangePasswordRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ChangePasswordResponse) => void): grpc.ClientUnaryCall;
closeChannel(request: xudrpc_pb.CloseChannelRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.CloseChannelResponse) => void): grpc.ClientUnaryCall;
closeChannel(request: xudrpc_pb.CloseChannelRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.CloseChannelResponse) => void): grpc.ClientUnaryCall;
closeChannel(request: xudrpc_pb.CloseChannelRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.CloseChannelResponse) => void): grpc.ClientUnaryCall;
@@ -554,6 +568,9 @@ export class XudClient extends grpc.Client implements IXudClient {
public ban(request: xudrpc_pb.BanRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.BanResponse) => void): grpc.ClientUnaryCall;
public ban(request: xudrpc_pb.BanRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.BanResponse) => void): grpc.ClientUnaryCall;
public ban(request: xudrpc_pb.BanRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.BanResponse) => void): grpc.ClientUnaryCall;
+ public changePassword(request: xudrpc_pb.ChangePasswordRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ChangePasswordResponse) => void): grpc.ClientUnaryCall;
+ public changePassword(request: xudrpc_pb.ChangePasswordRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ChangePasswordResponse) => void): grpc.ClientUnaryCall;
+ public changePassword(request: xudrpc_pb.ChangePasswordRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ChangePasswordResponse) => void): grpc.ClientUnaryCall;
public closeChannel(request: xudrpc_pb.CloseChannelRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.CloseChannelResponse) => void): grpc.ClientUnaryCall;
public closeChannel(request: xudrpc_pb.CloseChannelRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.CloseChannelResponse) => void): grpc.ClientUnaryCall;
public closeChannel(request: xudrpc_pb.CloseChannelRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.CloseChannelResponse) => void): grpc.ClientUnaryCall;
diff --git a/lib/proto/xudrpc_grpc_pb.js b/lib/proto/xudrpc_grpc_pb.js
index 35a63851a..8d359ad92 100644
--- a/lib/proto/xudrpc_grpc_pb.js
+++ b/lib/proto/xudrpc_grpc_pb.js
@@ -81,6 +81,28 @@ function deserialize_xudrpc_BanResponse(buffer_arg) {
return xudrpc_pb.BanResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
+function serialize_xudrpc_ChangePasswordRequest(arg) {
+ if (!(arg instanceof xudrpc_pb.ChangePasswordRequest)) {
+ throw new Error('Expected argument of type xudrpc.ChangePasswordRequest');
+ }
+ return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_xudrpc_ChangePasswordRequest(buffer_arg) {
+ return xudrpc_pb.ChangePasswordRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
+function serialize_xudrpc_ChangePasswordResponse(arg) {
+ if (!(arg instanceof xudrpc_pb.ChangePasswordResponse)) {
+ throw new Error('Expected argument of type xudrpc.ChangePasswordResponse');
+ }
+ return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_xudrpc_ChangePasswordResponse(buffer_arg) {
+ return xudrpc_pb.ChangePasswordResponse.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
function serialize_xudrpc_CloseChannelRequest(arg) {
if (!(arg instanceof xudrpc_pb.CloseChannelRequest)) {
throw new Error('Expected argument of type xudrpc.CloseChannelRequest');
@@ -876,6 +898,19 @@ var XudService = exports.XudService = {
responseSerialize: serialize_xudrpc_BanResponse,
responseDeserialize: deserialize_xudrpc_BanResponse,
},
+ // Changes the xud master password, including the wallet passwords for any underlying clients.
+ // shell: xucli changepass
+ changePassword: {
+ path: '/xudrpc.Xud/ChangePassword',
+ requestStream: false,
+ responseStream: false,
+ requestType: xudrpc_pb.ChangePasswordRequest,
+ responseType: xudrpc_pb.ChangePasswordResponse,
+ requestSerialize: serialize_xudrpc_ChangePasswordRequest,
+ requestDeserialize: deserialize_xudrpc_ChangePasswordRequest,
+ responseSerialize: serialize_xudrpc_ChangePasswordResponse,
+ responseDeserialize: deserialize_xudrpc_ChangePasswordResponse,
+ },
// Closes any existing payment channels with a peer for the specified currency.
// shell: xucli closechannel [node_identifier ] [--force]
closeChannel: {
diff --git a/lib/proto/xudrpc_pb.d.ts b/lib/proto/xudrpc_pb.d.ts
index ea4f29b08..bd4afaa62 100644
--- a/lib/proto/xudrpc_pb.d.ts
+++ b/lib/proto/xudrpc_pb.d.ts
@@ -202,6 +202,48 @@ export namespace Channels {
}
}
+export class ChangePasswordRequest extends jspb.Message {
+ getNewPassword(): string;
+ setNewPassword(value: string): void;
+
+ getOldPassword(): string;
+ setOldPassword(value: string): void;
+
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): ChangePasswordRequest.AsObject;
+ static toObject(includeInstance: boolean, msg: ChangePasswordRequest): ChangePasswordRequest.AsObject;
+ static extensions: {[key: number]: jspb.ExtensionFieldInfo};
+ static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo};
+ static serializeBinaryToWriter(message: ChangePasswordRequest, writer: jspb.BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): ChangePasswordRequest;
+ static deserializeBinaryFromReader(message: ChangePasswordRequest, reader: jspb.BinaryReader): ChangePasswordRequest;
+}
+
+export namespace ChangePasswordRequest {
+ export type AsObject = {
+ newPassword: string,
+ oldPassword: string,
+ }
+}
+
+export class ChangePasswordResponse extends jspb.Message {
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): ChangePasswordResponse.AsObject;
+ static toObject(includeInstance: boolean, msg: ChangePasswordResponse): ChangePasswordResponse.AsObject;
+ static extensions: {[key: number]: jspb.ExtensionFieldInfo};
+ static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo};
+ static serializeBinaryToWriter(message: ChangePasswordResponse, writer: jspb.BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): ChangePasswordResponse;
+ static deserializeBinaryFromReader(message: ChangePasswordResponse, reader: jspb.BinaryReader): ChangePasswordResponse;
+}
+
+export namespace ChangePasswordResponse {
+ export type AsObject = {
+ }
+}
+
export class CloseChannelRequest extends jspb.Message {
getNodeIdentifier(): string;
setNodeIdentifier(value: string): void;
diff --git a/lib/proto/xudrpc_pb.js b/lib/proto/xudrpc_pb.js
index 3431addf3..fd01ace0c 100644
--- a/lib/proto/xudrpc_pb.js
+++ b/lib/proto/xudrpc_pb.js
@@ -20,6 +20,8 @@ goog.exportSymbol('proto.xudrpc.Balance', null, global);
goog.exportSymbol('proto.xudrpc.BanRequest', null, global);
goog.exportSymbol('proto.xudrpc.BanResponse', null, global);
goog.exportSymbol('proto.xudrpc.Chain', null, global);
+goog.exportSymbol('proto.xudrpc.ChangePasswordRequest', null, global);
+goog.exportSymbol('proto.xudrpc.ChangePasswordResponse', null, global);
goog.exportSymbol('proto.xudrpc.Channels', null, global);
goog.exportSymbol('proto.xudrpc.CloseChannelRequest', null, global);
goog.exportSymbol('proto.xudrpc.CloseChannelResponse', null, global);
@@ -1429,6 +1431,291 @@ proto.xudrpc.Channels.prototype.setClosed = function(value) {
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.xudrpc.ChangePasswordRequest = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.xudrpc.ChangePasswordRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ proto.xudrpc.ChangePasswordRequest.displayName = 'proto.xudrpc.ChangePasswordRequest';
+}
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto suitable for use in Soy templates.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.xudrpc.ChangePasswordRequest.prototype.toObject = function(opt_includeInstance) {
+ return proto.xudrpc.ChangePasswordRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Whether to include the JSPB
+ * instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.xudrpc.ChangePasswordRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.ChangePasswordRequest.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ newPassword: jspb.Message.getFieldWithDefault(msg, 1, ""),
+ oldPassword: jspb.Message.getFieldWithDefault(msg, 2, "")
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.xudrpc.ChangePasswordRequest}
+ */
+proto.xudrpc.ChangePasswordRequest.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.xudrpc.ChangePasswordRequest;
+ return proto.xudrpc.ChangePasswordRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.xudrpc.ChangePasswordRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.xudrpc.ChangePasswordRequest}
+ */
+proto.xudrpc.ChangePasswordRequest.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setNewPassword(value);
+ break;
+ case 2:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setOldPassword(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.xudrpc.ChangePasswordRequest.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.xudrpc.ChangePasswordRequest.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.xudrpc.ChangePasswordRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.ChangePasswordRequest.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getNewPassword();
+ if (f.length > 0) {
+ writer.writeString(
+ 1,
+ f
+ );
+ }
+ f = message.getOldPassword();
+ if (f.length > 0) {
+ writer.writeString(
+ 2,
+ f
+ );
+ }
+};
+
+
+/**
+ * optional string new_password = 1;
+ * @return {string}
+ */
+proto.xudrpc.ChangePasswordRequest.prototype.getNewPassword = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/** @param {string} value */
+proto.xudrpc.ChangePasswordRequest.prototype.setNewPassword = function(value) {
+ jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string old_password = 2;
+ * @return {string}
+ */
+proto.xudrpc.ChangePasswordRequest.prototype.getOldPassword = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/** @param {string} value */
+proto.xudrpc.ChangePasswordRequest.prototype.setOldPassword = function(value) {
+ jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.xudrpc.ChangePasswordResponse = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.xudrpc.ChangePasswordResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ proto.xudrpc.ChangePasswordResponse.displayName = 'proto.xudrpc.ChangePasswordResponse';
+}
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto suitable for use in Soy templates.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
+ * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
+ * for transitional soy proto support: http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.xudrpc.ChangePasswordResponse.prototype.toObject = function(opt_includeInstance) {
+ return proto.xudrpc.ChangePasswordResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Whether to include the JSPB
+ * instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.xudrpc.ChangePasswordResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.ChangePasswordResponse.toObject = function(includeInstance, msg) {
+ var f, obj = {
+
+ };
+
+ if (includeInstance) {
+ obj.$jspbMessageInstance = msg;
+ }
+ return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.xudrpc.ChangePasswordResponse}
+ */
+proto.xudrpc.ChangePasswordResponse.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.xudrpc.ChangePasswordResponse;
+ return proto.xudrpc.ChangePasswordResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.xudrpc.ChangePasswordResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.xudrpc.ChangePasswordResponse}
+ */
+proto.xudrpc.ChangePasswordResponse.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.xudrpc.ChangePasswordResponse.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.xudrpc.ChangePasswordResponse.serializeBinaryToWriter(this, writer);
+ return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.xudrpc.ChangePasswordResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.ChangePasswordResponse.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+};
+
+
+
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
diff --git a/lib/service/InitService.ts b/lib/service/InitService.ts
index 4f2834f6f..da5f7d64c 100644
--- a/lib/service/InitService.ts
+++ b/lib/service/InitService.ts
@@ -39,7 +39,7 @@ class InitService extends EventEmitter {
// we use the deciphered seed (without the salt and extra fields that make up the enciphered seed)
// to generate an xud nodekey from the same seed used for wallets
const decipheredSeed = await decipher(seedMnemonic);
- const nodeKey = NodeKey.fromBytes(decipheredSeed);
+ const nodeKey = NodeKey.fromBytes(decipheredSeed, this.nodeKeyPath);
// use this seed to init any lnd wallets that are uninitialized
const initWalletResult = await this.swapClientManager.initWallets({
@@ -48,7 +48,7 @@ class InitService extends EventEmitter {
walletPassword: password,
});
- await nodeKey.toFile(this.nodeKeyPath, password);
+ await nodeKey.toFile(password);
this.emit('nodekey', nodeKey);
return {
initializedLndWallets: initWalletResult.initializedLndWallets,
@@ -112,7 +112,7 @@ class InitService extends EventEmitter {
await this.prepareCall();
const decipheredSeed = await decipher(seedMnemonicList);
- const nodeKey = NodeKey.fromBytes(decipheredSeed);
+ const nodeKey = NodeKey.fromBytes(decipheredSeed, this.nodeKeyPath);
// use the seed and database backups to restore any swap clients' wallets
// that are uninitialized
@@ -127,7 +127,7 @@ class InitService extends EventEmitter {
if (xudDatabase.byteLength) {
await fs.writeFile(this.databasePath, xudDatabase);
}
- await nodeKey.toFile(this.nodeKeyPath, password);
+ await nodeKey.toFile(password);
this.emit('nodekey', nodeKey);
return {
initializedLndWallets: initWalletResult.initializedLndWallets,
diff --git a/lib/service/Service.ts b/lib/service/Service.ts
index eadc4599a..f9ded99a7 100644
--- a/lib/service/Service.ts
+++ b/lib/service/Service.ts
@@ -847,5 +847,21 @@ class Service extends EventEmitter {
this.swapClientManager.connextClient?.emit('depositConfirmed', hash);
}
+ public changePassword = async ({ newPassword, oldPassword }: { newPassword: string, oldPassword: string }) => {
+ if (!this.nodekey.password) {
+ throw errors.NO_ENCRYPT_MODE_ENABLED;
+ }
+ if (newPassword.length < 8) {
+ // lnd requires 8+ character passwords, so we must as well
+ throw errors.INVALID_ARGUMENT('password must be at least 8 characters');
+ }
+ if (oldPassword !== this.nodekey.password) {
+ throw errors.INVALID_ARGUMENT('old password is incorrect');
+ }
+
+ // we change the password for our node key right away, then we queue up lnd password changes
+ await this.nodekey.toFile(newPassword);
+ await this.swapClientManager.changeLndPasswords(oldPassword, newPassword);
+ }
}
export default Service;
diff --git a/lib/service/errors.ts b/lib/service/errors.ts
index 07b653edc..e12e95465 100644
--- a/lib/service/errors.ts
+++ b/lib/service/errors.ts
@@ -10,6 +10,7 @@ const errorCodes = {
NODE_DOES_NOT_EXIST: codesPrefix.concat('.6'),
INVALID_REQUEST: codesPrefix.concat('.7'),
NO_CHANNELS_TO_CLOSE: codesPrefix.concat('.8'),
+ NO_ENCRYPT_MODE_ENABLED: codesPrefix.concat('.9'),
};
const errors = {
@@ -52,6 +53,10 @@ const errors = {
message: `no channels found to close for ${remoteIdentifier}`,
code: errorCodes.NO_CHANNELS_TO_CLOSE,
}),
+ NO_ENCRYPT_MODE_ENABLED: {
+ message: 'xud is not encrypted with a password',
+ code: errorCodes.NO_ENCRYPT_MODE_ENABLED,
+ },
};
export { errorCodes };
diff --git a/lib/swaps/SwapClientManager.ts b/lib/swaps/SwapClientManager.ts
index 27d75b7bb..e8baa9735 100644
--- a/lib/swaps/SwapClientManager.ts
+++ b/lib/swaps/SwapClientManager.ts
@@ -11,6 +11,7 @@ import { Level, Loggers } from '../Logger';
import NodeKey from '../nodekey/NodeKey';
import { Currency, OwnLimitOrder } from '../orderbook/types';
import Peer from '../p2p/Peer';
+import { encrypt, decrypt } from '../utils/cryptoUtils';
import { UnitConverter } from '../utils/UnitConverter';
import errors from './errors';
import SwapClient, { ClientStatus } from './SwapClient';
@@ -45,7 +46,6 @@ class SwapClientManager extends EventEmitter {
public swapClients = new Map();
public connextClient?: ConnextClient;
public misconfiguredClients = new Set();
- private walletPassword?: string;
/** A map of supported currency tickers to the inbound amount that is reserved by existing orders. */
private inboundReservedAmounts = new Map();
@@ -56,6 +56,7 @@ class SwapClientManager extends EventEmitter {
private config: Config,
private loggers: Loggers,
private unitConverter: UnitConverter,
+ private models: Models,
) {
super();
}
@@ -65,7 +66,7 @@ class SwapClientManager extends EventEmitter {
* and waits for the swap clients to initialize.
* @returns A promise that resolves upon successful initialization, rejects otherwise.
*/
- public init = async (models: Models): Promise => {
+ public init = async (): Promise => {
const initPromises = [];
// setup configured LND clients and initialize them
for (const currency in this.config.lnd) {
@@ -83,7 +84,7 @@ class SwapClientManager extends EventEmitter {
if (!this.config.connext.disable) {
// setup Connext
- const currencyInstances = await models.Currency.findAll();
+ const currencyInstances = await this.models.Currency.findAll();
this.connextClient = new ConnextClient({
currencyInstances,
unitConverter: this.unitConverter,
@@ -289,8 +290,6 @@ class SwapClientManager extends EventEmitter {
lndBackups?: Map,
nodeKey: NodeKey,
}) => {
- this.walletPassword = walletPassword;
-
// loop through swap clients to initialize locked lnd clients
const initWalletPromises: Promise[] = [];
const initializedLndWallets: string[] = [];
@@ -336,37 +335,57 @@ class SwapClientManager extends EventEmitter {
nodeKey: NodeKey,
connextSeed: string,
}) => {
- this.walletPassword = walletPassword;
-
// loop through swap clients to find locked lnd clients
const unlockWalletPromises: Promise[] = [];
const unlockedLndClients: string[] = [];
const lockedLndClients: string[] = [];
+ const oldEncryptedPasswords = await this.models.Password.findAll();
+
for (const swapClient of this.swapClients.values()) {
if (isLndClient(swapClient)) {
if (swapClient.isWaitingUnlock()) {
- const unlockWalletPromise = swapClient.unlockWallet(walletPassword).then(() => {
- unlockedLndClients.push(swapClient.currency);
- }).catch(async (err) => {
- let walletCreated = false;
- if (err.details === 'wallet not found') {
- // this wallet hasn't been initialized, so we will try to initialize it now
- const seedMnemonic = await nodeKey.getMnemonic();
- try {
- await swapClient.initWallet(this.walletPassword ?? '', seedMnemonic);
- walletCreated = true;
- } catch (err) {
- swapClient.logger.error('could not initialize lnd wallet', err);
+ // first we check whether this lnd is using an old wallet password
+ const oldEncryptedPassword = oldEncryptedPasswords.find((oldEncryptedPassword) => {
+ return oldEncryptedPassword.swapClient === SwapClientType.Lnd && oldEncryptedPassword.currency === swapClient.currency;
+ });
+ const oldPassword = oldEncryptedPassword ? decrypt(oldEncryptedPassword.encryptedPassword, walletPassword).toString() : undefined;
+
+ if (oldPassword) {
+ // if we have an old password for this lnd client, then we use it to change its password
+ // to the new password, which in turn will unlock the client
+ const changePasswordPromise = swapClient.changePassword(oldPassword, walletPassword).then(() => {
+ unlockedLndClients.push(swapClient.currency);
+ return oldEncryptedPassword?.destroy(); // we can remove the old password from the database
+ }).catch(async (err) => {
+ this.loggers.lnd.error(`could not change password for ${swapClient.currency}`, err);
+ lockedLndClients.push(swapClient.currency);
+ });
+
+ unlockWalletPromises.push(changePasswordPromise);
+ } else {
+ const unlockWalletPromise = swapClient.unlockWallet(walletPassword).then(() => {
+ unlockedLndClients.push(swapClient.currency);
+ }).catch(async (err) => {
+ let walletCreated = false;
+ if (err.details === 'wallet not found') {
+ // this wallet hasn't been initialized, so we will try to initialize it now
+ const seedMnemonic = await nodeKey.getMnemonic();
+ try {
+ await swapClient.initWallet(walletPassword ?? '', seedMnemonic);
+ walletCreated = true;
+ } catch (err) {
+ swapClient.logger.error('could not initialize lnd wallet', err);
+ }
}
- }
- if (!walletCreated) {
- lockedLndClients.push(swapClient.currency);
- swapClient.logger.debug(`could not unlock wallet: ${err.message}`);
- }
- });
- unlockWalletPromises.push(unlockWalletPromise);
+ if (!walletCreated) {
+ lockedLndClients.push(swapClient.currency);
+ swapClient.logger.debug(`could not unlock wallet: ${err.message}`);
+ }
+ });
+ unlockWalletPromises.push(unlockWalletPromise);
+ }
} else if (swapClient.isDisconnected() || swapClient.isMisconfigured() || swapClient.isNotInitialized()) {
// if the swap client is not connected, we treat it as locked since lnd will likely be locked when it comes online
lockedLndClients.push(swapClient.currency);
@@ -384,6 +403,31 @@ class SwapClientManager extends EventEmitter {
return { unlockedLndClients, lockedLndClients };
}
+ /**
+ * Changes the wallet passwords for all lnd clients by either calling ChangePassword
+ * right away if lnd is in a WaitingUnlock state or, more often, by persisting the
+ * current wallet password so that xud will try to automatically change it the next
+ * time it is unlocked.
+ */
+ public changeLndPasswords = async (oldPassword: string, newPassword: string) => {
+ const lndClients = this.getLndClientsMap().values();
+ const promises: Promise[] = [];
+ for (const lndClient of lndClients) {
+ if (lndClient.isWaitingUnlock()) {
+ // we can change the password and unlock right now
+ promises.push(lndClient.changePassword(oldPassword, newPassword));
+ } else if (lndClient.isOperational()) {
+ const encryptedPassword = (await encrypt(oldPassword, newPassword)).toString('base64');
+ promises.push(this.models.Password.create({
+ encryptedPassword,
+ swapClient: SwapClientType.Lnd,
+ currency: lndClient.currency,
+ }));
+ }
+ }
+ await Promise.all(promises);
+ }
+
/**
* Gets a swap client instance.
* @param currency a currency that the swap client is linked to.
@@ -648,8 +692,8 @@ class SwapClientManager extends EventEmitter {
this.emit('htlcAccepted', swapClient, rHash, amount, currency);
});
swapClient.on('locked', () => {
- if (this.walletPassword) {
- swapClient.unlockWallet(this.walletPassword).catch(swapClient.logger.error);
+ if (isLndClient(swapClient) && swapClient.walletPassword) {
+ swapClient.unlockWallet(swapClient.walletPassword).catch(swapClient.logger.error);
}
// TODO(connext): unlock ConnextClient when it's implemented
});
diff --git a/lib/swaps/Swaps.ts b/lib/swaps/Swaps.ts
index 2752660b7..c69463479 100644
--- a/lib/swaps/Swaps.ts
+++ b/lib/swaps/Swaps.ts
@@ -10,8 +10,9 @@ import { PacketType } from '../p2p/packets';
import * as packets from '../p2p/packets/types';
import Peer from '../p2p/Peer';
import Pool from '../p2p/Pool';
+import { generatePreimageAndHash } from '../utils/cryptoUtils';
import { UnitConverter } from '../utils/UnitConverter';
-import { generatePreimageAndHash, setTimeoutPromise } from '../utils/utils';
+import { setTimeoutPromise } from '../utils/utils';
import { MAX_PAYMENT_TIME } from './consts';
import errors, { errorCodes } from './errors';
import SwapClient, { PaymentState } from './SwapClient';
diff --git a/lib/utils/cryptoUtils.ts b/lib/utils/cryptoUtils.ts
new file mode 100644
index 000000000..45807a7af
--- /dev/null
+++ b/lib/utils/cryptoUtils.ts
@@ -0,0 +1,49 @@
+import { createCipheriv, createDecipheriv, createHash, randomBytes as cryptoRandomBytes } from 'crypto';
+import { promisify } from 'util';
+
+const ENCRYPTION_IV_LENGTH = 16;
+
+/** A promisified wrapper for the NodeJS `crypto.randomBytes` method. */
+export const randomBytes = promisify(cryptoRandomBytes);
+
+function getCipherKey(password: string) {
+ return createHash('sha256').update(password).digest();
+}
+
+/**
+ * Encrypts a Buffer or base64 string using a password
+ * @param payload a Buffer or base64 string
+ * @returns an encrypted Buffer
+ */
+export async function encrypt(payload: Buffer | string, password: string) {
+ const buf = typeof payload === 'string' ? Buffer.from(payload, 'utf8') : payload;
+
+ const iv = await randomBytes(ENCRYPTION_IV_LENGTH);
+ const key = getCipherKey(password);
+ const cipher = createCipheriv('aes-256-cbc', key, iv);
+ return Buffer.concat([iv, cipher.update(buf), cipher.final()]);
+}
+
+/**
+ * Decrypts a Buffer or base64 string using a password
+ * @param payload a Buffer or base64 string
+ * @returns a decrypted Buffer
+ */
+export function decrypt(payload: Buffer | string, password: string) {
+ const buf = typeof payload === 'string' ? Buffer.from(payload, 'base64') : payload;
+
+ // the first 16 bytes contain the initialization vector
+ const iv = buf.slice(0, ENCRYPTION_IV_LENGTH);
+ const key = getCipherKey(password);
+ const encrypted = buf.slice(ENCRYPTION_IV_LENGTH);
+ const decipher = createDecipheriv('aes-256-cbc', key, iv);
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]);
+}
+
+/** Returns a random payment preimage and hash in hex encoding. */
+export async function generatePreimageAndHash() {
+ const bytes = await randomBytes(32);
+ const rPreimage = bytes.toString('hex');
+ const rHash = createHash('sha256').update(bytes).digest('hex');
+ return { rPreimage, rHash };
+}
diff --git a/lib/utils/utils.ts b/lib/utils/utils.ts
index 1e243e545..6a865cb05 100644
--- a/lib/utils/utils.ts
+++ b/lib/utils/utils.ts
@@ -1,4 +1,3 @@
-import { createHash, randomBytes as cryptoRandomBytes } from 'crypto';
import http from 'http';
// @ts-ignore
import createKeccakHash from 'keccak';
@@ -158,9 +157,6 @@ export const isPlainObject = (obj: any) => {
/** A promisified wrapper for the NodeJS `setTimeout` method. */
export const setTimeoutPromise = promisify(setTimeout);
-/** A promisified wrapper for the NodeJS `crypto.randomBytes` method. */
-export const randomBytes = promisify(cryptoRandomBytes);
-
export const removeUndefinedProps = (typedObj: T): T => {
const obj = typedObj as any;
Object.keys(obj).forEach((key) => {
@@ -205,14 +201,6 @@ export const sortOrders = (orders: T[], isBuy: boolean)
});
};
-/** Returns a random payment preimage and hash in hex encoding. */
-export const generatePreimageAndHash = async () => {
- const bytes = await randomBytes(32);
- const rPreimage = bytes.toString('hex');
- const rHash = createHash('sha256').update(bytes).digest('hex');
- return { rPreimage, rHash };
-};
-
export const base64ToHex = (b64: string) => {
return Buffer.from(b64, 'base64').toString('hex');
};
diff --git a/proto/xudrpc.proto b/proto/xudrpc.proto
index 75fe3e903..c53c746c7 100644
--- a/proto/xudrpc.proto
+++ b/proto/xudrpc.proto
@@ -73,6 +73,14 @@ service Xud {
};
}
+ /* Changes the xud master password, including the wallet passwords for any underlying clients.
+ * shell: xucli changepass*/
+ rpc ChangePassword(ChangePasswordRequest) returns (ChangePasswordResponse) {
+ option (google.api.http) = {
+ post: "/v1/changepass"
+ };
+ }
+
/* Closes any existing payment channels with a peer for the specified currency.
* shell: xucli closechannel [node_identifier ] [--force]*/
rpc CloseChannel(CloseChannelRequest) returns (CloseChannelResponse) {
@@ -423,6 +431,12 @@ message Channels {
uint32 closed = 4 [json_name = "closed"];
}
+message ChangePasswordRequest {
+ string new_password = 1 [json_name = "new_password"];
+ string old_password = 2 [json_name = "old_password"];
+}
+message ChangePasswordResponse {}
+
message CloseChannelRequest {
// The node pub key or alias of the peer with which to close any channels with.
string node_identifier = 1 [json_name = "node_identifier"];
diff --git a/test/jest/NodeKey.spec.ts b/test/jest/NodeKey.spec.ts
index 4daad3211..946ec5a9e 100644
--- a/test/jest/NodeKey.spec.ts
+++ b/test/jest/NodeKey.spec.ts
@@ -1,8 +1,8 @@
import secp256k1 from 'secp256k1';
+import { SwapClientType } from '../../lib/constants/enums';
import NodeKey from '../../lib/nodekey/NodeKey';
-import { randomBytes } from '../../lib/utils/utils';
+import { randomBytes } from '../../lib/utils/cryptoUtils';
import { getTempDir } from '../utils';
-import { SwapClientType } from '../../lib/constants/enums';
function validateNodeKey(nodeKey: NodeKey) {
expect(nodeKey.pubKey).toHaveLength(66);
@@ -11,33 +11,32 @@ function validateNodeKey(nodeKey: NodeKey) {
}
describe('NodeKey', () => {
+ const path = NodeKey.getPath(getTempDir(true));
+
test('it should generate a valid node key', async () => {
const nodeKey = await NodeKey['generate']();
validateNodeKey(nodeKey);
});
test('it should write a nodekey to disk and read it back without encryption', async () => {
- const nodeKey = await NodeKey['generate']();
- const path = NodeKey.getPath(getTempDir(true));
- await nodeKey.toFile(path);
+ const nodeKey = await NodeKey['generate'](path);
+ await nodeKey.toFile();
const nodeKeyFromDisk = await NodeKey.fromFile(path);
expect(nodeKey.privKey.compare(nodeKeyFromDisk.privKey)).toEqual(0);
});
test('it should write a nodekey to disk and read it back with encryption', async () => {
const password = 'wasspord';
- const nodeKey = await NodeKey['generate']();
- const path = NodeKey.getPath(getTempDir(true));
- await nodeKey.toFile(path, password);
+ const nodeKey = await NodeKey['generate'](path);
+ await nodeKey.toFile(password);
const nodeKeyFromDisk = await NodeKey.fromFile(path, password);
expect(nodeKey.privKey.compare(nodeKeyFromDisk.privKey)).toEqual(0);
});
test('it should write a nodekey to disk with encryption and fail reading it with the wrong password', async () => {
const password = 'wasspord';
- const nodeKey = await NodeKey['generate']();
- const path = NodeKey.getPath(getTempDir(true));
- await nodeKey.toFile(path, password);
+ const nodeKey = await NodeKey['generate'](path);
+ await nodeKey.toFile(password);
await expect(NodeKey.fromFile(path, 'wrongpassword')).rejects.toThrow();
});
diff --git a/test/jest/Orderbook.spec.ts b/test/jest/Orderbook.spec.ts
index 8be87dcbf..6db0e0cf2 100644
--- a/test/jest/Orderbook.spec.ts
+++ b/test/jest/Orderbook.spec.ts
@@ -162,7 +162,7 @@ describe('OrderBook', () => {
pool.broadcastOrder = jest.fn();
unitConverter = new UnitConverter();
unitConverter.init();
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
swaps = new Swaps({
pool,
swapClientManager,
diff --git a/test/jest/SwapClientManager.spec.ts b/test/jest/SwapClientManager.spec.ts
index 1308be9f1..9e9e2f4d8 100644
--- a/test/jest/SwapClientManager.spec.ts
+++ b/test/jest/SwapClientManager.spec.ts
@@ -116,8 +116,9 @@ describe('Swaps.SwapClientManager', () => {
});
test('it initializes lnd-ltc and lnd-btc', async () => {
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
+
expect(swapClientManager['swapClients'].size).toEqual(2);
expect(onListenerMock).toHaveBeenCalledTimes(6);
expect(swapClientManager.get('BTC')).not.toBeUndefined();
@@ -132,8 +133,9 @@ describe('Swaps.SwapClientManager', () => {
});
test('it initializes lnd-ltc and lnd-btc', async () => {
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
+
expect(swapClientManager['swapClients'].size).toEqual(2);
expect(onListenerMock).toHaveBeenCalledTimes(6);
expect(swapClientManager.get('BTC')).not.toBeUndefined();
@@ -144,8 +146,9 @@ describe('Swaps.SwapClientManager', () => {
test('it initializes lnd-btc', async () => {
config.lnd.LTC!.disable = true;
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
+
expect(swapClientManager['swapClients'].size).toEqual(1);
expect(onListenerMock).toHaveBeenCalledTimes(3);
expect(swapClientManager.get('BTC')).not.toBeUndefined();
@@ -156,8 +159,9 @@ describe('Swaps.SwapClientManager', () => {
test('it initializes nothing', async () => {
config.lnd.BTC!.disable = true;
config.lnd.LTC!.disable = true;
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
+
expect(swapClientManager['swapClients'].size).toEqual(0);
expect(onListenerMock).toHaveBeenCalledTimes(0);
expect(swapClientManager.get('BTC')).toBeUndefined();
@@ -167,8 +171,9 @@ describe('Swaps.SwapClientManager', () => {
});
test('closes lnd-btc and lnd-ltc', async () => {
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
+
expect(swapClientManager['swapClients'].size).toEqual(2);
swapClientManager.close();
expect(closeMock).toHaveBeenCalledTimes(2);
@@ -180,8 +185,8 @@ describe('Swaps.SwapClientManager', () => {
const setReservedInboundBtcAmount = jest.fn();
beforeEach(async () => {
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
swapClientManager.swapClients.get(currency)!.setReservedInboundAmount = setReservedInboundBtcAmount;
});
@@ -228,17 +233,17 @@ describe('Swaps.SwapClientManager', () => {
describe('openChannel', () => {
let remoteIdentifier: string;
- beforeEach(() => {
+ beforeEach(async () => {
remoteIdentifier = '02afaef2634e5c7ca8d682b828a62bd040929b1e4b5030b21e2a0a891cf545b2e1';
+ swapClientManager = new SwapClientManager(config, loggers, unitConverter, db.models);
+ await swapClientManager.init();
});
test('it fails without swap client', async () => {
expect.assertions(1);
const currency = 'BTC';
const amount = 16000000;
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
swapClientManager.get = jest.fn().mockReturnValue(undefined);
- await swapClientManager.init(db.models);
try {
await swapClientManager.openChannel({ remoteIdentifier, currency, amount });
} catch (e) {
@@ -249,8 +254,6 @@ describe('Swaps.SwapClientManager', () => {
test('it fails without peerSwapClientPubKey', async () => {
const currency = 'BTC';
const amount = 16000000;
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
- await swapClientManager.init(db.models);
try {
await swapClientManager.openChannel({ remoteIdentifier, currency, amount });
} catch (e) {
@@ -261,13 +264,11 @@ describe('Swaps.SwapClientManager', () => {
test('it opens a channel using lnd', async () => {
const currency = 'BTC';
const amount = 16000000;
- swapClientManager = new SwapClientManager(config, loggers, unitConverter);
const getClientSpy = jest.spyOn(swapClientManager, 'get');
const lndListeningUris = [
'123.456.789.321:9735',
'192.168.63.155:9777',
];
- await swapClientManager.init(db.models);
await swapClientManager.openChannel({ remoteIdentifier, currency, amount, uris: lndListeningUris });
expect(getClientSpy).toHaveBeenCalledWith(currency);
expect(mockLndOpenChannel).toHaveBeenCalledTimes(1);
diff --git a/test/jest/cryptoUtils.spec.ts b/test/jest/cryptoUtils.spec.ts
new file mode 100644
index 000000000..7fe2aad00
--- /dev/null
+++ b/test/jest/cryptoUtils.spec.ts
@@ -0,0 +1,24 @@
+import { decrypt, encrypt } from '../../lib/utils/cryptoUtils';
+
+const password = 'wasspord';
+const payload = 'itsasecrettoeverybody';
+
+describe('encrypt & decrypt', () => {
+ test('encrypts a message and then decrypts it', async () => {
+ const encrypted = await encrypt(payload, password);
+ const decrypted = decrypt(encrypted, password);
+ expect(decrypted.toString()).toEqual(payload);
+ });
+
+ test('encrypts a message, converts the decrypted bytes to base64 string, and then decrypts it', async () => {
+ const encrypted = await encrypt(payload, password);
+ const encryptedString = encrypted.toString('base64');
+ const decrypted = decrypt(encryptedString, password);
+ expect(decrypted.toString()).toEqual(payload);
+ });
+
+ test('can not decrypt message using wrong password', async () => {
+ const encrypted = await encrypt(payload, password);
+ expect(() => decrypt(encrypted, 'wrongpass')).toThrow('error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt');
+ });
+});
diff --git a/test/simulation/xudrpc/xudrpc.pb.go b/test/simulation/xudrpc/xudrpc.pb.go
index b738a134e..2c4caacab 100644
--- a/test/simulation/xudrpc/xudrpc.pb.go
+++ b/test/simulation/xudrpc/xudrpc.pb.go
@@ -141,7 +141,7 @@ func (x Currency_SwapClient) String() string {
}
func (Currency_SwapClient) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{14, 0}
+ return fileDescriptor_6960a02cc0a63cf6, []int{16, 0}
}
type ListOrdersRequest_Owner int32
@@ -169,7 +169,7 @@ func (x ListOrdersRequest_Owner) String() string {
}
func (ListOrdersRequest_Owner) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{30, 0}
+ return fileDescriptor_6960a02cc0a63cf6, []int{32, 0}
}
type AddCurrencyResponse struct {
@@ -555,6 +555,84 @@ func (m *Channels) GetClosed() uint32 {
return 0
}
+type ChangePasswordRequest struct {
+ NewPassword string `protobuf:"bytes,1,opt,name=new_password,proto3" json:"new_password,omitempty"`
+ OldPassword string `protobuf:"bytes,2,opt,name=old_password,proto3" json:"old_password,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *ChangePasswordRequest) Reset() { *m = ChangePasswordRequest{} }
+func (m *ChangePasswordRequest) String() string { return proto.CompactTextString(m) }
+func (*ChangePasswordRequest) ProtoMessage() {}
+func (*ChangePasswordRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{8}
+}
+
+func (m *ChangePasswordRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_ChangePasswordRequest.Unmarshal(m, b)
+}
+func (m *ChangePasswordRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_ChangePasswordRequest.Marshal(b, m, deterministic)
+}
+func (m *ChangePasswordRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ChangePasswordRequest.Merge(m, src)
+}
+func (m *ChangePasswordRequest) XXX_Size() int {
+ return xxx_messageInfo_ChangePasswordRequest.Size(m)
+}
+func (m *ChangePasswordRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ChangePasswordRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ChangePasswordRequest proto.InternalMessageInfo
+
+func (m *ChangePasswordRequest) GetNewPassword() string {
+ if m != nil {
+ return m.NewPassword
+ }
+ return ""
+}
+
+func (m *ChangePasswordRequest) GetOldPassword() string {
+ if m != nil {
+ return m.OldPassword
+ }
+ return ""
+}
+
+type ChangePasswordResponse struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *ChangePasswordResponse) Reset() { *m = ChangePasswordResponse{} }
+func (m *ChangePasswordResponse) String() string { return proto.CompactTextString(m) }
+func (*ChangePasswordResponse) ProtoMessage() {}
+func (*ChangePasswordResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{9}
+}
+
+func (m *ChangePasswordResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_ChangePasswordResponse.Unmarshal(m, b)
+}
+func (m *ChangePasswordResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_ChangePasswordResponse.Marshal(b, m, deterministic)
+}
+func (m *ChangePasswordResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ChangePasswordResponse.Merge(m, src)
+}
+func (m *ChangePasswordResponse) XXX_Size() int {
+ return xxx_messageInfo_ChangePasswordResponse.Size(m)
+}
+func (m *ChangePasswordResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ChangePasswordResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ChangePasswordResponse proto.InternalMessageInfo
+
type CloseChannelRequest struct {
// The node pub key or alias of the peer with which to close any channels with.
NodeIdentifier string `protobuf:"bytes,1,opt,name=node_identifier,proto3" json:"node_identifier,omitempty"`
@@ -580,7 +658,7 @@ func (m *CloseChannelRequest) Reset() { *m = CloseChannelRequest{} }
func (m *CloseChannelRequest) String() string { return proto.CompactTextString(m) }
func (*CloseChannelRequest) ProtoMessage() {}
func (*CloseChannelRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{8}
+ return fileDescriptor_6960a02cc0a63cf6, []int{10}
}
func (m *CloseChannelRequest) XXX_Unmarshal(b []byte) error {
@@ -655,7 +733,7 @@ func (m *CloseChannelResponse) Reset() { *m = CloseChannelResponse{} }
func (m *CloseChannelResponse) String() string { return proto.CompactTextString(m) }
func (*CloseChannelResponse) ProtoMessage() {}
func (*CloseChannelResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{9}
+ return fileDescriptor_6960a02cc0a63cf6, []int{11}
}
func (m *CloseChannelResponse) XXX_Unmarshal(b []byte) error {
@@ -695,7 +773,7 @@ func (m *ConnectRequest) Reset() { *m = ConnectRequest{} }
func (m *ConnectRequest) String() string { return proto.CompactTextString(m) }
func (*ConnectRequest) ProtoMessage() {}
func (*ConnectRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{10}
+ return fileDescriptor_6960a02cc0a63cf6, []int{12}
}
func (m *ConnectRequest) XXX_Unmarshal(b []byte) error {
@@ -733,7 +811,7 @@ func (m *ConnectResponse) Reset() { *m = ConnectResponse{} }
func (m *ConnectResponse) String() string { return proto.CompactTextString(m) }
func (*ConnectResponse) ProtoMessage() {}
func (*ConnectResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{11}
+ return fileDescriptor_6960a02cc0a63cf6, []int{13}
}
func (m *ConnectResponse) XXX_Unmarshal(b []byte) error {
@@ -767,7 +845,7 @@ func (m *CreateNodeRequest) Reset() { *m = CreateNodeRequest{} }
func (m *CreateNodeRequest) String() string { return proto.CompactTextString(m) }
func (*CreateNodeRequest) ProtoMessage() {}
func (*CreateNodeRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{12}
+ return fileDescriptor_6960a02cc0a63cf6, []int{14}
}
func (m *CreateNodeRequest) XXX_Unmarshal(b []byte) error {
@@ -811,7 +889,7 @@ func (m *CreateNodeResponse) Reset() { *m = CreateNodeResponse{} }
func (m *CreateNodeResponse) String() string { return proto.CompactTextString(m) }
func (*CreateNodeResponse) ProtoMessage() {}
func (*CreateNodeResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{13}
+ return fileDescriptor_6960a02cc0a63cf6, []int{15}
}
func (m *CreateNodeResponse) XXX_Unmarshal(b []byte) error {
@@ -875,7 +953,7 @@ func (m *Currency) Reset() { *m = Currency{} }
func (m *Currency) String() string { return proto.CompactTextString(m) }
func (*Currency) ProtoMessage() {}
func (*Currency) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{14}
+ return fileDescriptor_6960a02cc0a63cf6, []int{16}
}
func (m *Currency) XXX_Unmarshal(b []byte) error {
@@ -936,7 +1014,7 @@ func (m *DepositRequest) Reset() { *m = DepositRequest{} }
func (m *DepositRequest) String() string { return proto.CompactTextString(m) }
func (*DepositRequest) ProtoMessage() {}
func (*DepositRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{15}
+ return fileDescriptor_6960a02cc0a63cf6, []int{17}
}
func (m *DepositRequest) XXX_Unmarshal(b []byte) error {
@@ -976,7 +1054,7 @@ func (m *DepositResponse) Reset() { *m = DepositResponse{} }
func (m *DepositResponse) String() string { return proto.CompactTextString(m) }
func (*DepositResponse) ProtoMessage() {}
func (*DepositResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{16}
+ return fileDescriptor_6960a02cc0a63cf6, []int{18}
}
func (m *DepositResponse) XXX_Unmarshal(b []byte) error {
@@ -1016,7 +1094,7 @@ func (m *DiscoverNodesRequest) Reset() { *m = DiscoverNodesRequest{} }
func (m *DiscoverNodesRequest) String() string { return proto.CompactTextString(m) }
func (*DiscoverNodesRequest) ProtoMessage() {}
func (*DiscoverNodesRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{17}
+ return fileDescriptor_6960a02cc0a63cf6, []int{19}
}
func (m *DiscoverNodesRequest) XXX_Unmarshal(b []byte) error {
@@ -1055,7 +1133,7 @@ func (m *DiscoverNodesResponse) Reset() { *m = DiscoverNodesResponse{} }
func (m *DiscoverNodesResponse) String() string { return proto.CompactTextString(m) }
func (*DiscoverNodesResponse) ProtoMessage() {}
func (*DiscoverNodesResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{18}
+ return fileDescriptor_6960a02cc0a63cf6, []int{20}
}
func (m *DiscoverNodesResponse) XXX_Unmarshal(b []byte) error {
@@ -1101,7 +1179,7 @@ func (m *ExecuteSwapRequest) Reset() { *m = ExecuteSwapRequest{} }
func (m *ExecuteSwapRequest) String() string { return proto.CompactTextString(m) }
func (*ExecuteSwapRequest) ProtoMessage() {}
func (*ExecuteSwapRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{19}
+ return fileDescriptor_6960a02cc0a63cf6, []int{21}
}
func (m *ExecuteSwapRequest) XXX_Unmarshal(b []byte) error {
@@ -1163,7 +1241,7 @@ func (m *GetBalanceRequest) Reset() { *m = GetBalanceRequest{} }
func (m *GetBalanceRequest) String() string { return proto.CompactTextString(m) }
func (*GetBalanceRequest) ProtoMessage() {}
func (*GetBalanceRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{20}
+ return fileDescriptor_6960a02cc0a63cf6, []int{22}
}
func (m *GetBalanceRequest) XXX_Unmarshal(b []byte) error {
@@ -1203,7 +1281,7 @@ func (m *GetBalanceResponse) Reset() { *m = GetBalanceResponse{} }
func (m *GetBalanceResponse) String() string { return proto.CompactTextString(m) }
func (*GetBalanceResponse) ProtoMessage() {}
func (*GetBalanceResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{21}
+ return fileDescriptor_6960a02cc0a63cf6, []int{23}
}
func (m *GetBalanceResponse) XXX_Unmarshal(b []byte) error {
@@ -1241,7 +1319,7 @@ func (m *GetInfoRequest) Reset() { *m = GetInfoRequest{} }
func (m *GetInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetInfoRequest) ProtoMessage() {}
func (*GetInfoRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{22}
+ return fileDescriptor_6960a02cc0a63cf6, []int{24}
}
func (m *GetInfoRequest) XXX_Unmarshal(b []byte) error {
@@ -1291,7 +1369,7 @@ func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} }
func (m *GetInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetInfoResponse) ProtoMessage() {}
func (*GetInfoResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{23}
+ return fileDescriptor_6960a02cc0a63cf6, []int{25}
}
func (m *GetInfoResponse) XXX_Unmarshal(b []byte) error {
@@ -1399,7 +1477,7 @@ func (m *GetMnemonicRequest) Reset() { *m = GetMnemonicRequest{} }
func (m *GetMnemonicRequest) String() string { return proto.CompactTextString(m) }
func (*GetMnemonicRequest) ProtoMessage() {}
func (*GetMnemonicRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{24}
+ return fileDescriptor_6960a02cc0a63cf6, []int{26}
}
func (m *GetMnemonicRequest) XXX_Unmarshal(b []byte) error {
@@ -1431,7 +1509,7 @@ func (m *GetMnemonicResponse) Reset() { *m = GetMnemonicResponse{} }
func (m *GetMnemonicResponse) String() string { return proto.CompactTextString(m) }
func (*GetMnemonicResponse) ProtoMessage() {}
func (*GetMnemonicResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{25}
+ return fileDescriptor_6960a02cc0a63cf6, []int{27}
}
func (m *GetMnemonicResponse) XXX_Unmarshal(b []byte) error {
@@ -1471,7 +1549,7 @@ func (m *GetNodeInfoRequest) Reset() { *m = GetNodeInfoRequest{} }
func (m *GetNodeInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetNodeInfoRequest) ProtoMessage() {}
func (*GetNodeInfoRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{26}
+ return fileDescriptor_6960a02cc0a63cf6, []int{28}
}
func (m *GetNodeInfoRequest) XXX_Unmarshal(b []byte) error {
@@ -1514,7 +1592,7 @@ func (m *GetNodeInfoResponse) Reset() { *m = GetNodeInfoResponse{} }
func (m *GetNodeInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetNodeInfoResponse) ProtoMessage() {}
func (*GetNodeInfoResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{27}
+ return fileDescriptor_6960a02cc0a63cf6, []int{29}
}
func (m *GetNodeInfoResponse) XXX_Unmarshal(b []byte) error {
@@ -1559,7 +1637,7 @@ func (m *ListCurrenciesRequest) Reset() { *m = ListCurrenciesRequest{} }
func (m *ListCurrenciesRequest) String() string { return proto.CompactTextString(m) }
func (*ListCurrenciesRequest) ProtoMessage() {}
func (*ListCurrenciesRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{28}
+ return fileDescriptor_6960a02cc0a63cf6, []int{30}
}
func (m *ListCurrenciesRequest) XXX_Unmarshal(b []byte) error {
@@ -1592,7 +1670,7 @@ func (m *ListCurrenciesResponse) Reset() { *m = ListCurrenciesResponse{}
func (m *ListCurrenciesResponse) String() string { return proto.CompactTextString(m) }
func (*ListCurrenciesResponse) ProtoMessage() {}
func (*ListCurrenciesResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{29}
+ return fileDescriptor_6960a02cc0a63cf6, []int{31}
}
func (m *ListCurrenciesResponse) XXX_Unmarshal(b []byte) error {
@@ -1638,7 +1716,7 @@ func (m *ListOrdersRequest) Reset() { *m = ListOrdersRequest{} }
func (m *ListOrdersRequest) String() string { return proto.CompactTextString(m) }
func (*ListOrdersRequest) ProtoMessage() {}
func (*ListOrdersRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{30}
+ return fileDescriptor_6960a02cc0a63cf6, []int{32}
}
func (m *ListOrdersRequest) XXX_Unmarshal(b []byte) error {
@@ -1699,7 +1777,7 @@ func (m *ListOrdersResponse) Reset() { *m = ListOrdersResponse{} }
func (m *ListOrdersResponse) String() string { return proto.CompactTextString(m) }
func (*ListOrdersResponse) ProtoMessage() {}
func (*ListOrdersResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{31}
+ return fileDescriptor_6960a02cc0a63cf6, []int{33}
}
func (m *ListOrdersResponse) XXX_Unmarshal(b []byte) error {
@@ -1737,7 +1815,7 @@ func (m *ListPairsRequest) Reset() { *m = ListPairsRequest{} }
func (m *ListPairsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPairsRequest) ProtoMessage() {}
func (*ListPairsRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{32}
+ return fileDescriptor_6960a02cc0a63cf6, []int{34}
}
func (m *ListPairsRequest) XXX_Unmarshal(b []byte) error {
@@ -1770,7 +1848,7 @@ func (m *ListPairsResponse) Reset() { *m = ListPairsResponse{} }
func (m *ListPairsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPairsResponse) ProtoMessage() {}
func (*ListPairsResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{33}
+ return fileDescriptor_6960a02cc0a63cf6, []int{35}
}
func (m *ListPairsResponse) XXX_Unmarshal(b []byte) error {
@@ -1808,7 +1886,7 @@ func (m *ListPeersRequest) Reset() { *m = ListPeersRequest{} }
func (m *ListPeersRequest) String() string { return proto.CompactTextString(m) }
func (*ListPeersRequest) ProtoMessage() {}
func (*ListPeersRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{34}
+ return fileDescriptor_6960a02cc0a63cf6, []int{36}
}
func (m *ListPeersRequest) XXX_Unmarshal(b []byte) error {
@@ -1841,7 +1919,7 @@ func (m *ListPeersResponse) Reset() { *m = ListPeersResponse{} }
func (m *ListPeersResponse) String() string { return proto.CompactTextString(m) }
func (*ListPeersResponse) ProtoMessage() {}
func (*ListPeersResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{35}
+ return fileDescriptor_6960a02cc0a63cf6, []int{37}
}
func (m *ListPeersResponse) XXX_Unmarshal(b []byte) error {
@@ -1886,7 +1964,7 @@ func (m *LndInfo) Reset() { *m = LndInfo{} }
func (m *LndInfo) String() string { return proto.CompactTextString(m) }
func (*LndInfo) ProtoMessage() {}
func (*LndInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{36}
+ return fileDescriptor_6960a02cc0a63cf6, []int{38}
}
func (m *LndInfo) XXX_Unmarshal(b []byte) error {
@@ -1970,7 +2048,7 @@ func (m *NodeIdentifier) Reset() { *m = NodeIdentifier{} }
func (m *NodeIdentifier) String() string { return proto.CompactTextString(m) }
func (*NodeIdentifier) ProtoMessage() {}
func (*NodeIdentifier) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{37}
+ return fileDescriptor_6960a02cc0a63cf6, []int{39}
}
func (m *NodeIdentifier) XXX_Unmarshal(b []byte) error {
@@ -2025,7 +2103,7 @@ func (m *OpenChannelRequest) Reset() { *m = OpenChannelRequest{} }
func (m *OpenChannelRequest) String() string { return proto.CompactTextString(m) }
func (*OpenChannelRequest) ProtoMessage() {}
func (*OpenChannelRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{38}
+ return fileDescriptor_6960a02cc0a63cf6, []int{40}
}
func (m *OpenChannelRequest) XXX_Unmarshal(b []byte) error {
@@ -2093,7 +2171,7 @@ func (m *OpenChannelResponse) Reset() { *m = OpenChannelResponse{} }
func (m *OpenChannelResponse) String() string { return proto.CompactTextString(m) }
func (*OpenChannelResponse) ProtoMessage() {}
func (*OpenChannelResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{39}
+ return fileDescriptor_6960a02cc0a63cf6, []int{41}
}
func (m *OpenChannelResponse) XXX_Unmarshal(b []byte) error {
@@ -2151,7 +2229,7 @@ func (m *Order) Reset() { *m = Order{} }
func (m *Order) String() string { return proto.CompactTextString(m) }
func (*Order) ProtoMessage() {}
func (*Order) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{40}
+ return fileDescriptor_6960a02cc0a63cf6, []int{42}
}
func (m *Order) XXX_Unmarshal(b []byte) error {
@@ -2262,7 +2340,7 @@ func (m *OrderRemoval) Reset() { *m = OrderRemoval{} }
func (m *OrderRemoval) String() string { return proto.CompactTextString(m) }
func (*OrderRemoval) ProtoMessage() {}
func (*OrderRemoval) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{41}
+ return fileDescriptor_6960a02cc0a63cf6, []int{43}
}
func (m *OrderRemoval) XXX_Unmarshal(b []byte) error {
@@ -2332,7 +2410,7 @@ func (m *Orders) Reset() { *m = Orders{} }
func (m *Orders) String() string { return proto.CompactTextString(m) }
func (*Orders) ProtoMessage() {}
func (*Orders) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{42}
+ return fileDescriptor_6960a02cc0a63cf6, []int{44}
}
func (m *Orders) XXX_Unmarshal(b []byte) error {
@@ -2381,7 +2459,7 @@ func (m *OrdersCount) Reset() { *m = OrdersCount{} }
func (m *OrdersCount) String() string { return proto.CompactTextString(m) }
func (*OrdersCount) ProtoMessage() {}
func (*OrdersCount) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{43}
+ return fileDescriptor_6960a02cc0a63cf6, []int{45}
}
func (m *OrdersCount) XXX_Unmarshal(b []byte) error {
@@ -2430,7 +2508,7 @@ func (m *OrderUpdate) Reset() { *m = OrderUpdate{} }
func (m *OrderUpdate) String() string { return proto.CompactTextString(m) }
func (*OrderUpdate) ProtoMessage() {}
func (*OrderUpdate) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{44}
+ return fileDescriptor_6960a02cc0a63cf6, []int{46}
}
func (m *OrderUpdate) XXX_Unmarshal(b []byte) error {
@@ -2522,7 +2600,7 @@ func (m *Peer) Reset() { *m = Peer{} }
func (m *Peer) String() string { return proto.CompactTextString(m) }
func (*Peer) ProtoMessage() {}
func (*Peer) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{45}
+ return fileDescriptor_6960a02cc0a63cf6, []int{47}
}
func (m *Peer) XXX_Unmarshal(b []byte) error {
@@ -2624,7 +2702,7 @@ func (m *PlaceOrderRequest) Reset() { *m = PlaceOrderRequest{} }
func (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }
func (*PlaceOrderRequest) ProtoMessage() {}
func (*PlaceOrderRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{46}
+ return fileDescriptor_6960a02cc0a63cf6, []int{48}
}
func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {
@@ -2712,7 +2790,7 @@ func (m *PlaceOrderResponse) Reset() { *m = PlaceOrderResponse{} }
func (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }
func (*PlaceOrderResponse) ProtoMessage() {}
func (*PlaceOrderResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{47}
+ return fileDescriptor_6960a02cc0a63cf6, []int{49}
}
func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {
@@ -2777,7 +2855,7 @@ func (m *PlaceOrderEvent) Reset() { *m = PlaceOrderEvent{} }
func (m *PlaceOrderEvent) String() string { return proto.CompactTextString(m) }
func (*PlaceOrderEvent) ProtoMessage() {}
func (*PlaceOrderEvent) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{48}
+ return fileDescriptor_6960a02cc0a63cf6, []int{50}
}
func (m *PlaceOrderEvent) XXX_Unmarshal(b []byte) error {
@@ -2885,7 +2963,7 @@ func (m *ConnextInfo) Reset() { *m = ConnextInfo{} }
func (m *ConnextInfo) String() string { return proto.CompactTextString(m) }
func (*ConnextInfo) ProtoMessage() {}
func (*ConnextInfo) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{49}
+ return fileDescriptor_6960a02cc0a63cf6, []int{51}
}
func (m *ConnextInfo) XXX_Unmarshal(b []byte) error {
@@ -2946,7 +3024,7 @@ func (m *RemoveCurrencyRequest) Reset() { *m = RemoveCurrencyRequest{} }
func (m *RemoveCurrencyRequest) String() string { return proto.CompactTextString(m) }
func (*RemoveCurrencyRequest) ProtoMessage() {}
func (*RemoveCurrencyRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{50}
+ return fileDescriptor_6960a02cc0a63cf6, []int{52}
}
func (m *RemoveCurrencyRequest) XXX_Unmarshal(b []byte) error {
@@ -2984,7 +3062,7 @@ func (m *RemoveCurrencyResponse) Reset() { *m = RemoveCurrencyResponse{}
func (m *RemoveCurrencyResponse) String() string { return proto.CompactTextString(m) }
func (*RemoveCurrencyResponse) ProtoMessage() {}
func (*RemoveCurrencyResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{51}
+ return fileDescriptor_6960a02cc0a63cf6, []int{53}
}
func (m *RemoveCurrencyResponse) XXX_Unmarshal(b []byte) error {
@@ -3020,7 +3098,7 @@ func (m *RemoveOrderRequest) Reset() { *m = RemoveOrderRequest{} }
func (m *RemoveOrderRequest) String() string { return proto.CompactTextString(m) }
func (*RemoveOrderRequest) ProtoMessage() {}
func (*RemoveOrderRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{52}
+ return fileDescriptor_6960a02cc0a63cf6, []int{54}
}
func (m *RemoveOrderRequest) XXX_Unmarshal(b []byte) error {
@@ -3074,7 +3152,7 @@ func (m *RemoveOrderResponse) Reset() { *m = RemoveOrderResponse{} }
func (m *RemoveOrderResponse) String() string { return proto.CompactTextString(m) }
func (*RemoveOrderResponse) ProtoMessage() {}
func (*RemoveOrderResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{53}
+ return fileDescriptor_6960a02cc0a63cf6, []int{55}
}
func (m *RemoveOrderResponse) XXX_Unmarshal(b []byte) error {
@@ -3133,7 +3211,7 @@ func (m *RemoveAllOrdersRequest) Reset() { *m = RemoveAllOrdersRequest{}
func (m *RemoveAllOrdersRequest) String() string { return proto.CompactTextString(m) }
func (*RemoveAllOrdersRequest) ProtoMessage() {}
func (*RemoveAllOrdersRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{54}
+ return fileDescriptor_6960a02cc0a63cf6, []int{56}
}
func (m *RemoveAllOrdersRequest) XXX_Unmarshal(b []byte) error {
@@ -3168,7 +3246,7 @@ func (m *RemoveAllOrdersResponse) Reset() { *m = RemoveAllOrdersResponse
func (m *RemoveAllOrdersResponse) String() string { return proto.CompactTextString(m) }
func (*RemoveAllOrdersResponse) ProtoMessage() {}
func (*RemoveAllOrdersResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{55}
+ return fileDescriptor_6960a02cc0a63cf6, []int{57}
}
func (m *RemoveAllOrdersResponse) XXX_Unmarshal(b []byte) error {
@@ -3215,7 +3293,7 @@ func (m *RemovePairRequest) Reset() { *m = RemovePairRequest{} }
func (m *RemovePairRequest) String() string { return proto.CompactTextString(m) }
func (*RemovePairRequest) ProtoMessage() {}
func (*RemovePairRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{56}
+ return fileDescriptor_6960a02cc0a63cf6, []int{58}
}
func (m *RemovePairRequest) XXX_Unmarshal(b []byte) error {
@@ -3253,7 +3331,7 @@ func (m *RemovePairResponse) Reset() { *m = RemovePairResponse{} }
func (m *RemovePairResponse) String() string { return proto.CompactTextString(m) }
func (*RemovePairResponse) ProtoMessage() {}
func (*RemovePairResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{57}
+ return fileDescriptor_6960a02cc0a63cf6, []int{59}
}
func (m *RemovePairResponse) XXX_Unmarshal(b []byte) error {
@@ -3293,7 +3371,7 @@ func (m *RestoreNodeRequest) Reset() { *m = RestoreNodeRequest{} }
func (m *RestoreNodeRequest) String() string { return proto.CompactTextString(m) }
func (*RestoreNodeRequest) ProtoMessage() {}
func (*RestoreNodeRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{58}
+ return fileDescriptor_6960a02cc0a63cf6, []int{60}
}
func (m *RestoreNodeRequest) XXX_Unmarshal(b []byte) error {
@@ -3356,7 +3434,7 @@ func (m *RestoreNodeResponse) Reset() { *m = RestoreNodeResponse{} }
func (m *RestoreNodeResponse) String() string { return proto.CompactTextString(m) }
func (*RestoreNodeResponse) ProtoMessage() {}
func (*RestoreNodeResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{59}
+ return fileDescriptor_6960a02cc0a63cf6, []int{61}
}
func (m *RestoreNodeResponse) XXX_Unmarshal(b []byte) error {
@@ -3402,7 +3480,7 @@ func (m *SetLogLevelRequest) Reset() { *m = SetLogLevelRequest{} }
func (m *SetLogLevelRequest) String() string { return proto.CompactTextString(m) }
func (*SetLogLevelRequest) ProtoMessage() {}
func (*SetLogLevelRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{60}
+ return fileDescriptor_6960a02cc0a63cf6, []int{62}
}
func (m *SetLogLevelRequest) XXX_Unmarshal(b []byte) error {
@@ -3440,7 +3518,7 @@ func (m *SetLogLevelResponse) Reset() { *m = SetLogLevelResponse{} }
func (m *SetLogLevelResponse) String() string { return proto.CompactTextString(m) }
func (*SetLogLevelResponse) ProtoMessage() {}
func (*SetLogLevelResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{61}
+ return fileDescriptor_6960a02cc0a63cf6, []int{63}
}
func (m *SetLogLevelResponse) XXX_Unmarshal(b []byte) error {
@@ -3471,7 +3549,7 @@ func (m *ShutdownRequest) Reset() { *m = ShutdownRequest{} }
func (m *ShutdownRequest) String() string { return proto.CompactTextString(m) }
func (*ShutdownRequest) ProtoMessage() {}
func (*ShutdownRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{62}
+ return fileDescriptor_6960a02cc0a63cf6, []int{64}
}
func (m *ShutdownRequest) XXX_Unmarshal(b []byte) error {
@@ -3502,7 +3580,7 @@ func (m *ShutdownResponse) Reset() { *m = ShutdownResponse{} }
func (m *ShutdownResponse) String() string { return proto.CompactTextString(m) }
func (*ShutdownResponse) ProtoMessage() {}
func (*ShutdownResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{63}
+ return fileDescriptor_6960a02cc0a63cf6, []int{65}
}
func (m *ShutdownResponse) XXX_Unmarshal(b []byte) error {
@@ -3535,7 +3613,7 @@ func (m *SubscribeOrdersRequest) Reset() { *m = SubscribeOrdersRequest{}
func (m *SubscribeOrdersRequest) String() string { return proto.CompactTextString(m) }
func (*SubscribeOrdersRequest) ProtoMessage() {}
func (*SubscribeOrdersRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{64}
+ return fileDescriptor_6960a02cc0a63cf6, []int{66}
}
func (m *SubscribeOrdersRequest) XXX_Unmarshal(b []byte) error {
@@ -3573,7 +3651,7 @@ func (m *SubscribeSwapsAcceptedRequest) Reset() { *m = SubscribeSwapsAcc
func (m *SubscribeSwapsAcceptedRequest) String() string { return proto.CompactTextString(m) }
func (*SubscribeSwapsAcceptedRequest) ProtoMessage() {}
func (*SubscribeSwapsAcceptedRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{65}
+ return fileDescriptor_6960a02cc0a63cf6, []int{67}
}
func (m *SubscribeSwapsAcceptedRequest) XXX_Unmarshal(b []byte) error {
@@ -3607,7 +3685,7 @@ func (m *SubscribeSwapsRequest) Reset() { *m = SubscribeSwapsRequest{} }
func (m *SubscribeSwapsRequest) String() string { return proto.CompactTextString(m) }
func (*SubscribeSwapsRequest) ProtoMessage() {}
func (*SubscribeSwapsRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{66}
+ return fileDescriptor_6960a02cc0a63cf6, []int{68}
}
func (m *SubscribeSwapsRequest) XXX_Unmarshal(b []byte) error {
@@ -3667,7 +3745,7 @@ func (m *SwapAccepted) Reset() { *m = SwapAccepted{} }
func (m *SwapAccepted) String() string { return proto.CompactTextString(m) }
func (*SwapAccepted) ProtoMessage() {}
func (*SwapAccepted) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{67}
+ return fileDescriptor_6960a02cc0a63cf6, []int{69}
}
func (m *SwapAccepted) XXX_Unmarshal(b []byte) error {
@@ -3785,7 +3863,7 @@ func (m *SwapFailure) Reset() { *m = SwapFailure{} }
func (m *SwapFailure) String() string { return proto.CompactTextString(m) }
func (*SwapFailure) ProtoMessage() {}
func (*SwapFailure) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{68}
+ return fileDescriptor_6960a02cc0a63cf6, []int{70}
}
func (m *SwapFailure) XXX_Unmarshal(b []byte) error {
@@ -3877,7 +3955,7 @@ func (m *SwapSuccess) Reset() { *m = SwapSuccess{} }
func (m *SwapSuccess) String() string { return proto.CompactTextString(m) }
func (*SwapSuccess) ProtoMessage() {}
func (*SwapSuccess) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{69}
+ return fileDescriptor_6960a02cc0a63cf6, []int{71}
}
func (m *SwapSuccess) XXX_Unmarshal(b []byte) error {
@@ -4021,7 +4099,7 @@ func (m *Trade) Reset() { *m = Trade{} }
func (m *Trade) String() string { return proto.CompactTextString(m) }
func (*Trade) ProtoMessage() {}
func (*Trade) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{70}
+ return fileDescriptor_6960a02cc0a63cf6, []int{72}
}
func (m *Trade) XXX_Unmarshal(b []byte) error {
@@ -4124,7 +4202,7 @@ func (m *TradeHistoryRequest) Reset() { *m = TradeHistoryRequest{} }
func (m *TradeHistoryRequest) String() string { return proto.CompactTextString(m) }
func (*TradeHistoryRequest) ProtoMessage() {}
func (*TradeHistoryRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{71}
+ return fileDescriptor_6960a02cc0a63cf6, []int{73}
}
func (m *TradeHistoryRequest) XXX_Unmarshal(b []byte) error {
@@ -4163,7 +4241,7 @@ func (m *TradeHistoryResponse) Reset() { *m = TradeHistoryResponse{} }
func (m *TradeHistoryResponse) String() string { return proto.CompactTextString(m) }
func (*TradeHistoryResponse) ProtoMessage() {}
func (*TradeHistoryResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{72}
+ return fileDescriptor_6960a02cc0a63cf6, []int{74}
}
func (m *TradeHistoryResponse) XXX_Unmarshal(b []byte) error {
@@ -4209,7 +4287,7 @@ func (m *TradingLimits) Reset() { *m = TradingLimits{} }
func (m *TradingLimits) String() string { return proto.CompactTextString(m) }
func (*TradingLimits) ProtoMessage() {}
func (*TradingLimits) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{73}
+ return fileDescriptor_6960a02cc0a63cf6, []int{75}
}
func (m *TradingLimits) XXX_Unmarshal(b []byte) error {
@@ -4271,7 +4349,7 @@ func (m *TradingLimitsRequest) Reset() { *m = TradingLimitsRequest{} }
func (m *TradingLimitsRequest) String() string { return proto.CompactTextString(m) }
func (*TradingLimitsRequest) ProtoMessage() {}
func (*TradingLimitsRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{74}
+ return fileDescriptor_6960a02cc0a63cf6, []int{76}
}
func (m *TradingLimitsRequest) XXX_Unmarshal(b []byte) error {
@@ -4311,7 +4389,7 @@ func (m *TradingLimitsResponse) Reset() { *m = TradingLimitsResponse{} }
func (m *TradingLimitsResponse) String() string { return proto.CompactTextString(m) }
func (*TradingLimitsResponse) ProtoMessage() {}
func (*TradingLimitsResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{75}
+ return fileDescriptor_6960a02cc0a63cf6, []int{77}
}
func (m *TradingLimitsResponse) XXX_Unmarshal(b []byte) error {
@@ -4353,7 +4431,7 @@ func (m *UnbanRequest) Reset() { *m = UnbanRequest{} }
func (m *UnbanRequest) String() string { return proto.CompactTextString(m) }
func (*UnbanRequest) ProtoMessage() {}
func (*UnbanRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{76}
+ return fileDescriptor_6960a02cc0a63cf6, []int{78}
}
func (m *UnbanRequest) XXX_Unmarshal(b []byte) error {
@@ -4398,7 +4476,7 @@ func (m *UnbanResponse) Reset() { *m = UnbanResponse{} }
func (m *UnbanResponse) String() string { return proto.CompactTextString(m) }
func (*UnbanResponse) ProtoMessage() {}
func (*UnbanResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{77}
+ return fileDescriptor_6960a02cc0a63cf6, []int{79}
}
func (m *UnbanResponse) XXX_Unmarshal(b []byte) error {
@@ -4432,7 +4510,7 @@ func (m *UnlockNodeRequest) Reset() { *m = UnlockNodeRequest{} }
func (m *UnlockNodeRequest) String() string { return proto.CompactTextString(m) }
func (*UnlockNodeRequest) ProtoMessage() {}
func (*UnlockNodeRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{78}
+ return fileDescriptor_6960a02cc0a63cf6, []int{80}
}
func (m *UnlockNodeRequest) XXX_Unmarshal(b []byte) error {
@@ -4474,7 +4552,7 @@ func (m *UnlockNodeResponse) Reset() { *m = UnlockNodeResponse{} }
func (m *UnlockNodeResponse) String() string { return proto.CompactTextString(m) }
func (*UnlockNodeResponse) ProtoMessage() {}
func (*UnlockNodeResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{79}
+ return fileDescriptor_6960a02cc0a63cf6, []int{81}
}
func (m *UnlockNodeResponse) XXX_Unmarshal(b []byte) error {
@@ -4530,7 +4608,7 @@ func (m *WithdrawRequest) Reset() { *m = WithdrawRequest{} }
func (m *WithdrawRequest) String() string { return proto.CompactTextString(m) }
func (*WithdrawRequest) ProtoMessage() {}
func (*WithdrawRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{80}
+ return fileDescriptor_6960a02cc0a63cf6, []int{82}
}
func (m *WithdrawRequest) XXX_Unmarshal(b []byte) error {
@@ -4598,7 +4676,7 @@ func (m *WithdrawResponse) Reset() { *m = WithdrawResponse{} }
func (m *WithdrawResponse) String() string { return proto.CompactTextString(m) }
func (*WithdrawResponse) ProtoMessage() {}
func (*WithdrawResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{81}
+ return fileDescriptor_6960a02cc0a63cf6, []int{83}
}
func (m *WithdrawResponse) XXX_Unmarshal(b []byte) error {
@@ -4640,6 +4718,8 @@ func init() {
proto.RegisterType((*BanResponse)(nil), "xudrpc.BanResponse")
proto.RegisterType((*Chain)(nil), "xudrpc.Chain")
proto.RegisterType((*Channels)(nil), "xudrpc.Channels")
+ proto.RegisterType((*ChangePasswordRequest)(nil), "xudrpc.ChangePasswordRequest")
+ proto.RegisterType((*ChangePasswordResponse)(nil), "xudrpc.ChangePasswordResponse")
proto.RegisterType((*CloseChannelRequest)(nil), "xudrpc.CloseChannelRequest")
proto.RegisterType((*CloseChannelResponse)(nil), "xudrpc.CloseChannelResponse")
proto.RegisterType((*ConnectRequest)(nil), "xudrpc.ConnectRequest")
@@ -4725,264 +4805,268 @@ func init() {
func init() { proto.RegisterFile("xudrpc.proto", fileDescriptor_6960a02cc0a63cf6) }
var fileDescriptor_6960a02cc0a63cf6 = []byte{
- // 4097 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3b, 0x4d, 0x6c, 0x1c, 0xc9,
- 0x5a, 0xee, 0xf9, 0xf1, 0x8c, 0xbf, 0xf9, 0x75, 0xf9, 0x27, 0x93, 0xd9, 0xec, 0x6e, 0x5e, 0xb1,
- 0x59, 0x65, 0xbd, 0xbb, 0x4e, 0xf0, 0xf2, 0xd8, 0xb7, 0x79, 0x64, 0xb5, 0xb6, 0x33, 0x2f, 0xc9,
- 0xae, 0x9f, 0x1d, 0xb5, 0x93, 0x4d, 0x78, 0x82, 0xd7, 0xea, 0xe9, 0xae, 0xd8, 0x4d, 0xda, 0xdd,
- 0xb3, 0xdd, 0x3d, 0x76, 0x0c, 0x17, 0xf4, 0xc4, 0x09, 0x0e, 0x1c, 0x10, 0x67, 0x38, 0x21, 0x24,
- 0x10, 0x57, 0x4e, 0x48, 0x9c, 0xb9, 0x72, 0x40, 0x02, 0x2e, 0x48, 0xdc, 0x91, 0x10, 0x57, 0x24,
- 0x54, 0x7f, 0x5d, 0x55, 0xdd, 0x3d, 0x7e, 0xc9, 0x0a, 0xb8, 0x4d, 0x7d, 0xf5, 0xf5, 0xf7, 0x55,
- 0x7d, 0xff, 0xf5, 0x55, 0x0d, 0x74, 0x5f, 0xcf, 0xfd, 0x64, 0xe6, 0x6d, 0xcf, 0x92, 0x38, 0x8b,
- 0xd1, 0x32, 0x1f, 0x8d, 0x57, 0xdd, 0x28, 0x8a, 0x33, 0x37, 0x0b, 0xe2, 0x28, 0xe5, 0x53, 0x78,
- 0x03, 0xd6, 0x76, 0x7d, 0x7f, 0x7f, 0x9e, 0x24, 0x24, 0xf2, 0x2e, 0x6d, 0x92, 0xce, 0xe2, 0x28,
- 0x25, 0xf8, 0xe7, 0xd0, 0xdf, 0xf5, 0xfd, 0x27, 0x6e, 0x90, 0xd8, 0xe4, 0xbb, 0x39, 0x49, 0x33,
- 0xf4, 0x01, 0xf4, 0xa6, 0x6e, 0x4a, 0x1c, 0x4f, 0xa0, 0x8e, 0xac, 0x9b, 0xd6, 0xed, 0x15, 0xdb,
- 0x04, 0xa2, 0x0f, 0xa1, 0xff, 0xdd, 0x3c, 0xce, 0x34, 0xb4, 0x1a, 0x43, 0x2b, 0x40, 0xf1, 0x2a,
- 0x0c, 0x72, 0xfa, 0x82, 0xe5, 0xdf, 0xd6, 0xa0, 0xb5, 0xe7, 0x86, 0x6e, 0xe4, 0x11, 0xca, 0x2c,
- 0x8b, 0x33, 0x37, 0x74, 0xa6, 0x1c, 0xc0, 0x98, 0x35, 0x6c, 0x13, 0x88, 0x6e, 0xc3, 0xc0, 0x3b,
- 0x75, 0xa3, 0x88, 0x28, 0xbc, 0x1a, 0xc3, 0x2b, 0x82, 0xd1, 0x8f, 0xe0, 0xda, 0x8c, 0x44, 0x7e,
- 0x10, 0x9d, 0x38, 0xc5, 0x2f, 0xea, 0xec, 0x8b, 0x45, 0xd3, 0xe8, 0x1e, 0x8c, 0x82, 0xc8, 0xf5,
- 0xb2, 0xe0, 0x9c, 0x94, 0x3e, 0x6d, 0xb0, 0x4f, 0x17, 0xce, 0x53, 0x61, 0x5c, 0xb8, 0x61, 0x48,
- 0xb2, 0xfc, 0x8b, 0x26, 0xfb, 0xa2, 0x00, 0x45, 0x5f, 0xc2, 0x78, 0x1e, 0x79, 0x71, 0xf4, 0x32,
- 0x48, 0xce, 0x88, 0xef, 0x14, 0xbe, 0x59, 0x66, 0xdf, 0x5c, 0x81, 0x81, 0x7f, 0x1d, 0x60, 0xcf,
- 0x8d, 0xa4, 0xa2, 0x6e, 0xc3, 0x20, 0x8a, 0x7d, 0xe2, 0x04, 0x3e, 0x89, 0xb2, 0xe0, 0x65, 0x40,
- 0x12, 0xa1, 0xaa, 0x22, 0x18, 0xf7, 0xa0, 0xc3, 0xbe, 0x13, 0x0a, 0xf8, 0x1c, 0x9a, 0xfb, 0xa7,
- 0x6e, 0x10, 0xa1, 0x75, 0x68, 0x7a, 0xf4, 0x87, 0xf8, 0x8e, 0x0f, 0xd0, 0x08, 0x5a, 0x11, 0xc9,
- 0x2e, 0xe2, 0xe4, 0x95, 0xd0, 0xa9, 0x1c, 0xe2, 0x19, 0xb4, 0xf7, 0xf9, 0xd6, 0x53, 0xb4, 0x09,
- 0xcb, 0x5c, 0x1a, 0xec, 0xe3, 0x9e, 0x2d, 0x46, 0x68, 0x0c, 0x6d, 0x29, 0x27, 0xf6, 0x79, 0xcf,
- 0xce, 0xc7, 0x94, 0xb2, 0x10, 0x3f, 0xd3, 0x46, 0xcf, 0x96, 0x43, 0x4a, 0xcd, 0x0b, 0xe3, 0x94,
- 0xf8, 0x4c, 0xd6, 0x3d, 0x5b, 0x8c, 0xf0, 0xdf, 0x59, 0xb0, 0xb6, 0x4f, 0x7f, 0x0a, 0xbe, 0x6f,
- 0xbd, 0x77, 0xba, 0x9e, 0x82, 0x89, 0xe6, 0x63, 0xba, 0xff, 0x97, 0x71, 0x22, 0x6c, 0xa3, 0x6d,
- 0xf3, 0x01, 0xba, 0x09, 0x1d, 0x9f, 0xa4, 0x59, 0x10, 0x31, 0xff, 0x61, 0x0b, 0x5a, 0xb1, 0x75,
- 0x10, 0xdb, 0xfb, 0x59, 0x3c, 0x8f, 0x32, 0xa1, 0x67, 0x31, 0x42, 0x43, 0xa8, 0xbf, 0x24, 0x52,
- 0x91, 0xf4, 0x27, 0xfe, 0x0a, 0xd6, 0xcd, 0xe5, 0x73, 0x15, 0xd0, 0xf5, 0x67, 0x89, 0x1b, 0xa5,
- 0x54, 0x30, 0x71, 0xe4, 0x04, 0x7e, 0x3a, 0xb2, 0x6e, 0xd6, 0xe9, 0xfa, 0x0b, 0x60, 0xfc, 0x09,
- 0xf4, 0xf7, 0xe3, 0x28, 0x22, 0x5e, 0x26, 0xf7, 0x3e, 0x86, 0x36, 0xdb, 0xe4, 0x3c, 0x09, 0xc4,
- 0xa6, 0xf3, 0x31, 0x75, 0xb7, 0x1c, 0x5b, 0x68, 0xfb, 0x0e, 0xac, 0xee, 0x27, 0xc4, 0xcd, 0xc8,
- 0x61, 0xec, 0x13, 0x8d, 0xc6, 0xcc, 0x4d, 0xd3, 0x8b, 0x38, 0xf1, 0x25, 0x0d, 0x39, 0xc6, 0x7f,
- 0x6a, 0x01, 0xd2, 0xbf, 0x10, 0x4b, 0xfe, 0x15, 0xe8, 0xa5, 0x84, 0xf8, 0xce, 0x59, 0x44, 0xce,
- 0xe2, 0x28, 0xf0, 0xc4, 0x82, 0xbb, 0x14, 0xf8, 0x53, 0x01, 0x43, 0x1f, 0xc1, 0x30, 0x88, 0x82,
- 0x2c, 0x70, 0xc3, 0xe0, 0x77, 0x89, 0xef, 0x84, 0x91, 0x9f, 0x8e, 0x6a, 0x7c, 0x63, 0x1a, 0xfc,
- 0x20, 0xf2, 0x53, 0x74, 0x07, 0xd6, 0x74, 0x54, 0x8f, 0x2e, 0xfb, 0x75, 0x26, 0x54, 0x81, 0xb4,
- 0xa9, 0x7d, 0x3e, 0x83, 0xff, 0xc9, 0x82, 0xb6, 0x8c, 0x5f, 0x86, 0x5a, 0xad, 0x82, 0x5a, 0xef,
- 0x43, 0x27, 0xbd, 0x70, 0x67, 0x8e, 0x17, 0x06, 0x24, 0xca, 0x98, 0xd6, 0xfb, 0x3b, 0xef, 0x6c,
- 0x8b, 0x48, 0x29, 0x49, 0x6c, 0x1f, 0x5f, 0xb8, 0xb3, 0x7d, 0x86, 0x62, 0xeb, 0xf8, 0x3c, 0x26,
- 0xbd, 0x22, 0x91, 0xe3, 0xfa, 0x7e, 0x42, 0xd2, 0x94, 0x2d, 0x69, 0xc5, 0x36, 0x81, 0xd4, 0xe7,
- 0x7d, 0xe2, 0x05, 0x67, 0x6e, 0xe8, 0xcc, 0x42, 0xd7, 0x23, 0xa9, 0xb0, 0xdc, 0x02, 0x14, 0x63,
- 0x00, 0xc5, 0x08, 0xb5, 0xa0, 0x7e, 0x70, 0xf8, 0x60, 0xb8, 0x84, 0x3a, 0xd0, 0xda, 0x3f, 0x3a,
- 0x3c, 0x9c, 0xbc, 0x78, 0x3a, 0xac, 0x51, 0x1d, 0x3f, 0x20, 0xb3, 0x38, 0x0d, 0x74, 0x1d, 0x2f,
- 0xda, 0x1e, 0xfe, 0x18, 0x06, 0x39, 0xb6, 0xd0, 0xcd, 0x08, 0x5a, 0x72, 0xb1, 0x1c, 0x5b, 0x0e,
- 0xa9, 0x01, 0x3e, 0x08, 0x52, 0x2f, 0x3e, 0x27, 0x09, 0xd5, 0x66, 0xfa, 0xf6, 0xc1, 0xe3, 0x87,
- 0xb0, 0x51, 0xa0, 0x20, 0x98, 0xde, 0x80, 0x95, 0x68, 0x7e, 0xe6, 0x50, 0xfc, 0x54, 0x04, 0x01,
- 0x05, 0xc0, 0x7f, 0x68, 0x01, 0x9a, 0xbc, 0x26, 0xde, 0x3c, 0x23, 0x74, 0xff, 0xda, 0xc6, 0xe2,
- 0xc4, 0x27, 0x89, 0x13, 0xe4, 0x86, 0x27, 0xc7, 0x2c, 0x3c, 0xb8, 0x01, 0x9b, 0x12, 0x81, 0x47,
- 0x0c, 0x11, 0x86, 0xee, 0x8c, 0x90, 0xc4, 0x99, 0xcd, 0xa7, 0xce, 0x2b, 0x72, 0x29, 0x34, 0x62,
- 0xc0, 0x28, 0xe5, 0xef, 0xe6, 0x6e, 0x94, 0x05, 0xd9, 0xa5, 0x08, 0xd8, 0xf9, 0x98, 0xfa, 0xc0,
- 0x43, 0x92, 0x89, 0xa4, 0xf3, 0x26, 0x32, 0xfe, 0x4b, 0x0b, 0x90, 0xfe, 0x85, 0xd8, 0xf2, 0x03,
- 0x68, 0x8b, 0x58, 0xcc, 0xfd, 0xb5, 0xb3, 0x73, 0x5b, 0x9a, 0x55, 0x19, 0x7b, 0x5b, 0x8c, 0xd3,
- 0x49, 0x94, 0x25, 0x97, 0x76, 0xfe, 0xe5, 0xf8, 0x00, 0x7a, 0xc6, 0x14, 0x8d, 0x1b, 0x74, 0x57,
- 0x7c, 0x11, 0xf4, 0x27, 0xba, 0x05, 0xcd, 0x73, 0x37, 0x9c, 0xf3, 0x10, 0xda, 0xd9, 0x19, 0x48,
- 0x2e, 0x92, 0x05, 0x9f, 0xbd, 0x57, 0xfb, 0x91, 0x85, 0x87, 0xd0, 0x7f, 0x48, 0xb2, 0xc7, 0xd1,
- 0xcb, 0x58, 0x6c, 0x0c, 0xff, 0x73, 0x1d, 0x06, 0x39, 0x48, 0x59, 0xc8, 0x39, 0x49, 0x52, 0x1a,
- 0xd0, 0x84, 0x85, 0x88, 0x21, 0x95, 0x2d, 0x53, 0xb9, 0x94, 0x2d, 0x17, 0xbd, 0x01, 0x43, 0x08,
- 0x1a, 0xf3, 0x24, 0xa0, 0x9e, 0x40, 0x5d, 0x99, 0xfd, 0x96, 0xea, 0xa7, 0x3a, 0x90, 0xb6, 0xaf,
- 0x00, 0xf9, 0xac, 0x1b, 0x24, 0x29, 0x8b, 0x92, 0x72, 0x96, 0x02, 0xd0, 0xc7, 0xb0, 0xcc, 0xb4,
- 0x9e, 0xb2, 0x58, 0xd9, 0xd9, 0x59, 0x93, 0xfb, 0x3b, 0x62, 0xd0, 0x7d, 0x1a, 0x4d, 0x6d, 0x81,
- 0x82, 0x76, 0xa0, 0x1e, 0x46, 0xfe, 0xa8, 0xc5, 0xe4, 0x7d, 0x53, 0x93, 0xb7, 0xbe, 0xc1, 0xed,
- 0x83, 0xc8, 0xe7, 0x72, 0xa6, 0xc8, 0x34, 0xb2, 0xbb, 0x61, 0xe0, 0xa6, 0xa3, 0x15, 0x9e, 0xd9,
- 0xd8, 0x40, 0xcf, 0x6c, 0x60, 0x64, 0x36, 0x74, 0x17, 0xd6, 0x64, 0x61, 0xc0, 0x42, 0xc1, 0xa9,
- 0x9b, 0x9e, 0x92, 0x74, 0xd4, 0x61, 0xfb, 0xad, 0x9a, 0x42, 0x9f, 0x42, 0x4b, 0x86, 0xac, 0xae,
- 0xb9, 0x07, 0x11, 0xaf, 0xd8, 0xea, 0x24, 0xce, 0xf8, 0x21, 0xb4, 0xe5, 0x0a, 0xdf, 0x42, 0xdd,
- 0x07, 0x91, 0xcf, 0xc8, 0x68, 0xea, 0x5e, 0x67, 0x86, 0x29, 0x03, 0xae, 0x54, 0xf9, 0x8f, 0x61,
- 0xcd, 0x80, 0x0a, 0xad, 0x7f, 0x50, 0x1d, 0xb3, 0x4d, 0x20, 0xfe, 0x92, 0x91, 0xa4, 0xce, 0xad,
- 0x59, 0xd1, 0x5b, 0x44, 0x08, 0x9b, 0x31, 0x57, 0xdf, 0xe7, 0x09, 0x63, 0x90, 0x90, 0xd9, 0x9c,
- 0x97, 0xa1, 0xc7, 0x5e, 0x9c, 0xf0, 0x52, 0x61, 0xd5, 0x06, 0x05, 0xa6, 0xa9, 0x74, 0x4a, 0x53,
- 0x23, 0x77, 0xf9, 0xb6, 0x2d, 0x46, 0xf8, 0x1a, 0x6c, 0x1c, 0x04, 0x69, 0x26, 0x82, 0x75, 0x90,
- 0x07, 0x2e, 0xfc, 0x35, 0x6c, 0x16, 0x27, 0x04, 0xbf, 0xbb, 0x00, 0x5e, 0x0e, 0x15, 0xee, 0x39,
- 0x2c, 0x46, 0x7d, 0x5b, 0xc3, 0xc1, 0xff, 0x60, 0xc1, 0x2a, 0x25, 0xc6, 0xad, 0x4e, 0x6e, 0x5c,
- 0x0b, 0x43, 0x96, 0x19, 0x86, 0x7e, 0x08, 0xcd, 0xf8, 0x22, 0x22, 0x89, 0x48, 0x29, 0xef, 0xe7,
- 0x6a, 0x2a, 0xd2, 0xd8, 0x3e, 0xa2, 0x68, 0x36, 0xc7, 0xa6, 0xc6, 0x18, 0x06, 0x67, 0x41, 0x26,
- 0x8a, 0x1e, 0x3e, 0xa0, 0xf2, 0x0d, 0x22, 0x2f, 0x9c, 0xfb, 0xc4, 0x61, 0xd6, 0x29, 0x32, 0x48,
- 0xdb, 0x2e, 0x82, 0xf1, 0x07, 0xd0, 0x64, 0xf4, 0x50, 0x1b, 0x1a, 0x7b, 0x47, 0x4f, 0x1f, 0x0d,
- 0x97, 0x68, 0x1e, 0x39, 0x7a, 0x7e, 0x38, 0xb4, 0x28, 0xe8, 0xc9, 0x64, 0x62, 0x0f, 0x6b, 0xf8,
- 0xcf, 0x2c, 0x40, 0xfa, 0x42, 0x84, 0x54, 0xbe, 0xcc, 0x5d, 0x8d, 0x4b, 0xe4, 0xc3, 0xaa, 0x45,
- 0x0b, 0x1f, 0xe2, 0x43, 0xee, 0x46, 0xe2, 0xab, 0xf1, 0x63, 0xe8, 0x68, 0xe0, 0x0a, 0xdb, 0xfd,
- 0xc0, 0xb4, 0xdd, 0xbe, 0xe9, 0xca, 0xba, 0xe9, 0x22, 0x18, 0x52, 0xa6, 0xf4, 0x30, 0x90, 0xab,
- 0xf3, 0x23, 0xae, 0x01, 0x01, 0x13, 0x6b, 0x5e, 0x87, 0x26, 0x0f, 0x1c, 0xdc, 0x5c, 0xf9, 0x20,
- 0xff, 0x9c, 0x28, 0x39, 0xe3, 0xcf, 0xc5, 0xe7, 0x44, 0xdf, 0x32, 0x86, 0x26, 0x8f, 0x4a, 0x7c,
- 0xc7, 0x5d, 0xb9, 0x22, 0x8a, 0x65, 0xf3, 0x29, 0xfc, 0xaf, 0x16, 0xb4, 0x84, 0x77, 0x51, 0x1b,
- 0x4c, 0x33, 0x37, 0x9b, 0xcb, 0xe4, 0x29, 0x46, 0xe8, 0x13, 0x68, 0x8b, 0x4a, 0x3f, 0x15, 0x9b,
- 0x53, 0xe6, 0x24, 0xe0, 0x76, 0x8e, 0x81, 0x6e, 0xc1, 0x32, 0xab, 0x9f, 0x79, 0x94, 0xec, 0xec,
- 0xf4, 0x34, 0xdc, 0x20, 0xb2, 0xc5, 0x24, 0xad, 0x2e, 0xa7, 0x61, 0xec, 0xbd, 0x3a, 0x25, 0xc1,
- 0xc9, 0x69, 0x26, 0x02, 0xa7, 0x0e, 0xca, 0x83, 0x6d, 0x53, 0x0b, 0xb6, 0x5a, 0xf8, 0x5e, 0x36,
- 0xc3, 0x77, 0x1e, 0xe9, 0x5a, 0x5a, 0xa4, 0xc3, 0x5f, 0x43, 0x9f, 0xf9, 0xa3, 0xaa, 0x83, 0x8b,
- 0x61, 0xde, 0xaa, 0x08, 0xf3, 0x39, 0xad, 0x9a, 0x4e, 0xeb, 0x2f, 0x2c, 0x40, 0x47, 0x33, 0x12,
- 0xfd, 0x9f, 0x94, 0xe0, 0xaa, 0x94, 0xae, 0x1b, 0xa5, 0xf4, 0x4d, 0xe8, 0xcc, 0xe6, 0xe9, 0xa9,
- 0x23, 0x26, 0x79, 0x42, 0xd7, 0x41, 0xb2, 0xd8, 0x6e, 0xaa, 0x62, 0xfb, 0x3e, 0xac, 0x19, 0xeb,
- 0x14, 0xe6, 0xf0, 0x21, 0xf4, 0xcd, 0xa2, 0x5a, 0xac, 0xb3, 0x00, 0xc5, 0x7f, 0x5f, 0x83, 0x26,
- 0x33, 0x5a, 0x66, 0x7f, 0x49, 0x20, 0x4e, 0xa3, 0x96, 0xcd, 0x07, 0x46, 0x81, 0x51, 0x33, 0x0b,
- 0x0c, 0x3d, 0x66, 0xd4, 0xcd, 0x98, 0xd1, 0x87, 0x5a, 0xe0, 0x8b, 0x43, 0x44, 0x2d, 0xf0, 0xd1,
- 0x57, 0x65, 0xb1, 0x35, 0x99, 0x6d, 0x6d, 0x4a, 0x7b, 0x31, 0x15, 0x57, 0x29, 0xce, 0x30, 0xf6,
- 0xdc, 0x90, 0x32, 0xe3, 0xc6, 0x90, 0x8f, 0xd1, 0x7b, 0x00, 0x1e, 0x2b, 0xdd, 0x7d, 0xc7, 0xcd,
- 0x98, 0x49, 0x34, 0x6c, 0x0d, 0x82, 0x6e, 0x41, 0x23, 0x0d, 0x7c, 0x32, 0x6a, 0xb3, 0x00, 0xb6,
- 0x6a, 0xf8, 0xea, 0x71, 0xe0, 0x13, 0x9b, 0x4d, 0x53, 0x63, 0x09, 0x52, 0x27, 0xbe, 0x88, 0x1c,
- 0x16, 0x05, 0x58, 0x16, 0x6d, 0xdb, 0x06, 0x8c, 0x9a, 0xe9, 0x69, 0x1c, 0xfa, 0x2c, 0x93, 0x36,
- 0x6c, 0xf6, 0x1b, 0xff, 0xb9, 0x05, 0x5d, 0x46, 0xcb, 0x26, 0x67, 0xf1, 0xb9, 0x1b, 0x1a, 0x32,
- 0xb3, 0x16, 0xcb, 0xac, 0x50, 0xee, 0xe9, 0x45, 0x62, 0xbd, 0x50, 0x24, 0xea, 0xbb, 0x6f, 0x14,
- 0x76, 0x5f, 0x5c, 0x76, 0xb3, 0xbc, 0x6c, 0x7c, 0x0a, 0xcb, 0x3c, 0x32, 0xa1, 0x4f, 0x01, 0xa6,
- 0xf3, 0x4b, 0xc7, 0x88, 0x8e, 0x3d, 0x43, 0x22, 0xb6, 0x86, 0x80, 0xee, 0x40, 0x27, 0x25, 0x61,
- 0x28, 0xf1, 0x6b, 0x55, 0xf8, 0x3a, 0x06, 0xfe, 0x4c, 0x46, 0x4e, 0x56, 0xce, 0x50, 0x79, 0xd1,
- 0xd0, 0x23, 0x2a, 0x65, 0xf6, 0x9b, 0xda, 0x70, 0x7c, 0x11, 0x89, 0x73, 0x32, 0xfd, 0x89, 0x7f,
- 0x61, 0x89, 0xaf, 0x9e, 0xcd, 0x7c, 0x37, 0x23, 0xb4, 0x32, 0xe0, 0x7b, 0xb1, 0x98, 0x91, 0x98,
- 0xfc, 0x1e, 0x2d, 0xd9, 0x7c, 0x16, 0xfd, 0x06, 0xf4, 0xb8, 0x84, 0x12, 0x2e, 0x78, 0x11, 0xaf,
- 0xd6, 0xcd, 0xe5, 0xf1, 0xb9, 0x47, 0x4b, 0xb6, 0x89, 0xbc, 0xd7, 0x87, 0x2e, 0x07, 0xcc, 0x19,
- 0x53, 0xfc, 0x2f, 0x35, 0x68, 0xd0, 0x60, 0xb9, 0xf8, 0x5c, 0xf1, 0x46, 0x55, 0xe3, 0x57, 0xd0,
- 0x0d, 0x23, 0x5f, 0x0e, 0x65, 0x5c, 0xbc, 0xa1, 0x87, 0x63, 0x5a, 0xe1, 0x3c, 0x99, 0x4f, 0xbf,
- 0x21, 0x97, 0x22, 0xed, 0x18, 0x5f, 0x50, 0xfe, 0x41, 0x34, 0x8d, 0xe7, 0x91, 0x2f, 0x72, 0xa3,
- 0x1c, 0xaa, 0x14, 0xd1, 0xd4, 0x52, 0x04, 0x8d, 0x1a, 0xaf, 0xe7, 0xbe, 0x63, 0x86, 0x4a, 0x1d,
- 0x84, 0x3e, 0x81, 0xd5, 0x94, 0x78, 0x71, 0xe4, 0xa7, 0xfc, 0xc4, 0xe9, 0x65, 0xc4, 0x67, 0x7e,
- 0xd2, 0xb3, 0xcb, 0x13, 0xd5, 0x65, 0xe4, 0xf8, 0x3e, 0x0c, 0x0a, 0xcb, 0xae, 0x48, 0x8b, 0xeb,
- 0x7a, 0x5a, 0x5c, 0xd1, 0xd3, 0xe0, 0xef, 0xd7, 0x60, 0xf5, 0x09, 0x3d, 0x1c, 0x0a, 0xa5, 0xf0,
- 0x70, 0xfa, 0xbf, 0x19, 0x73, 0x74, 0xff, 0x69, 0x14, 0xfc, 0x47, 0x46, 0x80, 0xe6, 0xd5, 0x11,
- 0x60, 0x0b, 0x86, 0x09, 0x61, 0x47, 0x58, 0x27, 0x27, 0xc5, 0xc5, 0x59, 0x82, 0xd3, 0xe2, 0x39,
- 0x38, 0x3b, 0x23, 0x7e, 0xe0, 0x66, 0x14, 0xea, 0x78, 0xf4, 0x88, 0x12, 0x32, 0xa9, 0xb6, 0xed,
- 0xaa, 0x29, 0x2a, 0x02, 0xa4, 0x8b, 0x40, 0x44, 0xea, 0x2f, 0x60, 0x18, 0x44, 0x19, 0x49, 0x22,
- 0x37, 0x74, 0xce, 0xdc, 0xcc, 0x3b, 0x25, 0x0b, 0xfc, 0xb2, 0x84, 0x86, 0x7e, 0x0c, 0x7d, 0x56,
- 0x9d, 0xa7, 0x73, 0xcf, 0x23, 0x29, 0x2d, 0xa6, 0xb8, 0x83, 0xe6, 0x55, 0x39, 0x3d, 0x84, 0x1e,
- 0xf3, 0x49, 0xbb, 0x80, 0x8a, 0x3e, 0xa7, 0x95, 0xea, 0x99, 0x1b, 0x44, 0xb4, 0xc8, 0xe7, 0xee,
- 0x56, 0xaf, 0x70, 0x37, 0xbb, 0x88, 0x85, 0xbe, 0x80, 0x1e, 0x23, 0xf5, 0xd2, 0x0d, 0xc2, 0x79,
- 0xc2, 0x2a, 0xb8, 0x12, 0xd3, 0x9f, 0xf0, 0x39, 0xdb, 0xc4, 0xc4, 0xff, 0x69, 0xc1, 0x40, 0x89,
- 0x60, 0x72, 0x4e, 0x22, 0x1a, 0x9d, 0x9b, 0x6c, 0x3f, 0x0b, 0x9d, 0x9d, 0xcd, 0xa2, 0x2f, 0xa0,
- 0xab, 0x6f, 0x40, 0xf8, 0x7a, 0xd5, 0x4e, 0x1f, 0x2d, 0xd9, 0x06, 0x2a, 0xfa, 0xe2, 0xcd, 0x76,
- 0xfa, 0x68, 0xa9, 0x6a, 0xaf, 0x5d, 0x7d, 0x07, 0xcc, 0xb0, 0xaa, 0xb7, 0x9a, 0x73, 0x15, 0xa8,
- 0x7b, 0x2d, 0x68, 0x12, 0xba, 0x41, 0x1c, 0x43, 0x47, 0x3b, 0x1d, 0x2d, 0x2c, 0xbc, 0xb4, 0xb0,
- 0x53, 0x33, 0xc3, 0x8e, 0x56, 0x07, 0x35, 0x4a, 0x75, 0x10, 0xef, 0x65, 0x36, 0xb5, 0x5e, 0x26,
- 0xfe, 0x0c, 0x36, 0x58, 0xd4, 0x23, 0xaa, 0xf1, 0xfd, 0xcb, 0x0f, 0xff, 0x23, 0xd8, 0x2c, 0x7e,
- 0x24, 0x7a, 0x69, 0x07, 0x80, 0xf8, 0x8c, 0xe1, 0xba, 0x57, 0xf5, 0x34, 0xae, 0x70, 0x60, 0xfc,
- 0x57, 0x16, 0xac, 0x19, 0xe4, 0x84, 0x1b, 0xbc, 0x07, 0x43, 0x89, 0xe3, 0xc4, 0x91, 0xc3, 0xb2,
- 0xac, 0xa5, 0xb2, 0x2c, 0xda, 0x06, 0xa4, 0x94, 0x53, 0xa0, 0x5e, 0x31, 0xc3, 0x7d, 0x99, 0xb2,
- 0xf1, 0x15, 0x36, 0xaf, 0xb6, 0x4a, 0x70, 0x3d, 0xa8, 0x34, 0x8c, 0xa0, 0xa2, 0xa4, 0xb2, 0x1b,
- 0x86, 0xc6, 0x61, 0x07, 0xcf, 0xe1, 0x5a, 0x69, 0x46, 0x6c, 0xe5, 0x13, 0x58, 0x95, 0x2c, 0xa4,
- 0x48, 0x64, 0x55, 0x5f, 0x9e, 0xa0, 0xd8, 0x62, 0xbf, 0x1a, 0x36, 0x6f, 0x1f, 0x96, 0x27, 0xf0,
- 0xa7, 0xb0, 0xca, 0xd9, 0xea, 0xb7, 0x17, 0x0b, 0x0f, 0x6f, 0xf4, 0xe0, 0xac, 0xa3, 0x0b, 0x8d,
- 0xfe, 0x41, 0x8d, 0x82, 0xd3, 0x2c, 0x4e, 0x8c, 0xfe, 0xe8, 0x1b, 0x35, 0x3b, 0xf5, 0x26, 0x6a,
- 0xcd, 0x6c, 0xa2, 0xa2, 0x6f, 0xa0, 0x43, 0x33, 0xd9, 0xd4, 0xf5, 0x5e, 0xcd, 0x67, 0x32, 0xf5,
- 0x6d, 0x49, 0x67, 0x29, 0x73, 0xa4, 0x89, 0x70, 0x8f, 0x23, 0xf3, 0x44, 0x08, 0x61, 0x0e, 0x40,
- 0x3f, 0x60, 0xd7, 0x3c, 0x8e, 0xef, 0x66, 0xee, 0xd4, 0x4d, 0x79, 0x83, 0xb9, 0xcb, 0xf2, 0xda,
- 0x03, 0x01, 0x12, 0x39, 0x49, 0xa7, 0xf0, 0xcb, 0x72, 0x52, 0x57, 0xcf, 0x49, 0x84, 0x5a, 0xa2,
- 0xb6, 0x26, 0xd5, 0xf3, 0x4d, 0x38, 0x58, 0xf4, 0x72, 0x85, 0x18, 0x24, 0x90, 0x35, 0x72, 0x3f,
- 0xa2, 0xe6, 0x25, 0x90, 0x64, 0x4b, 0x84, 0x1f, 0xe6, 0x07, 0x12, 0x2e, 0x5b, 0xb8, 0x0f, 0x00,
- 0x1d, 0x93, 0xec, 0x20, 0x3e, 0x39, 0x20, 0xe7, 0xea, 0x24, 0xb1, 0x0d, 0x2b, 0x61, 0x7c, 0xe2,
- 0x84, 0x14, 0xc6, 0x96, 0xdb, 0x57, 0x07, 0xad, 0x1c, 0x57, 0xa1, 0xe0, 0x0d, 0x58, 0x33, 0xa8,
- 0x08, 0x55, 0xae, 0xc2, 0xe0, 0xf8, 0x74, 0x9e, 0xf9, 0xf1, 0x85, 0xbc, 0x22, 0xa1, 0x47, 0x46,
- 0x05, 0x12, 0x68, 0xbf, 0x06, 0x9b, 0xc7, 0xf3, 0x69, 0xea, 0x25, 0xc1, 0x94, 0x98, 0x07, 0xff,
- 0x31, 0xb4, 0xc9, 0xeb, 0x20, 0xcd, 0x82, 0xe8, 0x84, 0x2d, 0xa3, 0x6d, 0xe7, 0x63, 0xfc, 0x3e,
- 0xbc, 0x9b, 0x7f, 0x45, 0x43, 0x5d, 0xba, 0xeb, 0x79, 0x64, 0x96, 0x11, 0x5f, 0xb2, 0xba, 0x0f,
- 0x1b, 0x26, 0x82, 0x76, 0x9f, 0x26, 0x0f, 0xf4, 0x99, 0xfb, 0x4a, 0x54, 0x72, 0x6d, 0xdb, 0x04,
- 0xe2, 0xff, 0xae, 0x41, 0x97, 0x7e, 0x26, 0xc9, 0xa2, 0xeb, 0xa5, 0xa0, 0xd2, 0x62, 0xe3, 0xc7,
- 0x66, 0x09, 0x5c, 0x2b, 0x94, 0xc0, 0x57, 0x16, 0x05, 0x8b, 0xfa, 0xa3, 0xaa, 0xf8, 0x68, 0xea,
- 0xc5, 0x47, 0xb1, 0xeb, 0xba, 0x5c, 0xd1, 0x75, 0xdd, 0x84, 0xe5, 0x84, 0xb5, 0xc4, 0xc4, 0xf9,
- 0x53, 0x8c, 0x68, 0xcc, 0xe1, 0xe7, 0x34, 0x27, 0x21, 0x1e, 0x09, 0xce, 0xa9, 0x4c, 0xdb, 0x3c,
- 0xe6, 0x14, 0xe1, 0xf4, 0x80, 0x26, 0x60, 0xa9, 0xb8, 0x1d, 0x5a, 0xe1, 0xd7, 0x67, 0x26, 0x94,
- 0xc6, 0x3d, 0x19, 0xa3, 0x35, 0xaa, 0xbc, 0x93, 0x57, 0x31, 0x43, 0xd7, 0x90, 0x43, 0x25, 0xe5,
- 0x0e, 0xaf, 0x61, 0x8a, 0x70, 0x1a, 0x8b, 0x3b, 0x5a, 0x0a, 0xfb, 0x9e, 0x7d, 0x6a, 0x5d, 0xc6,
- 0xf5, 0x82, 0x8c, 0x8b, 0xd2, 0x6c, 0x54, 0x48, 0xf3, 0x43, 0xe8, 0x8b, 0x9c, 0xe9, 0x24, 0xc4,
- 0x4d, 0x63, 0x99, 0xcd, 0x0a, 0x50, 0xfc, 0x37, 0x75, 0xbe, 0x5a, 0x91, 0xe6, 0xff, 0x7f, 0x8d,
- 0x45, 0xa9, 0xbc, 0x69, 0xa8, 0xfc, 0x36, 0x0c, 0x0c, 0xd5, 0x12, 0x5f, 0x68, 0xbc, 0x08, 0xa6,
- 0x65, 0xba, 0x52, 0x6d, 0x26, 0xb4, 0xad, 0x83, 0x4a, 0xc2, 0x82, 0x0a, 0x61, 0xdd, 0x84, 0x46,
- 0x12, 0x87, 0x84, 0xa9, 0xb4, 0xaf, 0xba, 0x3c, 0x76, 0x1c, 0x12, 0x9b, 0xcd, 0xd0, 0x7c, 0x52,
- 0x30, 0x0b, 0xe2, 0xb3, 0x6e, 0xed, 0x8a, 0x5d, 0x9e, 0xa0, 0x8e, 0xaa, 0x9b, 0x45, 0x36, 0xea,
- 0xf1, 0x7b, 0x1f, 0x03, 0x48, 0x4f, 0xd8, 0x89, 0x33, 0x4b, 0x48, 0x70, 0xe6, 0x9e, 0x90, 0x51,
- 0x9f, 0xa1, 0x68, 0x10, 0xe5, 0x4a, 0x03, 0xcd, 0x95, 0xf0, 0x7f, 0xd5, 0xa0, 0xf9, 0x34, 0x71,
- 0x7d, 0x42, 0x8f, 0x91, 0x67, 0xd4, 0xe3, 0x9d, 0xc5, 0xc7, 0x3a, 0x5b, 0xc7, 0xa0, 0x1f, 0x64,
- 0xda, 0x07, 0xb5, 0xca, 0x0f, 0x34, 0x0c, 0x4d, 0x3f, 0x75, 0x43, 0x3f, 0x57, 0xe9, 0x54, 0xb3,
- 0x84, 0xa6, 0x69, 0x09, 0xf9, 0x7e, 0x96, 0xf5, 0xd0, 0x20, 0x65, 0xdf, 0x5a, 0x28, 0xfb, 0x9b,
- 0xd0, 0x21, 0xfc, 0xfa, 0x87, 0xb5, 0x22, 0xb8, 0x25, 0xe8, 0xa0, 0xfc, 0x24, 0xb2, 0x72, 0xf5,
- 0x49, 0xe4, 0x1e, 0x74, 0x3d, 0x6a, 0x18, 0x24, 0x99, 0xb9, 0x49, 0xc6, 0x4d, 0x61, 0x71, 0xb7,
- 0xc4, 0xc0, 0xc5, 0x1f, 0xc3, 0x1a, 0x93, 0xfa, 0xa3, 0x80, 0xe6, 0xa1, 0x4b, 0xed, 0xac, 0xc5,
- 0x1b, 0xb2, 0x96, 0xd6, 0x90, 0xc5, 0xf7, 0x61, 0xdd, 0x44, 0x16, 0x49, 0xf0, 0x16, 0x2c, 0x67,
- 0x14, 0x5e, 0x3a, 0x8b, 0x30, 0x6c, 0x5b, 0x4c, 0xe2, 0x3f, 0xb6, 0xa0, 0x47, 0x21, 0x41, 0x74,
- 0x72, 0x40, 0xe9, 0xa5, 0x54, 0xe0, 0x67, 0xee, 0x6b, 0x27, 0x25, 0x61, 0x28, 0x9b, 0x1f, 0x72,
- 0x4c, 0x05, 0x4e, 0x7f, 0x4f, 0xe7, 0xb2, 0x70, 0x93, 0x43, 0x6a, 0x86, 0x09, 0x49, 0x49, 0x42,
- 0x4b, 0x23, 0xf6, 0x29, 0x0f, 0x24, 0x26, 0x90, 0x3a, 0x48, 0x0e, 0xa0, 0x44, 0xb8, 0x42, 0x0d,
- 0x18, 0xde, 0xe1, 0x1b, 0xca, 0x17, 0xf4, 0x26, 0xb5, 0xef, 0x5f, 0x5b, 0xb0, 0x51, 0xf8, 0x48,
- 0x88, 0x61, 0x17, 0x96, 0x99, 0x9c, 0xa4, 0x18, 0x3e, 0xd2, 0xc5, 0x50, 0x42, 0xdf, 0xe6, 0x43,
- 0xd1, 0x4b, 0xe6, 0x1f, 0x8e, 0x9f, 0x40, 0x47, 0x03, 0x57, 0x14, 0x28, 0x1f, 0x9b, 0xbd, 0xe4,
- 0x8d, 0x6a, 0x16, 0x5a, 0xdd, 0xf2, 0x2d, 0x74, 0x9f, 0x45, 0xd3, 0xef, 0xf1, 0x26, 0x02, 0xdd,
- 0x80, 0x95, 0x84, 0x88, 0x93, 0xbe, 0x28, 0x57, 0x14, 0x00, 0x0f, 0xa0, 0x27, 0xe8, 0xaa, 0x5b,
- 0xf4, 0x67, 0x51, 0x18, 0x7b, 0xaf, 0xde, 0xf4, 0x16, 0xfd, 0x67, 0x80, 0xf4, 0x0f, 0x54, 0x41,
- 0x35, 0x67, 0xd0, 0x42, 0x41, 0x25, 0x81, 0xac, 0xa0, 0x7a, 0x1f, 0x3a, 0x3a, 0x0a, 0xbf, 0x74,
- 0x03, 0x85, 0x80, 0xff, 0xc8, 0x82, 0xc1, 0xf3, 0x20, 0x3b, 0xf5, 0x13, 0xf7, 0xe2, 0x0d, 0x94,
- 0x5a, 0x7c, 0xd1, 0x50, 0xbb, 0xea, 0x45, 0x43, 0xbd, 0xf8, 0xa2, 0xc1, 0x0d, 0x43, 0xd1, 0x7c,
- 0xa1, 0x3f, 0xf5, 0xb6, 0x6b, 0x8f, 0xb7, 0x5d, 0xef, 0xc1, 0x50, 0x2d, 0xe6, 0xed, 0x7a, 0xae,
- 0x5b, 0xb7, 0x61, 0x25, 0xf7, 0x77, 0xd4, 0x82, 0xfa, 0xde, 0xb3, 0xdf, 0x1c, 0x2e, 0xa1, 0x36,
- 0x34, 0x8e, 0x27, 0x07, 0x07, 0xfc, 0x7a, 0x83, 0xdd, 0x78, 0xd4, 0xb6, 0xb6, 0xa0, 0x41, 0xa3,
- 0x0b, 0x5a, 0x81, 0xe6, 0xd3, 0xdd, 0x6f, 0x26, 0xf6, 0x70, 0x89, 0xfe, 0xfc, 0x29, 0xfb, 0x69,
- 0xa1, 0x2e, 0xb4, 0x1f, 0x1f, 0x3e, 0x9d, 0xd8, 0x87, 0xbb, 0x07, 0xc3, 0xda, 0xd6, 0x73, 0x68,
- 0xcb, 0xea, 0x90, 0x22, 0xed, 0x1e, 0x4c, 0xec, 0xa7, 0x1c, 0x7f, 0x62, 0xdb, 0x47, 0x36, 0xa7,
- 0xfb, 0x7c, 0xd7, 0x3e, 0x1c, 0xd6, 0xe8, 0xaf, 0xc7, 0x87, 0x3f, 0x39, 0x1a, 0xd6, 0x51, 0x07,
- 0x5a, 0xdf, 0x4e, 0xec, 0xbd, 0xa3, 0xe3, 0xc9, 0xb0, 0x41, 0x71, 0x1f, 0x4c, 0xf6, 0x9e, 0x3d,
- 0x1c, 0x36, 0x19, 0x47, 0x7b, 0x77, 0x7f, 0x32, 0x5c, 0xde, 0xf9, 0x37, 0x0b, 0x5a, 0x2f, 0xe6,
- 0xfe, 0xe3, 0x28, 0xc8, 0xd0, 0x04, 0x40, 0xbd, 0x92, 0x40, 0xd7, 0xf3, 0x6e, 0x7f, 0xf1, 0xad,
- 0xc5, 0x78, 0x5c, 0x35, 0x25, 0xcc, 0x6a, 0x09, 0x3d, 0x82, 0x8e, 0x56, 0x79, 0xa3, 0xf1, 0xe2,
- 0x23, 0xc2, 0xf8, 0x9d, 0xca, 0xb9, 0x9c, 0xd2, 0x04, 0x40, 0x59, 0x9c, 0x5a, 0x50, 0xc9, 0x6c,
- 0xd5, 0x82, 0xca, 0x06, 0x8a, 0x97, 0x76, 0xfe, 0x63, 0x04, 0xf5, 0x17, 0x73, 0x1f, 0xbd, 0x80,
- 0x8e, 0xf6, 0x60, 0x0c, 0x95, 0x6e, 0xd2, 0xd4, 0x72, 0xaa, 0xde, 0x95, 0x8d, 0x7f, 0xf1, 0x8f,
- 0xff, 0xfe, 0x27, 0xb5, 0x75, 0x3c, 0xb8, 0x73, 0xfe, 0xab, 0x77, 0x5c, 0xdf, 0x97, 0xb6, 0x78,
- 0xcf, 0xda, 0x42, 0x36, 0xb4, 0xc4, 0x9b, 0x30, 0xb4, 0xa9, 0xd1, 0xd0, 0x8e, 0x71, 0xe3, 0x6b,
- 0x25, 0xb8, 0xa0, 0xbb, 0xc9, 0xe8, 0x0e, 0x71, 0x47, 0xd0, 0xa5, 0x69, 0x8a, 0xd2, 0xdc, 0x83,
- 0xfa, 0x9e, 0x1b, 0x21, 0xa4, 0x2e, 0xca, 0x65, 0x4c, 0x18, 0xaf, 0x19, 0x30, 0x41, 0x07, 0x31,
- 0x3a, 0x5d, 0xdc, 0xa2, 0x74, 0xa6, 0x6e, 0x44, 0x69, 0x78, 0xd0, 0xd5, 0x1f, 0xeb, 0x20, 0xf5,
- 0x64, 0xa4, 0xfc, 0x02, 0x69, 0x7c, 0xa3, 0x7a, 0x52, 0x90, 0x1f, 0x31, 0xf2, 0x08, 0x0f, 0x29,
- 0x79, 0xf6, 0x96, 0x49, 0xdc, 0x13, 0xd1, 0xcd, 0x8b, 0x17, 0x3a, 0x6a, 0xf3, 0xe6, 0x03, 0x1f,
- 0xb5, 0xf9, 0xe2, 0x53, 0x1e, 0x63, 0xf3, 0x22, 0x54, 0xd1, 0x85, 0xff, 0x1c, 0x7a, 0xcf, 0xd9,
- 0x4b, 0x31, 0xf1, 0x2e, 0x44, 0x51, 0x36, 0x9f, 0x95, 0x28, 0xca, 0x85, 0x07, 0x24, 0xf8, 0x06,
- 0xa3, 0xbc, 0x89, 0x57, 0x29, 0x65, 0xfe, 0xea, 0xcc, 0xe7, 0x28, 0x94, 0xfe, 0xef, 0x40, 0xcf,
- 0x78, 0x02, 0x82, 0xf2, 0xcd, 0x57, 0xbd, 0x2d, 0x19, 0xbf, 0xbb, 0x60, 0xb6, 0x8a, 0x97, 0x2f,
- 0x50, 0xd8, 0xa3, 0x11, 0xca, 0xeb, 0x05, 0x80, 0x7a, 0x4a, 0xa1, 0xac, 0xb8, 0xf4, 0x7c, 0x43,
- 0x59, 0x71, 0xf9, 0xe5, 0x05, 0x5e, 0x63, 0x2c, 0x7a, 0xa8, 0xc3, 0xb5, 0xcb, 0x69, 0x1d, 0x40,
- 0x4b, 0x3c, 0x1a, 0x50, 0xf2, 0x31, 0x5f, 0x4e, 0x28, 0xf9, 0x14, 0x5e, 0x17, 0xe0, 0x21, 0x23,
- 0x08, 0xa8, 0x4d, 0x09, 0x06, 0x94, 0xc4, 0x6f, 0x41, 0x47, 0xbb, 0x71, 0x47, 0xfa, 0x6a, 0x0a,
- 0x97, 0xf3, 0xca, 0x51, 0x2a, 0xae, 0xe8, 0xf1, 0x3a, 0xa3, 0xdc, 0x47, 0x5d, 0x4a, 0x59, 0xb6,
- 0x1b, 0x04, 0x75, 0x79, 0xa5, 0x6e, 0x50, 0x2f, 0xdc, 0xd3, 0x1b, 0xd4, 0x8b, 0x77, 0xf0, 0x26,
- 0x75, 0x2a, 0x63, 0xb6, 0xf6, 0xe7, 0x00, 0xea, 0xf6, 0x57, 0xc9, 0xb8, 0x74, 0x8d, 0xad, 0x64,
- 0x5c, 0xbe, 0x2c, 0x96, 0x1e, 0x84, 0x80, 0x92, 0x16, 0x77, 0x24, 0x27, 0xd0, 0x37, 0x2f, 0xe7,
- 0xd1, 0xbb, 0x3a, 0x85, 0xd2, 0x6d, 0xfe, 0xf8, 0xbd, 0x45, 0xd3, 0xa6, 0xc5, 0xa3, 0x3e, 0xb3,
- 0x78, 0x45, 0xf6, 0x18, 0x56, 0xf2, 0x6b, 0x63, 0x34, 0xd2, 0x89, 0xe8, 0xb7, 0xcb, 0xe3, 0xeb,
- 0x15, 0x33, 0xb2, 0x5b, 0xc0, 0x28, 0x77, 0xd0, 0x0a, 0xa5, 0xcc, 0x6f, 0x0f, 0x24, 0x51, 0xf6,
- 0x80, 0xc5, 0x24, 0xaa, 0xdd, 0x39, 0x17, 0x88, 0xea, 0x37, 0xcf, 0x05, 0xa2, 0x8c, 0x8e, 0x03,
- 0x1d, 0xed, 0x52, 0x52, 0x69, 0xb2, 0x7c, 0xa3, 0xaa, 0x34, 0x59, 0x71, 0x8b, 0x89, 0xaf, 0x31,
- 0xd2, 0xab, 0x3c, 0xa0, 0xc6, 0x33, 0x12, 0xc9, 0x80, 0xf2, 0xdb, 0x00, 0xaa, 0x8f, 0xac, 0x94,
- 0x59, 0xba, 0x61, 0x50, 0xc6, 0x5d, 0x68, 0x3b, 0xe3, 0xeb, 0x8c, 0xf4, 0x1a, 0x66, 0x42, 0x66,
- 0xbd, 0x7d, 0xa6, 0xce, 0x7b, 0xd6, 0xd6, 0x5d, 0x0b, 0xbd, 0x84, 0xbe, 0xc2, 0x3f, 0xbe, 0x8c,
- 0xbc, 0xab, 0x58, 0x8c, 0xab, 0xa6, 0xc4, 0x06, 0xde, 0x65, 0x5c, 0xae, 0x61, 0x64, 0x72, 0x49,
- 0x2f, 0x23, 0x8f, 0xfa, 0xfd, 0xcf, 0xa0, 0xa3, 0x3d, 0x17, 0x53, 0x72, 0x2a, 0xbf, 0x21, 0x1b,
- 0x57, 0x75, 0xba, 0xcd, 0x84, 0x23, 0x8e, 0x19, 0xe9, 0x85, 0x3b, 0xa3, 0xb4, 0x23, 0xe8, 0x9b,
- 0x0d, 0x5d, 0x65, 0x96, 0x95, 0xdd, 0x61, 0x65, 0x96, 0x0b, 0xfa, 0xc0, 0xc6, 0x5e, 0x78, 0x1f,
- 0x53, 0x4f, 0x70, 0x53, 0x9a, 0xd3, 0xf3, 0xbe, 0xae, 0x9e, 0xd3, 0x8b, 0xbd, 0x63, 0x3d, 0xa7,
- 0x97, 0x1a, 0xc1, 0xe6, 0x9e, 0x38, 0x1b, 0xa9, 0x19, 0x94, 0xc0, 0xa0, 0xd0, 0x74, 0x45, 0x85,
- 0x55, 0x17, 0xfb, 0xb4, 0xe3, 0xf7, 0x17, 0xce, 0x0b, 0x7e, 0xef, 0x31, 0x7e, 0x23, 0xbc, 0xa6,
- 0xf8, 0xb9, 0x61, 0xc8, 0xd5, 0xc4, 0xf3, 0x0c, 0xa8, 0x16, 0xaa, 0xb2, 0x83, 0x52, 0x17, 0x76,
- 0x3c, 0xae, 0x9a, 0x12, 0x4c, 0x0c, 0x6b, 0xe3, 0x4c, 0x64, 0x12, 0x9f, 0x42, 0x47, 0x6b, 0xec,
- 0x29, 0xb9, 0x95, 0x7b, 0x86, 0x4a, 0x6e, 0x55, 0x9d, 0x40, 0x43, 0x6e, 0x29, 0xc9, 0xc2, 0xf8,
- 0x84, 0x75, 0x0e, 0x29, 0x8f, 0x6f, 0xa1, 0x2d, 0x5b, 0x82, 0x28, 0xf7, 0x88, 0x42, 0xdf, 0x70,
- 0x3c, 0x2a, 0x4f, 0x14, 0xdc, 0x90, 0x05, 0xd4, 0x54, 0xcc, 0x52, 0xba, 0x04, 0x06, 0x85, 0xb6,
- 0xa2, 0xd2, 0x47, 0x75, 0xbf, 0x71, 0x6c, 0xbe, 0x7a, 0xe3, 0x17, 0xbe, 0xf8, 0x1d, 0xc6, 0x60,
- 0x03, 0x31, 0x1d, 0xa4, 0xf2, 0x43, 0xae, 0x83, 0xbb, 0x16, 0x9a, 0x15, 0xda, 0x8c, 0xa2, 0x5f,
- 0xa5, 0x05, 0xda, 0xca, 0x2e, 0xe4, 0xb8, 0xea, 0x9e, 0x06, 0xff, 0x80, 0xf1, 0x7a, 0x07, 0x5d,
- 0x37, 0x78, 0x51, 0xaf, 0x91, 0xd7, 0x54, 0x77, 0x2d, 0x34, 0x85, 0xbe, 0x49, 0xf2, 0xad, 0x58,
- 0x15, 0xdc, 0x13, 0xa1, 0x12, 0x2b, 0xca, 0xe3, 0xf7, 0xb4, 0x9e, 0xac, 0xd1, 0x5d, 0x45, 0xb7,
- 0xaa, 0x79, 0x15, 0xba, 0xaf, 0xe3, 0x75, 0x9d, 0xa7, 0x9c, 0xc4, 0x98, 0x31, 0xbd, 0x81, 0xc6,
- 0x65, 0xa6, 0xae, 0xc0, 0x61, 0x11, 0xae, 0xab, 0x9f, 0xfb, 0x55, 0xd9, 0x57, 0xd1, 0x3a, 0x50,
- 0x65, 0x5f, 0x55, 0xab, 0x40, 0x2a, 0x8f, 0x97, 0x7d, 0xac, 0x2f, 0x70, 0xca, 0x31, 0xa8, 0x85,
- 0x9c, 0x14, 0xfb, 0x03, 0x37, 0x16, 0x9c, 0xa0, 0x0b, 0x55, 0x54, 0xe5, 0xf9, 0x5a, 0xba, 0x11,
- 0x5a, 0x95, 0xac, 0x82, 0xe8, 0x84, 0x1f, 0xb3, 0xd1, 0xd7, 0xd0, 0x64, 0x87, 0x57, 0xb4, 0xae,
- 0x0a, 0x7d, 0x75, 0x46, 0x1e, 0x6f, 0x14, 0xa0, 0x66, 0xa9, 0x80, 0x59, 0xee, 0x9a, 0x47, 0xa2,
- 0x26, 0x9e, 0x42, 0x9f, 0x97, 0x96, 0xf2, 0x88, 0xa7, 0x9c, 0xa6, 0x70, 0x02, 0x55, 0x4e, 0x53,
- 0x3c, 0x0d, 0x9a, 0xe1, 0x92, 0x57, 0x97, 0x17, 0x02, 0xe7, 0x9e, 0xb5, 0x35, 0x5d, 0x66, 0xff,
- 0x50, 0xf9, 0xec, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x5e, 0xda, 0xc9, 0x11, 0xcc, 0x32, 0x00,
- 0x00,
+ // 4162 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3b, 0x4d, 0x8f, 0x1c, 0x49,
+ 0x56, 0x9d, 0xd5, 0x5d, 0xdd, 0xd5, 0xaf, 0x3e, 0x3b, 0xfa, 0xc3, 0xe5, 0x1a, 0xcf, 0x8c, 0x37,
+ 0x18, 0x8f, 0x3c, 0x9e, 0x59, 0xdb, 0x78, 0x58, 0x66, 0xc7, 0x8b, 0x47, 0xd3, 0xdd, 0xee, 0x1d,
+ 0x7b, 0xa6, 0xd7, 0xb6, 0xb2, 0xed, 0xb1, 0x59, 0xc1, 0xa6, 0xb2, 0x32, 0xc3, 0xdd, 0x89, 0xb3,
+ 0x33, 0x6b, 0x32, 0xb3, 0xdc, 0x36, 0x5c, 0xd0, 0x8a, 0x13, 0x1c, 0x38, 0x20, 0xce, 0x70, 0x42,
+ 0x48, 0x20, 0xae, 0x9c, 0x90, 0x38, 0x73, 0xe5, 0x00, 0x02, 0x2e, 0x48, 0xfc, 0x02, 0xc4, 0x15,
+ 0x09, 0xbd, 0xf8, 0xc8, 0x88, 0xc8, 0xcc, 0xea, 0xb5, 0x57, 0xc0, 0xad, 0xe2, 0xc5, 0xcb, 0xf7,
+ 0x22, 0xde, 0x57, 0xbc, 0xf7, 0x22, 0x0a, 0x7a, 0xaf, 0xe6, 0x61, 0x36, 0x0b, 0xae, 0xcf, 0xb2,
+ 0xb4, 0x48, 0xc9, 0xaa, 0x18, 0x4d, 0x36, 0xfc, 0x24, 0x49, 0x0b, 0xbf, 0x88, 0xd2, 0x24, 0x17,
+ 0x53, 0x74, 0x1b, 0x36, 0x77, 0xc3, 0x70, 0x7f, 0x9e, 0x65, 0x2c, 0x09, 0x5e, 0xbb, 0x2c, 0x9f,
+ 0xa5, 0x49, 0xce, 0xe8, 0xcf, 0x60, 0xb0, 0x1b, 0x86, 0x8f, 0xfc, 0x28, 0x73, 0xd9, 0x77, 0x73,
+ 0x96, 0x17, 0xe4, 0x03, 0xe8, 0x4f, 0xfd, 0x9c, 0x79, 0x81, 0x44, 0x1d, 0x3b, 0x97, 0x9d, 0xab,
+ 0xeb, 0xae, 0x0d, 0x24, 0x1f, 0xc2, 0xe0, 0xbb, 0x79, 0x5a, 0x18, 0x68, 0x2d, 0x8e, 0x56, 0x81,
+ 0xd2, 0x0d, 0x18, 0x96, 0xf4, 0x25, 0xcb, 0xbf, 0x6d, 0xc1, 0xda, 0x9e, 0x1f, 0xfb, 0x49, 0xc0,
+ 0x90, 0x59, 0x91, 0x16, 0x7e, 0xec, 0x4d, 0x05, 0x80, 0x33, 0x5b, 0x71, 0x6d, 0x20, 0xb9, 0x0a,
+ 0xc3, 0xe0, 0xc4, 0x4f, 0x12, 0xa6, 0xf1, 0x5a, 0x1c, 0xaf, 0x0a, 0x26, 0x3f, 0x84, 0x0b, 0x33,
+ 0x96, 0x84, 0x51, 0x72, 0xec, 0x55, 0xbf, 0x58, 0xe6, 0x5f, 0x2c, 0x9a, 0x26, 0xb7, 0x61, 0x1c,
+ 0x25, 0x7e, 0x50, 0x44, 0x2f, 0x59, 0xed, 0xd3, 0x15, 0xfe, 0xe9, 0xc2, 0x79, 0x14, 0xc6, 0x99,
+ 0x1f, 0xc7, 0xac, 0x28, 0xbf, 0x68, 0xf3, 0x2f, 0x2a, 0x50, 0xf2, 0x05, 0x4c, 0xe6, 0x49, 0x90,
+ 0x26, 0xcf, 0xa3, 0xec, 0x94, 0x85, 0x5e, 0xe5, 0x9b, 0x55, 0xfe, 0xcd, 0x39, 0x18, 0xf4, 0xd7,
+ 0x01, 0xf6, 0xfc, 0x44, 0x29, 0xea, 0x2a, 0x0c, 0x93, 0x34, 0x64, 0x5e, 0x14, 0xb2, 0xa4, 0x88,
+ 0x9e, 0x47, 0x2c, 0x93, 0xaa, 0xaa, 0x82, 0x69, 0x1f, 0xba, 0xfc, 0x3b, 0xa9, 0x80, 0xcf, 0xa0,
+ 0xbd, 0x7f, 0xe2, 0x47, 0x09, 0xd9, 0x82, 0x76, 0x80, 0x3f, 0xe4, 0x77, 0x62, 0x40, 0xc6, 0xb0,
+ 0x96, 0xb0, 0xe2, 0x2c, 0xcd, 0x5e, 0x48, 0x9d, 0xaa, 0x21, 0x9d, 0x41, 0x67, 0x5f, 0x6c, 0x3d,
+ 0x27, 0x3b, 0xb0, 0x2a, 0xa4, 0xc1, 0x3f, 0xee, 0xbb, 0x72, 0x44, 0x26, 0xd0, 0x51, 0x72, 0xe2,
+ 0x9f, 0xf7, 0xdd, 0x72, 0x8c, 0x94, 0xa5, 0xf8, 0xb9, 0x36, 0xfa, 0xae, 0x1a, 0x22, 0xb5, 0x20,
+ 0x4e, 0x73, 0x16, 0x72, 0x59, 0xf7, 0x5d, 0x39, 0xa2, 0x1e, 0x6c, 0x23, 0xc7, 0x63, 0xf6, 0xc8,
+ 0xcf, 0xf3, 0xb3, 0x34, 0x0b, 0xd5, 0xe6, 0x29, 0xf4, 0x12, 0x76, 0xe6, 0xcd, 0x24, 0x58, 0xee,
+ 0xc0, 0x82, 0x21, 0x4e, 0x1a, 0x87, 0x1a, 0x47, 0xec, 0xc6, 0x82, 0xd1, 0x31, 0xec, 0x54, 0x19,
+ 0x48, 0x29, 0xfd, 0x9d, 0x03, 0x9b, 0xfb, 0xb8, 0x0a, 0xb9, 0xe5, 0xb7, 0x16, 0x3b, 0x8a, 0xa2,
+ 0xe2, 0x1d, 0xe5, 0x18, 0x45, 0xff, 0x3c, 0xcd, 0xa4, 0x59, 0x76, 0x5c, 0x31, 0x20, 0x97, 0xa1,
+ 0x1b, 0xb2, 0xbc, 0x88, 0x12, 0xee, 0xba, 0x5c, 0x16, 0xeb, 0xae, 0x09, 0xe2, 0x62, 0x3f, 0x4d,
+ 0xe7, 0x49, 0x21, 0x4d, 0x4c, 0x8e, 0xc8, 0x08, 0x96, 0x9f, 0x33, 0x65, 0x43, 0xf8, 0x93, 0x7e,
+ 0x09, 0x5b, 0xf6, 0xf2, 0xc5, 0xbe, 0x70, 0xfd, 0x45, 0xe6, 0x27, 0x39, 0xea, 0x24, 0x4d, 0xbc,
+ 0x28, 0xcc, 0xc7, 0xce, 0xe5, 0x65, 0x5c, 0x7f, 0x05, 0x4c, 0x3f, 0x81, 0xc1, 0x7e, 0x9a, 0x24,
+ 0x2c, 0x28, 0xd4, 0xde, 0x27, 0xd0, 0xe1, 0x9b, 0x9c, 0x67, 0x91, 0xdc, 0x74, 0x39, 0x46, 0x4f,
+ 0x2f, 0xb1, 0xa5, 0x08, 0x6f, 0xc0, 0xc6, 0x7e, 0xc6, 0xfc, 0x82, 0x3d, 0x48, 0x43, 0x66, 0xd0,
+ 0xa8, 0x68, 0xad, 0x1c, 0xd3, 0x3f, 0x75, 0x80, 0x98, 0x5f, 0xc8, 0x25, 0xff, 0x0a, 0xf4, 0x73,
+ 0xc6, 0x42, 0xef, 0x34, 0x61, 0xa7, 0x69, 0x12, 0x05, 0x72, 0xc1, 0x3d, 0x04, 0xfe, 0x44, 0xc2,
+ 0xc8, 0x47, 0x30, 0x8a, 0x92, 0xa8, 0x88, 0xfc, 0x38, 0xfa, 0x5d, 0x16, 0x7a, 0x71, 0x12, 0xe6,
+ 0xe3, 0x96, 0xd8, 0x98, 0x01, 0x3f, 0x4c, 0xc2, 0x9c, 0xdc, 0x80, 0x4d, 0x13, 0x35, 0xc0, 0x65,
+ 0xbf, 0x2a, 0xa4, 0x2a, 0x88, 0x31, 0xb5, 0x2f, 0x66, 0xe8, 0x3f, 0x39, 0xd0, 0x51, 0xa1, 0xd3,
+ 0x52, 0xab, 0x53, 0x51, 0xeb, 0x1d, 0xe8, 0xe6, 0x67, 0xfe, 0xcc, 0x0b, 0xe2, 0x88, 0x25, 0x05,
+ 0xd7, 0xfa, 0xe0, 0xd6, 0x3b, 0xd7, 0x65, 0x90, 0x56, 0x24, 0xae, 0x1f, 0x9d, 0xf9, 0xb3, 0x7d,
+ 0x8e, 0xe2, 0x9a, 0xf8, 0x22, 0x1c, 0xbe, 0x60, 0x89, 0xe7, 0x87, 0x61, 0xc6, 0xf2, 0x9c, 0x2f,
+ 0x69, 0xdd, 0xb5, 0x81, 0x18, 0x6e, 0x42, 0x16, 0x44, 0xa7, 0x7e, 0xec, 0xcd, 0x62, 0x3f, 0x60,
+ 0xb9, 0x74, 0x9a, 0x0a, 0x94, 0x52, 0x00, 0xcd, 0x88, 0xac, 0xc1, 0xf2, 0xe1, 0x83, 0xbb, 0xa3,
+ 0x25, 0xd2, 0x85, 0xb5, 0xfd, 0x87, 0x0f, 0x1e, 0x1c, 0x3c, 0x7b, 0x3c, 0x6a, 0xa1, 0x8e, 0xef,
+ 0xb2, 0x59, 0x9a, 0x47, 0xa6, 0x8e, 0x17, 0x6d, 0x8f, 0x7e, 0x0c, 0xc3, 0x12, 0x5b, 0xea, 0x66,
+ 0x0c, 0x6b, 0x6a, 0xb1, 0x02, 0x5b, 0x0d, 0xd1, 0x00, 0xef, 0x46, 0x79, 0x90, 0xbe, 0x64, 0x19,
+ 0x6a, 0x33, 0x7f, 0xfb, 0xb8, 0xf5, 0x03, 0xd8, 0xae, 0x50, 0x90, 0x4c, 0x2f, 0xc1, 0x7a, 0x32,
+ 0x3f, 0xf5, 0x10, 0x3f, 0x97, 0xf1, 0x47, 0x03, 0xe8, 0x1f, 0x3a, 0x40, 0x0e, 0x5e, 0xb1, 0x60,
+ 0x5e, 0x30, 0xdc, 0xbf, 0xb1, 0xb1, 0x34, 0x0b, 0x59, 0xe6, 0x45, 0xa5, 0xe1, 0xa9, 0x31, 0x8f,
+ 0x4c, 0x7e, 0xc4, 0xa7, 0x64, 0xcc, 0x93, 0x43, 0x0c, 0x22, 0x33, 0xc6, 0x32, 0x6f, 0x36, 0x9f,
+ 0x7a, 0x2f, 0xd8, 0x6b, 0xa9, 0x11, 0x0b, 0x86, 0x94, 0xbf, 0x9b, 0xfb, 0x49, 0x11, 0x15, 0xaf,
+ 0xe5, 0x59, 0x51, 0x8e, 0xd1, 0x07, 0xbe, 0x62, 0x85, 0x3c, 0xef, 0xde, 0x44, 0xc6, 0x7f, 0xe9,
+ 0x00, 0x31, 0xbf, 0x90, 0x5b, 0xbe, 0x0b, 0x1d, 0x79, 0x0c, 0x08, 0x7f, 0xed, 0xde, 0xba, 0xaa,
+ 0xcc, 0xaa, 0x8e, 0x7d, 0x5d, 0x8e, 0xf3, 0x83, 0xa4, 0xc8, 0x5e, 0xbb, 0xe5, 0x97, 0x93, 0x43,
+ 0xe8, 0x5b, 0x53, 0x18, 0x37, 0x70, 0x57, 0x62, 0x11, 0xf8, 0x93, 0x5c, 0x81, 0xf6, 0x4b, 0x3f,
+ 0x9e, 0x8b, 0xe8, 0xdd, 0xbd, 0x35, 0x54, 0x5c, 0x14, 0x0b, 0x31, 0x7b, 0xbb, 0xf5, 0x43, 0x87,
+ 0x8e, 0x60, 0xf0, 0x15, 0x2b, 0xee, 0x27, 0xcf, 0x53, 0xb9, 0x31, 0xfa, 0x2f, 0xcb, 0x30, 0x2c,
+ 0x41, 0xda, 0x42, 0x5e, 0xb2, 0x2c, 0xc7, 0x80, 0x26, 0x2d, 0x44, 0x0e, 0x79, 0x10, 0x47, 0x95,
+ 0x2b, 0xd9, 0xca, 0x00, 0x6d, 0xc2, 0x08, 0x81, 0x95, 0x79, 0x16, 0xa1, 0x27, 0xa0, 0x2b, 0xf3,
+ 0xdf, 0x4a, 0xfd, 0xa8, 0x03, 0x65, 0xfb, 0x1a, 0x50, 0xce, 0xfa, 0x51, 0x96, 0xf3, 0x28, 0xa9,
+ 0x66, 0x11, 0x40, 0x3e, 0x86, 0x55, 0xae, 0xf5, 0x9c, 0xc7, 0xca, 0xee, 0xad, 0x4d, 0xb5, 0xbf,
+ 0x87, 0x1c, 0xba, 0x8f, 0xd1, 0xd4, 0x95, 0x28, 0xe4, 0x16, 0x2c, 0xc7, 0x49, 0x38, 0x5e, 0xe3,
+ 0xf2, 0xbe, 0x6c, 0xc8, 0xdb, 0xdc, 0xe0, 0xf5, 0xc3, 0x24, 0x14, 0x72, 0x46, 0x64, 0x8c, 0xec,
+ 0x7e, 0x1c, 0xf9, 0xf9, 0x78, 0x5d, 0x1c, 0xaa, 0x7c, 0x60, 0x1e, 0xaa, 0x60, 0x1d, 0xaa, 0xe4,
+ 0x26, 0x6c, 0xaa, 0x9c, 0x84, 0x87, 0x82, 0x13, 0x3f, 0x3f, 0x61, 0xf9, 0xb8, 0xcb, 0xf7, 0xdb,
+ 0x34, 0x45, 0xbe, 0x0f, 0x6b, 0x2a, 0x64, 0xf5, 0xec, 0x3d, 0xc8, 0x78, 0xc5, 0x57, 0xa7, 0x70,
+ 0x26, 0x5f, 0x41, 0x47, 0xad, 0xf0, 0x2d, 0xd4, 0x7d, 0x98, 0x84, 0x9c, 0x8c, 0xa1, 0xee, 0x2d,
+ 0x6e, 0x98, 0x2a, 0xe0, 0x2a, 0x95, 0xff, 0x08, 0x36, 0x2d, 0xa8, 0xd4, 0xfa, 0x07, 0xcd, 0x31,
+ 0xdb, 0x06, 0xd2, 0x2f, 0x38, 0x49, 0x74, 0x6e, 0xc3, 0x8a, 0xde, 0x22, 0x42, 0xb8, 0x9c, 0xb9,
+ 0xfe, 0xbe, 0x3c, 0x30, 0x86, 0x19, 0x9b, 0xcd, 0x45, 0x06, 0x7c, 0x14, 0xa4, 0x99, 0xc8, 0x52,
+ 0x36, 0x5c, 0xd0, 0x60, 0x3c, 0x4a, 0xa7, 0x78, 0x34, 0x0a, 0x97, 0xef, 0xb8, 0x72, 0x44, 0x2f,
+ 0xc0, 0xf6, 0x61, 0x94, 0x17, 0x32, 0x58, 0x47, 0x65, 0xe0, 0xa2, 0x5f, 0xc3, 0x4e, 0x75, 0x42,
+ 0xf2, 0xbb, 0x09, 0x10, 0x94, 0x50, 0xe9, 0x9e, 0xa3, 0x6a, 0xd4, 0x77, 0x0d, 0x1c, 0xfa, 0x0f,
+ 0x0e, 0x6c, 0x20, 0x31, 0x61, 0x75, 0x6a, 0xe3, 0x46, 0x18, 0x72, 0xec, 0x30, 0xf4, 0x03, 0x68,
+ 0xa7, 0x67, 0x09, 0xcb, 0xe4, 0x91, 0xf2, 0x7e, 0xa9, 0xa6, 0x2a, 0x8d, 0xeb, 0x0f, 0x11, 0xcd,
+ 0x15, 0xd8, 0x68, 0x8c, 0x71, 0x74, 0x1a, 0x15, 0x32, 0xdf, 0x12, 0x03, 0x94, 0x6f, 0x94, 0x04,
+ 0xf1, 0x3c, 0x64, 0x1e, 0xb7, 0x4e, 0x79, 0x82, 0x74, 0xdc, 0x2a, 0x98, 0x7e, 0x00, 0x6d, 0x4e,
+ 0x8f, 0x74, 0x60, 0x65, 0xef, 0xe1, 0xe3, 0x7b, 0xa3, 0x25, 0x3c, 0x47, 0x1e, 0x3e, 0x7d, 0x30,
+ 0x72, 0x10, 0xf4, 0xe8, 0xe0, 0xc0, 0x1d, 0xb5, 0xe8, 0x9f, 0x39, 0x40, 0xcc, 0x85, 0x48, 0xa9,
+ 0x7c, 0x51, 0xba, 0x9a, 0x90, 0xc8, 0x87, 0x4d, 0x8b, 0x96, 0x3e, 0x24, 0x86, 0xc2, 0x8d, 0xe4,
+ 0x57, 0x93, 0xfb, 0xd0, 0x35, 0xc0, 0x0d, 0xb6, 0xfb, 0x81, 0x6d, 0xbb, 0x03, 0xdb, 0x95, 0x4d,
+ 0xd3, 0x25, 0x30, 0x42, 0xa6, 0x58, 0x87, 0x94, 0xea, 0xfc, 0x48, 0x68, 0x40, 0xc2, 0xe4, 0x9a,
+ 0xb7, 0xa0, 0x2d, 0x02, 0x87, 0x30, 0x57, 0x31, 0x28, 0x3f, 0x67, 0x5a, 0xce, 0xf4, 0x33, 0xf9,
+ 0x39, 0x33, 0xb7, 0x4c, 0xa1, 0x2d, 0xa2, 0x92, 0xd8, 0x71, 0x4f, 0xad, 0x08, 0xb1, 0x5c, 0x31,
+ 0x45, 0xff, 0xcd, 0x81, 0x35, 0xe9, 0x5d, 0x68, 0x83, 0x79, 0xe1, 0x17, 0x73, 0x75, 0x78, 0xca,
+ 0x11, 0xf9, 0x04, 0x3a, 0xb2, 0xc8, 0xc8, 0xe5, 0xe6, 0xb4, 0x39, 0x49, 0xb8, 0x5b, 0x62, 0x90,
+ 0x2b, 0xb0, 0xca, 0x53, 0x77, 0x11, 0x25, 0xbb, 0xb7, 0xfa, 0x06, 0x6e, 0x94, 0xb8, 0x72, 0x12,
+ 0xb3, 0xcb, 0x69, 0x9c, 0x06, 0x2f, 0x4e, 0x58, 0x74, 0x7c, 0x52, 0xc8, 0xc0, 0x69, 0x82, 0xca,
+ 0x60, 0xdb, 0x36, 0x82, 0xad, 0x11, 0xbe, 0x57, 0xed, 0xf0, 0x5d, 0x46, 0xba, 0x35, 0x23, 0xd2,
+ 0xd1, 0xaf, 0x61, 0xc0, 0xfd, 0x51, 0xe7, 0xc1, 0xd5, 0x30, 0xef, 0x34, 0x84, 0xf9, 0x92, 0x56,
+ 0xcb, 0xa4, 0xf5, 0x17, 0x0e, 0x90, 0x87, 0x33, 0x96, 0xfc, 0x9f, 0xa4, 0xe0, 0x3a, 0x95, 0x5e,
+ 0xb6, 0x52, 0xe9, 0xcb, 0xd0, 0x9d, 0xcd, 0xf3, 0x13, 0x4f, 0x4e, 0x8a, 0x03, 0xdd, 0x04, 0xa9,
+ 0x64, 0xbb, 0xad, 0x93, 0xed, 0x3b, 0xb0, 0x69, 0xad, 0x53, 0x9a, 0xc3, 0x87, 0x30, 0xb0, 0x93,
+ 0x6a, 0xb9, 0xce, 0x0a, 0x94, 0xfe, 0x7d, 0x0b, 0xda, 0xdc, 0x68, 0xb9, 0xfd, 0x65, 0x91, 0x2c,
+ 0x84, 0x1d, 0x57, 0x0c, 0xac, 0x04, 0xa3, 0x65, 0x27, 0x18, 0x66, 0xcc, 0x58, 0xb6, 0x63, 0xc6,
+ 0x00, 0x5a, 0x51, 0x28, 0x8b, 0x88, 0x56, 0x14, 0x92, 0x2f, 0xeb, 0x62, 0x6b, 0x73, 0xdb, 0xda,
+ 0x51, 0xf6, 0x62, 0x2b, 0xae, 0x51, 0x9c, 0x71, 0x1a, 0xf8, 0x31, 0x32, 0x13, 0xc6, 0x50, 0x8e,
+ 0xc9, 0x7b, 0x00, 0x01, 0x4f, 0xdd, 0x43, 0xcf, 0x2f, 0xb8, 0x49, 0xac, 0xb8, 0x06, 0x84, 0x5c,
+ 0x81, 0x95, 0x3c, 0x0a, 0xd9, 0xb8, 0xc3, 0x03, 0xd8, 0x86, 0xe5, 0xab, 0x47, 0x51, 0xc8, 0x5c,
+ 0x3e, 0x8d, 0xc6, 0x12, 0xe5, 0x5e, 0x7a, 0x96, 0x78, 0x3c, 0x0a, 0xf0, 0x53, 0xb4, 0xe3, 0x5a,
+ 0x30, 0x34, 0xd3, 0x93, 0x34, 0x0e, 0xf9, 0x49, 0xba, 0xe2, 0xf2, 0xdf, 0xf4, 0xcf, 0x1d, 0xe8,
+ 0x71, 0x5a, 0x2e, 0x3b, 0x4d, 0x5f, 0xfa, 0xb1, 0x25, 0x33, 0x67, 0xb1, 0xcc, 0x2a, 0xe9, 0x9e,
+ 0x99, 0x24, 0x2e, 0x57, 0x92, 0x44, 0x73, 0xf7, 0x2b, 0x95, 0xdd, 0x57, 0x97, 0xdd, 0xae, 0x2f,
+ 0x9b, 0x9e, 0xc0, 0xaa, 0x88, 0x4c, 0xe4, 0xfb, 0x00, 0xd3, 0xf9, 0x6b, 0xcf, 0x8a, 0x8e, 0x7d,
+ 0x4b, 0x22, 0xae, 0x81, 0x40, 0x6e, 0x40, 0x37, 0x67, 0x71, 0xac, 0xf0, 0x5b, 0x4d, 0xf8, 0x26,
+ 0x06, 0xfd, 0x54, 0x45, 0x4e, 0x9e, 0xce, 0xa0, 0xbc, 0x30, 0xf4, 0xc8, 0x4c, 0x99, 0xff, 0x46,
+ 0x1b, 0x4e, 0xcf, 0x12, 0x59, 0xa2, 0xe3, 0x4f, 0xfa, 0x73, 0x47, 0x7e, 0xf5, 0x64, 0x16, 0xfa,
+ 0x05, 0xc3, 0xcc, 0x40, 0xec, 0xc5, 0xe1, 0x46, 0x62, 0xf3, 0xbb, 0xb7, 0xe4, 0x8a, 0x59, 0xf2,
+ 0x1b, 0xd0, 0x17, 0x12, 0xca, 0x84, 0xe0, 0x65, 0xbc, 0xda, 0xb2, 0x97, 0x27, 0xe6, 0xee, 0x2d,
+ 0xb9, 0x36, 0xf2, 0xde, 0x00, 0x7a, 0x02, 0x30, 0xe7, 0x4c, 0xe9, 0xbf, 0xb6, 0x60, 0x05, 0x83,
+ 0xe5, 0xe2, 0xba, 0xe2, 0x8d, 0xb2, 0xc6, 0x2f, 0xa1, 0x17, 0x27, 0xa1, 0x1a, 0xaa, 0xb8, 0x78,
+ 0xc9, 0x0c, 0xc7, 0x98, 0xe1, 0x3c, 0x9a, 0x4f, 0xbf, 0x61, 0xaf, 0xe5, 0xb1, 0x63, 0x7d, 0x81,
+ 0xfc, 0xa3, 0x64, 0x9a, 0xce, 0x93, 0x50, 0x9e, 0x8d, 0x6a, 0xa8, 0x8f, 0x88, 0xb6, 0x71, 0x44,
+ 0x60, 0xd4, 0x78, 0x35, 0x0f, 0x3d, 0x3b, 0x54, 0x9a, 0x20, 0xf2, 0x09, 0x6c, 0xe4, 0x2c, 0x48,
+ 0x93, 0x30, 0x17, 0x15, 0x67, 0x50, 0xb0, 0x90, 0xfb, 0x49, 0xdf, 0xad, 0x4f, 0x34, 0xa7, 0x91,
+ 0x93, 0x3b, 0x30, 0xac, 0x2c, 0xbb, 0xe1, 0x58, 0xdc, 0x32, 0x8f, 0xc5, 0x75, 0xf3, 0x18, 0xfc,
+ 0xfd, 0x16, 0x6c, 0x3c, 0xc2, 0xe2, 0x50, 0x2a, 0x45, 0x84, 0xd3, 0xff, 0xcd, 0x98, 0x63, 0xfa,
+ 0xcf, 0x4a, 0xc5, 0x7f, 0x54, 0x04, 0x68, 0x9f, 0x1f, 0x01, 0xae, 0xc1, 0x28, 0x63, 0xbc, 0x84,
+ 0xf5, 0x4a, 0x52, 0x42, 0x9c, 0x35, 0x38, 0x26, 0xcf, 0xd1, 0xe9, 0x29, 0x0b, 0x23, 0xbf, 0x40,
+ 0xa8, 0x17, 0x60, 0x89, 0x12, 0x73, 0xa9, 0x76, 0xdc, 0xa6, 0x29, 0x14, 0x01, 0x31, 0x45, 0x20,
+ 0x23, 0xf5, 0xe7, 0x30, 0x8a, 0x92, 0x82, 0x65, 0x89, 0x1f, 0x7b, 0xa7, 0x7e, 0x11, 0x9c, 0xb0,
+ 0x05, 0x7e, 0x59, 0x43, 0x23, 0x3f, 0x82, 0x01, 0xcf, 0xce, 0xf3, 0x79, 0x10, 0xb0, 0x1c, 0x93,
+ 0x29, 0xe1, 0xa0, 0x65, 0x56, 0x8e, 0x45, 0xe8, 0x91, 0x98, 0x74, 0x2b, 0xa8, 0xe4, 0x33, 0xcc,
+ 0x54, 0x4f, 0xfd, 0x28, 0xc1, 0x24, 0x5f, 0xb8, 0xdb, 0x72, 0x83, 0xbb, 0xb9, 0x55, 0x2c, 0xf2,
+ 0x39, 0xf4, 0x39, 0xa9, 0xe7, 0x7e, 0x14, 0xcf, 0x33, 0x9e, 0xc1, 0xd5, 0x98, 0xfe, 0x58, 0xcc,
+ 0xb9, 0x36, 0x26, 0xfd, 0x4f, 0x07, 0x86, 0x5a, 0x04, 0x07, 0x2f, 0x59, 0x82, 0xd1, 0xb9, 0xcd,
+ 0xf7, 0xb3, 0xd0, 0xd9, 0xf9, 0x2c, 0xf9, 0x1c, 0x7a, 0xe6, 0x06, 0xa4, 0xaf, 0x37, 0xed, 0xf4,
+ 0xde, 0x92, 0x6b, 0xa1, 0x92, 0xcf, 0xdf, 0x6c, 0xa7, 0xf7, 0x96, 0x9a, 0xf6, 0xda, 0x33, 0x77,
+ 0xc0, 0x0d, 0xab, 0x79, 0xab, 0x25, 0x57, 0x89, 0xba, 0xb7, 0x06, 0x6d, 0x86, 0x1b, 0xa4, 0x29,
+ 0x74, 0x8d, 0xea, 0x68, 0x61, 0xe2, 0x65, 0x84, 0x9d, 0x96, 0x1d, 0x76, 0x8c, 0x3c, 0x68, 0xa5,
+ 0x96, 0x07, 0x89, 0x36, 0x6a, 0xdb, 0x68, 0xa3, 0xd2, 0x4f, 0x61, 0x9b, 0x47, 0x3d, 0xa6, 0x7b,
+ 0xee, 0xbf, 0xb8, 0xf8, 0x1f, 0xc3, 0x4e, 0xf5, 0x23, 0xd9, 0x4b, 0x3b, 0x04, 0x22, 0x66, 0x2c,
+ 0xd7, 0x3d, 0xaf, 0xa7, 0x71, 0x8e, 0x03, 0xd3, 0xbf, 0x72, 0x60, 0xd3, 0x22, 0x27, 0xdd, 0xe0,
+ 0x3d, 0x18, 0x29, 0x1c, 0x2f, 0x4d, 0x3c, 0x7e, 0xca, 0x3a, 0xfa, 0x94, 0x25, 0xd7, 0x81, 0x68,
+ 0xe5, 0x54, 0xa8, 0x37, 0xcc, 0x08, 0x5f, 0x46, 0x36, 0xa1, 0xc6, 0x16, 0xd9, 0x56, 0x0d, 0x6e,
+ 0x06, 0x95, 0x15, 0x2b, 0xa8, 0x68, 0xa9, 0xec, 0xc6, 0xb1, 0x55, 0xec, 0xd0, 0x39, 0x5c, 0xa8,
+ 0xcd, 0xc8, 0xad, 0x7c, 0x02, 0x1b, 0x8a, 0x85, 0x12, 0x89, 0xca, 0xea, 0xeb, 0x13, 0x88, 0x2d,
+ 0xf7, 0x6b, 0x60, 0x8b, 0xf6, 0x61, 0x7d, 0x82, 0x7e, 0x1f, 0x36, 0x04, 0x5b, 0xf3, 0xe2, 0x64,
+ 0x61, 0xf1, 0x86, 0x85, 0xb3, 0x89, 0x2e, 0x35, 0xfa, 0x07, 0x2d, 0x04, 0xe7, 0x45, 0x9a, 0x59,
+ 0xfd, 0xd1, 0x37, 0x6a, 0x76, 0x9a, 0x4d, 0xd4, 0x96, 0xdd, 0x44, 0x25, 0xdf, 0x40, 0x17, 0x4f,
+ 0xb2, 0xa9, 0x1f, 0xbc, 0x98, 0xcf, 0xd4, 0xd1, 0x77, 0x4d, 0x39, 0x4b, 0x9d, 0x23, 0x1e, 0x84,
+ 0x7b, 0x02, 0x59, 0x1c, 0x84, 0x10, 0x97, 0x00, 0xf2, 0x3d, 0x7e, 0xc3, 0xe4, 0x85, 0x7e, 0xe1,
+ 0x4f, 0xfd, 0x5c, 0x34, 0x98, 0x7b, 0xfc, 0x5c, 0xbb, 0x2b, 0x41, 0xf2, 0x4c, 0x32, 0x29, 0xfc,
+ 0xa2, 0x33, 0xa9, 0x67, 0x9e, 0x49, 0x0c, 0x2d, 0xd1, 0x58, 0x93, 0xee, 0xf9, 0x66, 0x02, 0x2c,
+ 0x7b, 0xb9, 0x52, 0x0c, 0x0a, 0xc8, 0x1b, 0xb9, 0x1f, 0xa1, 0x79, 0x49, 0x24, 0xd5, 0x12, 0x11,
+ 0xc5, 0xfc, 0x50, 0xc1, 0x55, 0x0b, 0xf7, 0x2e, 0x90, 0x23, 0x56, 0x1c, 0xa6, 0xc7, 0x87, 0xec,
+ 0xa5, 0xae, 0x24, 0xae, 0xc3, 0x7a, 0x9c, 0x1e, 0x7b, 0x31, 0xc2, 0xf8, 0x72, 0x07, 0xba, 0xd0,
+ 0x2a, 0x71, 0x35, 0x0a, 0xdd, 0x86, 0x4d, 0x8b, 0x8a, 0x54, 0xe5, 0x06, 0x0c, 0x8f, 0x4e, 0xe6,
+ 0x45, 0x98, 0x9e, 0xa9, 0xdb, 0x19, 0x2c, 0x19, 0x35, 0x48, 0xa2, 0xfd, 0x1a, 0xec, 0x1c, 0xcd,
+ 0xa7, 0x79, 0x90, 0x45, 0x53, 0x66, 0x17, 0xfe, 0x13, 0xe8, 0xb0, 0x57, 0x51, 0x5e, 0x44, 0xc9,
+ 0x31, 0x5f, 0x46, 0xc7, 0x2d, 0xc7, 0xf4, 0x7d, 0x78, 0xb7, 0xfc, 0x0a, 0x43, 0x5d, 0xbe, 0x1b,
+ 0x04, 0x6c, 0x56, 0x30, 0x75, 0x17, 0x42, 0xef, 0xc0, 0xb6, 0x8d, 0x60, 0x5c, 0xe5, 0xa9, 0x82,
+ 0xbe, 0xf0, 0x5f, 0xc8, 0x4c, 0xae, 0xe3, 0xda, 0x40, 0xfa, 0xdf, 0x2d, 0xe8, 0xe1, 0x67, 0x8a,
+ 0x2c, 0xb9, 0x58, 0x0b, 0x2a, 0x6b, 0x7c, 0x7c, 0xdf, 0x4e, 0x81, 0x5b, 0x95, 0x14, 0xf8, 0xdc,
+ 0xa4, 0x60, 0x51, 0x7f, 0x54, 0x27, 0x1f, 0x6d, 0x33, 0xf9, 0xa8, 0x76, 0x5d, 0x57, 0x1b, 0xba,
+ 0xae, 0x3b, 0xb0, 0x9a, 0xf1, 0x96, 0x98, 0xac, 0x3f, 0xe5, 0x08, 0x63, 0x8e, 0xa8, 0xd3, 0xbc,
+ 0x8c, 0x05, 0x2c, 0x7a, 0x89, 0x32, 0xed, 0x88, 0x98, 0x53, 0x85, 0x63, 0x81, 0x26, 0x61, 0xb9,
+ 0xbc, 0x98, 0x5a, 0x17, 0x37, 0x77, 0x36, 0x14, 0xe3, 0x9e, 0x8a, 0xd1, 0x06, 0x55, 0xd1, 0xc9,
+ 0x6b, 0x98, 0xc1, 0x35, 0x94, 0x50, 0x45, 0xb9, 0x2b, 0x72, 0x98, 0x2a, 0x1c, 0x63, 0x71, 0xd7,
+ 0x38, 0xc2, 0x7e, 0xc9, 0x3e, 0xb5, 0x29, 0xe3, 0xe5, 0x8a, 0x8c, 0xab, 0xd2, 0x5c, 0x69, 0x90,
+ 0xe6, 0x87, 0x30, 0x90, 0x67, 0xa6, 0x97, 0x31, 0x3f, 0x4f, 0xd5, 0x69, 0x56, 0x81, 0xd2, 0xbf,
+ 0x59, 0x16, 0xab, 0x95, 0xc7, 0xfc, 0xff, 0xaf, 0xb1, 0x68, 0x95, 0xb7, 0x2d, 0x95, 0x5f, 0x85,
+ 0xa1, 0xa5, 0x5a, 0x16, 0x4a, 0x8d, 0x57, 0xc1, 0x98, 0xa6, 0x6b, 0xd5, 0x16, 0x52, 0xdb, 0x26,
+ 0xa8, 0x26, 0x2c, 0x68, 0x10, 0xd6, 0x65, 0x58, 0xc9, 0xd2, 0x98, 0x71, 0x95, 0x0e, 0x74, 0x97,
+ 0xc7, 0x4d, 0x63, 0xe6, 0xf2, 0x19, 0x3c, 0x4f, 0x2a, 0x66, 0xc1, 0x42, 0xde, 0xad, 0x5d, 0x77,
+ 0xeb, 0x13, 0xe8, 0xa8, 0xa6, 0x59, 0x14, 0xe3, 0xbe, 0xb8, 0xf7, 0xb1, 0x80, 0x58, 0x61, 0x67,
+ 0xde, 0x2c, 0x63, 0xd1, 0xa9, 0x7f, 0xcc, 0xc6, 0x03, 0x8e, 0x62, 0x40, 0xb4, 0x2b, 0x0d, 0x0d,
+ 0x57, 0xa2, 0xff, 0xd5, 0x82, 0xf6, 0xe3, 0xcc, 0x0f, 0x19, 0x96, 0x91, 0xa7, 0xe8, 0xf1, 0xde,
+ 0xe2, 0xb2, 0xce, 0x35, 0x31, 0xf0, 0x83, 0xc2, 0xf8, 0xa0, 0xd5, 0xf8, 0x81, 0x81, 0x61, 0xe8,
+ 0x67, 0xd9, 0xd2, 0xcf, 0x79, 0x3a, 0x35, 0x2c, 0xa1, 0x6d, 0x5b, 0x42, 0xb9, 0x9f, 0x55, 0x33,
+ 0x34, 0x28, 0xd9, 0xaf, 0x2d, 0x94, 0xfd, 0x65, 0xe8, 0x32, 0x71, 0xfd, 0xc3, 0x5b, 0x11, 0xc2,
+ 0x12, 0x4c, 0x50, 0x59, 0x89, 0xac, 0x9f, 0x5f, 0x89, 0xdc, 0x86, 0x5e, 0x80, 0x86, 0xc1, 0xb2,
+ 0x99, 0x9f, 0x15, 0xc2, 0x14, 0x16, 0x77, 0x4b, 0x2c, 0x5c, 0xfa, 0x31, 0x6c, 0x72, 0xa9, 0xdf,
+ 0x8b, 0xf0, 0x1c, 0x7a, 0x6d, 0xd4, 0x5a, 0xa2, 0x21, 0xeb, 0x18, 0x0d, 0x59, 0x7a, 0x07, 0xb6,
+ 0x6c, 0x64, 0x79, 0x08, 0x5e, 0x81, 0xd5, 0x02, 0xe1, 0xb5, 0x5a, 0x84, 0x63, 0xbb, 0x72, 0x92,
+ 0xfe, 0xb1, 0x03, 0x7d, 0x84, 0x44, 0xc9, 0xf1, 0x21, 0xd2, 0xcb, 0x51, 0xe0, 0xa7, 0xfe, 0x2b,
+ 0x2f, 0x67, 0x71, 0xac, 0x9a, 0x1f, 0x6a, 0x8c, 0x02, 0xc7, 0xdf, 0xd3, 0xb9, 0x4a, 0xdc, 0xd4,
+ 0x10, 0xcd, 0x30, 0x63, 0x39, 0xcb, 0x30, 0x35, 0xe2, 0x9f, 0x8a, 0x40, 0x62, 0x03, 0xd1, 0x41,
+ 0x4a, 0x00, 0x12, 0x11, 0x0a, 0xb5, 0x60, 0xf4, 0x96, 0xd8, 0x50, 0xb9, 0xa0, 0x37, 0xc9, 0x7d,
+ 0xff, 0xda, 0x81, 0xed, 0xca, 0x47, 0x52, 0x0c, 0xbb, 0xb0, 0xca, 0xe5, 0xa4, 0xc4, 0xf0, 0x91,
+ 0x29, 0x86, 0x1a, 0xfa, 0x75, 0x31, 0x94, 0xbd, 0x64, 0xf1, 0xe1, 0xe4, 0x11, 0x74, 0x0d, 0x70,
+ 0x43, 0x82, 0xf2, 0xb1, 0xdd, 0x4b, 0xde, 0x6e, 0x66, 0x61, 0xe4, 0x2d, 0xdf, 0x42, 0xef, 0x49,
+ 0x32, 0xfd, 0x25, 0x9e, 0x63, 0x90, 0x4b, 0xb0, 0x9e, 0x31, 0x59, 0xe9, 0xcb, 0x74, 0x45, 0x03,
+ 0xe8, 0x10, 0xfa, 0x92, 0xae, 0xbe, 0x45, 0x7f, 0x92, 0xc4, 0x69, 0xf0, 0xe2, 0x4d, 0x6f, 0xd1,
+ 0x7f, 0x0a, 0xc4, 0xfc, 0x40, 0x27, 0x54, 0x73, 0x0e, 0xad, 0x24, 0x54, 0x0a, 0xc8, 0x13, 0xaa,
+ 0xf7, 0xa1, 0x6b, 0xa2, 0x88, 0x4b, 0x37, 0xd0, 0x08, 0xf4, 0x8f, 0x1c, 0x18, 0x3e, 0x8d, 0x8a,
+ 0x93, 0x30, 0xf3, 0xcf, 0xde, 0x40, 0xa9, 0xd5, 0x17, 0x0d, 0xad, 0xf3, 0x5e, 0x34, 0x2c, 0x57,
+ 0x5f, 0x34, 0xf8, 0x71, 0x2c, 0x9b, 0x2f, 0xf8, 0xd3, 0x6c, 0xbb, 0xf6, 0x45, 0xdb, 0xf5, 0x36,
+ 0x8c, 0xf4, 0x62, 0xde, 0xae, 0xe7, 0x7a, 0xed, 0x2a, 0xac, 0x97, 0xfe, 0x4e, 0xd6, 0x60, 0x79,
+ 0xef, 0xc9, 0x6f, 0x8e, 0x96, 0x48, 0x07, 0x56, 0x8e, 0x0e, 0x0e, 0x0f, 0xc5, 0xf5, 0x06, 0xbf,
+ 0xf1, 0x68, 0x5d, 0xbb, 0x06, 0x2b, 0x18, 0x5d, 0xc8, 0x3a, 0xb4, 0x1f, 0xef, 0x7e, 0x73, 0xe0,
+ 0x8e, 0x96, 0xf0, 0xe7, 0x4f, 0xf8, 0x4f, 0x87, 0xf4, 0xa0, 0x73, 0xff, 0xc1, 0xe3, 0x03, 0xf7,
+ 0xc1, 0xee, 0xe1, 0xa8, 0x75, 0xed, 0x29, 0x74, 0x54, 0x76, 0x88, 0x48, 0xbb, 0x87, 0x07, 0xee,
+ 0x63, 0x81, 0x7f, 0xe0, 0xba, 0x0f, 0x5d, 0x41, 0xf7, 0xe9, 0xae, 0xfb, 0x60, 0xd4, 0xc2, 0x5f,
+ 0xf7, 0x1f, 0xfc, 0xf8, 0xe1, 0x68, 0x99, 0x74, 0x61, 0xed, 0xdb, 0x03, 0x77, 0xef, 0xe1, 0xd1,
+ 0xc1, 0x68, 0x05, 0x71, 0xef, 0x1e, 0xec, 0x3d, 0xf9, 0x6a, 0xd4, 0xe6, 0x1c, 0xdd, 0xdd, 0xfd,
+ 0x83, 0xd1, 0xea, 0xad, 0x7f, 0x77, 0x60, 0xed, 0xd9, 0x3c, 0xbc, 0x9f, 0x44, 0x05, 0x39, 0x00,
+ 0xd0, 0xaf, 0x24, 0xc8, 0xc5, 0xb2, 0xdb, 0x5f, 0x7d, 0x6b, 0x31, 0x99, 0x34, 0x4d, 0x49, 0xb3,
+ 0x5a, 0x22, 0xf7, 0xa0, 0x6b, 0x64, 0xde, 0x64, 0xb2, 0xb8, 0x44, 0x98, 0xbc, 0xd3, 0x38, 0x57,
+ 0x52, 0x3a, 0x00, 0xd0, 0x16, 0xa7, 0x17, 0x54, 0x33, 0x5b, 0xbd, 0xa0, 0xba, 0x81, 0xd2, 0xa5,
+ 0x5b, 0xff, 0x7c, 0x11, 0x96, 0x9f, 0xcd, 0x43, 0xf2, 0x0c, 0xba, 0xc6, 0x5b, 0x35, 0x52, 0xbb,
+ 0x49, 0xd3, 0xcb, 0x69, 0x7a, 0xd2, 0x36, 0xf9, 0xf9, 0x3f, 0xfe, 0xc7, 0x9f, 0xb4, 0xb6, 0xe8,
+ 0xf0, 0xc6, 0xcb, 0x5f, 0xbd, 0xe1, 0x87, 0xa1, 0xb2, 0xc5, 0xdb, 0xce, 0x35, 0xe2, 0xc2, 0x9a,
+ 0x7c, 0x8e, 0x46, 0x76, 0x0c, 0x1a, 0x46, 0x19, 0x37, 0xb9, 0x50, 0x83, 0x4b, 0xba, 0x3b, 0x9c,
+ 0xee, 0x88, 0x76, 0x25, 0x5d, 0x3c, 0xa6, 0x90, 0xe6, 0x1e, 0x2c, 0xef, 0xf9, 0x09, 0x21, 0xfa,
+ 0xa2, 0x5c, 0xc5, 0x84, 0xc9, 0xa6, 0x05, 0x93, 0x74, 0x08, 0xa7, 0xd3, 0xa3, 0x6b, 0x48, 0x67,
+ 0xea, 0x27, 0x48, 0xe3, 0x18, 0x06, 0xf6, 0x33, 0x24, 0xf2, 0xae, 0x79, 0xdf, 0x53, 0x7b, 0xff,
+ 0x34, 0x79, 0x6f, 0xd1, 0x74, 0x65, 0xb1, 0x03, 0x64, 0x12, 0x70, 0x1c, 0x8c, 0x0f, 0x24, 0x80,
+ 0x9e, 0xf9, 0x2a, 0x88, 0xe8, 0xb7, 0x29, 0xf5, 0xa7, 0x4e, 0x93, 0x4b, 0xcd, 0x93, 0x92, 0xc5,
+ 0x98, 0xb3, 0x20, 0x74, 0xc4, 0x59, 0x20, 0x86, 0xbc, 0x90, 0x42, 0x29, 0xcb, 0xa7, 0x40, 0x5a,
+ 0xca, 0xf6, 0x4b, 0x22, 0x2d, 0xe5, 0xea, 0x9b, 0x21, 0x4b, 0xca, 0x32, 0x26, 0xa2, 0x84, 0x7e,
+ 0x06, 0xfd, 0xa7, 0xfc, 0x35, 0x9c, 0x7c, 0x80, 0xa2, 0x29, 0xdb, 0xef, 0x57, 0x34, 0xe5, 0xca,
+ 0x4b, 0x15, 0x7a, 0x89, 0x53, 0xde, 0xa1, 0x1b, 0x48, 0x59, 0xbc, 0xac, 0x0b, 0x05, 0x0a, 0xd2,
+ 0xff, 0x1d, 0xe8, 0x5b, 0x6f, 0x4d, 0x48, 0xb9, 0xf9, 0xa6, 0x47, 0x2c, 0x93, 0x77, 0x17, 0xcc,
+ 0x36, 0xf1, 0x0a, 0x25, 0x0a, 0x7f, 0x9d, 0x82, 0xbc, 0x9e, 0x01, 0xe8, 0x37, 0x1b, 0xda, 0x5d,
+ 0x6a, 0xef, 0x44, 0xb4, 0xbb, 0xd4, 0x9f, 0x78, 0xd0, 0x4d, 0xce, 0xa2, 0x4f, 0xba, 0xc2, 0x8c,
+ 0x04, 0xad, 0x43, 0x58, 0x93, 0xaf, 0x13, 0xb4, 0x7c, 0xec, 0x27, 0x1a, 0x5a, 0x3e, 0x95, 0x67,
+ 0x0c, 0x74, 0xc4, 0x09, 0x02, 0xe9, 0x20, 0xc1, 0x08, 0x49, 0xfc, 0x16, 0x74, 0x8d, 0xab, 0x7d,
+ 0x62, 0xae, 0xa6, 0xf2, 0x0a, 0x40, 0x7b, 0x64, 0xc3, 0x5b, 0x00, 0xba, 0xc5, 0x29, 0x0f, 0x48,
+ 0x0f, 0x29, 0xab, 0xbe, 0x86, 0xa4, 0xae, 0xee, 0xee, 0x2d, 0xea, 0x95, 0x07, 0x01, 0x16, 0xf5,
+ 0xea, 0x65, 0xbf, 0x4d, 0x1d, 0x65, 0xcc, 0xd7, 0xfe, 0x14, 0x40, 0x5f, 0x33, 0x6b, 0x19, 0xd7,
+ 0xee, 0xcb, 0xb5, 0x8c, 0xeb, 0xb7, 0xd2, 0xca, 0x55, 0x09, 0x20, 0x69, 0x79, 0x19, 0x73, 0x0c,
+ 0x03, 0xfb, 0x15, 0x80, 0x76, 0xd5, 0xc6, 0x67, 0x03, 0xda, 0x55, 0x9b, 0x1f, 0x0f, 0x28, 0x8b,
+ 0x27, 0xc2, 0x55, 0x35, 0xd9, 0x23, 0x58, 0x2f, 0xef, 0xa7, 0xc9, 0xd8, 0x24, 0x62, 0x5e, 0x63,
+ 0x4f, 0x2e, 0x36, 0xcc, 0xa8, 0xb6, 0x04, 0xa7, 0xdc, 0x25, 0xeb, 0x48, 0x59, 0x5c, 0x53, 0x28,
+ 0xa2, 0xfc, 0xa5, 0x8c, 0x4d, 0xd4, 0xb8, 0xdc, 0xae, 0x10, 0x35, 0xaf, 0xb8, 0x2b, 0x44, 0x39,
+ 0x1d, 0x0f, 0xba, 0xc6, 0xed, 0xa7, 0xd6, 0x64, 0xfd, 0xea, 0x56, 0x6b, 0xb2, 0xe1, 0xba, 0x94,
+ 0x5e, 0xe0, 0xa4, 0x37, 0x44, 0xe4, 0x4e, 0x67, 0x2c, 0x51, 0x01, 0xe5, 0xb7, 0x01, 0x74, 0xc3,
+ 0x5a, 0x2b, 0xb3, 0x76, 0x95, 0xa1, 0x8d, 0xbb, 0xd2, 0xdf, 0xa6, 0x17, 0x39, 0xe9, 0x4d, 0x11,
+ 0x0f, 0xf9, 0x25, 0x02, 0x57, 0xe7, 0x6d, 0xe7, 0xda, 0x4d, 0x87, 0x3c, 0x87, 0x81, 0xc6, 0x3f,
+ 0x7a, 0x9d, 0x04, 0xe7, 0xb1, 0x98, 0x34, 0x4d, 0xc9, 0x0d, 0xbc, 0xcb, 0xb9, 0x5c, 0xa0, 0xc4,
+ 0xe6, 0x92, 0xbf, 0x4e, 0x02, 0xf4, 0xfb, 0x9f, 0x42, 0xd7, 0x78, 0x97, 0xa6, 0xe5, 0x54, 0x7f,
+ 0xac, 0x36, 0x69, 0x6a, 0xa9, 0xdb, 0x27, 0x9b, 0xac, 0x67, 0xf2, 0x33, 0x7f, 0x86, 0xb4, 0x13,
+ 0x18, 0xd8, 0x9d, 0x63, 0x6d, 0x96, 0x8d, 0x6d, 0x68, 0x6d, 0x96, 0x0b, 0x1a, 0xce, 0xd6, 0x5e,
+ 0x44, 0xc3, 0xd4, 0x3c, 0x49, 0xa7, 0x98, 0x3c, 0x94, 0x0d, 0x64, 0x33, 0x79, 0xa8, 0x36, 0xa9,
+ 0xcd, 0xe4, 0xa1, 0xd6, 0x71, 0xb6, 0xf7, 0x24, 0xd8, 0x28, 0xcd, 0x90, 0x0c, 0x86, 0x95, 0xee,
+ 0x2e, 0xa9, 0xac, 0xba, 0xda, 0x10, 0x9e, 0xbc, 0xbf, 0x70, 0x5e, 0xf2, 0x7b, 0x8f, 0xf3, 0x1b,
+ 0xd3, 0x4d, 0xcd, 0xcf, 0x8f, 0x63, 0xa1, 0x26, 0x71, 0xce, 0x80, 0xee, 0xd5, 0x6a, 0x3b, 0xa8,
+ 0xb5, 0x7b, 0x27, 0x93, 0xa6, 0x29, 0xc9, 0xc4, 0xb2, 0x36, 0xc1, 0x44, 0x65, 0x0b, 0x53, 0xe8,
+ 0x1a, 0x1d, 0x44, 0x2d, 0xb7, 0x7a, 0x73, 0x52, 0xcb, 0xad, 0xa9, 0xe5, 0x68, 0xc9, 0x2d, 0x67,
+ 0x45, 0x9c, 0x1e, 0xf3, 0x16, 0x25, 0xf2, 0xf8, 0x16, 0x3a, 0xaa, 0xf7, 0x48, 0x4a, 0x8f, 0xa8,
+ 0x34, 0x28, 0x27, 0xe3, 0xfa, 0x44, 0xc5, 0x0d, 0x79, 0x40, 0xcd, 0xe5, 0x2c, 0xd2, 0x65, 0x30,
+ 0xac, 0xf4, 0x2f, 0xb5, 0x3e, 0x9a, 0x1b, 0x9b, 0x13, 0xfb, 0x79, 0x9d, 0xb8, 0x59, 0xa6, 0xef,
+ 0x70, 0x06, 0xdb, 0x84, 0xeb, 0x20, 0x57, 0x1f, 0x0a, 0x1d, 0xdc, 0x74, 0xc8, 0xac, 0xd2, 0xcf,
+ 0x94, 0x8d, 0x31, 0x23, 0xd0, 0x36, 0xb6, 0x3b, 0x27, 0x4d, 0x17, 0x42, 0xf4, 0x7b, 0x9c, 0xd7,
+ 0x3b, 0xe4, 0xa2, 0xc5, 0x0b, 0xbd, 0x46, 0xdd, 0x87, 0xdd, 0x74, 0xc8, 0x14, 0x06, 0x36, 0xc9,
+ 0xb7, 0x62, 0x55, 0x71, 0x4f, 0x42, 0x6a, 0xac, 0x90, 0xc7, 0xef, 0x19, 0xcd, 0x5f, 0xab, 0x8d,
+ 0x4b, 0xae, 0x34, 0xf3, 0xaa, 0xb4, 0x79, 0x27, 0x5b, 0x26, 0x4f, 0x35, 0x49, 0x29, 0x67, 0x7a,
+ 0x89, 0x4c, 0xea, 0x4c, 0x7d, 0x89, 0xc3, 0x23, 0x5c, 0xcf, 0x6c, 0x30, 0xe8, 0xb4, 0xaf, 0xa1,
+ 0x47, 0xa1, 0xd3, 0xbe, 0xa6, 0x9e, 0x84, 0x52, 0x9e, 0x48, 0xfb, 0x78, 0x03, 0xe2, 0x44, 0x60,
+ 0x88, 0x3c, 0xb6, 0xd2, 0x88, 0xb8, 0xb4, 0xa0, 0x54, 0xaf, 0x64, 0x51, 0x8d, 0x85, 0xbc, 0x72,
+ 0x23, 0xb2, 0xa1, 0x58, 0x45, 0xc9, 0xb1, 0xa8, 0xe7, 0xc9, 0xd7, 0xd0, 0xe6, 0x55, 0x32, 0xd9,
+ 0xd2, 0x15, 0x85, 0x2e, 0xc6, 0x27, 0xdb, 0x15, 0xa8, 0x9d, 0x2a, 0x50, 0x7e, 0x76, 0xcd, 0x13,
+ 0x99, 0x7c, 0x4f, 0x61, 0x20, 0x52, 0x4b, 0x55, 0x4b, 0x6a, 0xa7, 0xa9, 0x94, 0xba, 0xda, 0x69,
+ 0xaa, 0x65, 0xa7, 0x1d, 0x2e, 0x45, 0x76, 0x79, 0x26, 0x71, 0x6e, 0x3b, 0xd7, 0xa6, 0xab, 0xfc,
+ 0x5f, 0x38, 0x9f, 0xfe, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x9c, 0x44, 0x52, 0xb0, 0x33,
+ 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -5155,6 +5239,9 @@ type XudClient interface {
// to a specific node.
// shell: xucli ban
Ban(ctx context.Context, in *BanRequest, opts ...grpc.CallOption) (*BanResponse, error)
+ // Changes the xud master password, including the wallet passwords for any underlying clients.
+ // shell: xucli changepass
+ ChangePassword(ctx context.Context, in *ChangePasswordRequest, opts ...grpc.CallOption) (*ChangePasswordResponse, error)
// Closes any existing payment channels with a peer for the specified currency.
// shell: xucli closechannel [node_identifier ] [--force]
CloseChannel(ctx context.Context, in *CloseChannelRequest, opts ...grpc.CallOption) (*CloseChannelResponse, error)
@@ -5304,6 +5391,15 @@ func (c *xudClient) Ban(ctx context.Context, in *BanRequest, opts ...grpc.CallOp
return out, nil
}
+func (c *xudClient) ChangePassword(ctx context.Context, in *ChangePasswordRequest, opts ...grpc.CallOption) (*ChangePasswordResponse, error) {
+ out := new(ChangePasswordResponse)
+ err := c.cc.Invoke(ctx, "/xudrpc.Xud/ChangePassword", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
func (c *xudClient) CloseChannel(ctx context.Context, in *CloseChannelRequest, opts ...grpc.CallOption) (*CloseChannelResponse, error) {
out := new(CloseChannelResponse)
err := c.cc.Invoke(ctx, "/xudrpc.Xud/CloseChannel", in, out, opts...)
@@ -5703,6 +5799,9 @@ type XudServer interface {
// to a specific node.
// shell: xucli ban
Ban(context.Context, *BanRequest) (*BanResponse, error)
+ // Changes the xud master password, including the wallet passwords for any underlying clients.
+ // shell: xucli changepass
+ ChangePassword(context.Context, *ChangePasswordRequest) (*ChangePasswordResponse, error)
// Closes any existing payment channels with a peer for the specified currency.
// shell: xucli closechannel [node_identifier ] [--force]
CloseChannel(context.Context, *CloseChannelRequest) (*CloseChannelResponse, error)
@@ -5875,6 +5974,24 @@ func _Xud_Ban_Handler(srv interface{}, ctx context.Context, dec func(interface{}
return interceptor(ctx, in, info, handler)
}
+func _Xud_ChangePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ChangePasswordRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(XudServer).ChangePassword(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/xudrpc.Xud/ChangePassword",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(XudServer).ChangePassword(ctx, req.(*ChangePasswordRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
func _Xud_CloseChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseChannelRequest)
if err := dec(in); err != nil {
@@ -6446,6 +6563,10 @@ var _Xud_serviceDesc = grpc.ServiceDesc{
MethodName: "Ban",
Handler: _Xud_Ban_Handler,
},
+ {
+ MethodName: "ChangePassword",
+ Handler: _Xud_ChangePassword_Handler,
+ },
{
MethodName: "CloseChannel",
Handler: _Xud_CloseChannel_Handler,