diff --git a/docs/api.md b/docs/api.md
index ad370b3f1..dad06172b 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -7,7 +7,9 @@
- [AddCurrencyResponse](#xudrpc.AddCurrencyResponse)
- [AddPairRequest](#xudrpc.AddPairRequest)
- [AddPairResponse](#xudrpc.AddPairResponse)
+ - [Alert](#xudrpc.Alert)
- [Balance](#xudrpc.Balance)
+ - [BalanceAlert](#xudrpc.BalanceAlert)
- [BanRequest](#xudrpc.BanRequest)
- [BanResponse](#xudrpc.BanResponse)
- [Chain](#xudrpc.Chain)
@@ -76,6 +78,7 @@
- [SetLogLevelResponse](#xudrpc.SetLogLevelResponse)
- [ShutdownRequest](#xudrpc.ShutdownRequest)
- [ShutdownResponse](#xudrpc.ShutdownResponse)
+ - [SubscribeAlertsRequest](#xudrpc.SubscribeAlertsRequest)
- [SubscribeOrdersRequest](#xudrpc.SubscribeOrdersRequest)
- [SubscribeSwapsAcceptedRequest](#xudrpc.SubscribeSwapsAcceptedRequest)
- [SubscribeSwapsRequest](#xudrpc.SubscribeSwapsRequest)
@@ -96,6 +99,8 @@
- [WithdrawRequest](#xudrpc.WithdrawRequest)
- [WithdrawResponse](#xudrpc.WithdrawResponse)
+ - [Alert.AlertType](#xudrpc.Alert.AlertType)
+ - [BalanceAlert.Side](#xudrpc.BalanceAlert.Side)
- [Currency.SwapClient](#xudrpc.Currency.SwapClient)
- [ListOrdersRequest.Owner](#xudrpc.ListOrdersRequest.Owner)
- [LogLevel](#xudrpc.LogLevel)
@@ -152,6 +157,24 @@
+
+
+### Alert
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| type | [Alert.AlertType](#xudrpc.Alert.AlertType) | | |
+| message | [string](#string) | | The human readable alert message. |
+| date | [int64](#int64) | | The human readable alert message. |
+| balance_alert | [BalanceAlert](#xudrpc.BalanceAlert) | | |
+
+
+
+
+
+
### Balance
@@ -172,6 +195,26 @@
+
+
+### BalanceAlert
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| total_balance | [uint64](#uint64) | | The total balance. |
+| side | [BalanceAlert.Side](#xudrpc.BalanceAlert.Side) | | |
+| bound | [uint32](#uint32) | | The bound of the low balance in percentage. |
+| percent | [uint32](#uint32) | | The percent of the total trading balance. |
+| side_balance | [uint64](#uint64) | | The balance in satoshis on this side of the channel |
+| currency | [string](#string) | | The currency of the channel this alert is for. |
+
+
+
+
+
+
### BanRequest
@@ -1220,6 +1263,16 @@ A map of ticker symbols to lnd uris for this peer
+
+
+### SubscribeAlertsRequest
+
+
+
+
+
+
+
### SubscribeOrdersRequest
@@ -1542,6 +1595,29 @@ A map of ticker symbols to lnd uris for this peer
+
+
+### Alert.AlertType
+The type of the alert.
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| LOW_TRADING_BALANCE | 0 | |
+
+
+
+
+
+### BalanceAlert.Side
+The side of the low balance.
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| REMOTE | 0 | |
+| LOCAL | 1 | |
+
+
+
### Currency.SwapClient
@@ -1648,6 +1724,7 @@ The primary service for interacting with a running xud node.
| RemovePair | [RemovePairRequest](#xudrpc.RemovePairRequest) | [RemovePairResponse](#xudrpc.RemovePairResponse) | Removes a trading pair from the list of currently supported trading pair. This call will effectively cancel any standing orders for that trading pair. Peers are informed when a pair is no longer supported so that they will know to stop sending orders for it. shell: xucli removepair <pair_id> |
| SetLogLevel | [SetLogLevelRequest](#xudrpc.SetLogLevelRequest) | [SetLogLevelResponse](#xudrpc.SetLogLevelResponse) | Set the logging level. shell: xucli loglevel <level> |
| Shutdown | [ShutdownRequest](#xudrpc.ShutdownRequest) | [ShutdownResponse](#xudrpc.ShutdownResponse) | Begin gracefully shutting down xud. shell: xucli shutdown |
+| SubscribeAlerts | [SubscribeAlertsRequest](#xudrpc.SubscribeAlertsRequest) | [Alert](#xudrpc.Alert) stream | Subscribes to alerts such as low balance. |
| SubscribeOrders | [SubscribeOrdersRequest](#xudrpc.SubscribeOrdersRequest) | [OrderUpdate](#xudrpc.OrderUpdate) stream | Subscribes to orders being added to and removed from the order book. This call allows the client to maintain an up-to-date view of the order book. For example, an exchange that wants to show its users a real time view of the orders available to them would subscribe to this streaming call to be alerted as new orders are added and expired orders are removed. |
| SubscribeSwapFailures | [SubscribeSwapsRequest](#xudrpc.SubscribeSwapsRequest) | [SwapFailure](#xudrpc.SwapFailure) stream | Subscribes to failed swaps. By default, only swaps that are initiated by a remote peer are transmitted unless a flag is set to include swaps initiated by the local node. This call allows the client to get real-time notifications when swap attempts are failing. It can be used for status monitoring, debugging, and testing purposes. |
| SubscribeSwaps | [SubscribeSwapsRequest](#xudrpc.SubscribeSwapsRequest) | [SwapSuccess](#xudrpc.SwapSuccess) stream | Subscribes to completed swaps. By default, only swaps that are initiated by a remote peer are transmitted unless a flag is set to include swaps initiated by the local node. This call allows the client to get real-time notifications when its orders are filled by a peer. It can be used for tracking order executions, updating balances, and informing a trader when one of their orders is settled through the Exchange Union network. |
diff --git a/lib/Logger.ts b/lib/Logger.ts
index 510ce856a..bbc74a4a8 100644
--- a/lib/Logger.ts
+++ b/lib/Logger.ts
@@ -44,6 +44,7 @@ export enum Context {
Http = 'HTTP',
Backup = 'BACKUP',
Service = 'SERVICE',
+ Alerts = 'ALERTS',
}
type Loggers = {
@@ -57,6 +58,7 @@ type Loggers = {
swaps: Logger;
http: Logger;
service: Logger;
+ alerts: Logger;
};
class Logger {
@@ -134,6 +136,7 @@ class Logger {
swaps: new Logger({ ...object, context: Context.Swaps }),
http: new Logger({ ...object, context: Context.Http }),
service: new Logger({ ...object, context: Context.Service }),
+ alerts: new Logger({ ...object, context: Context.Alerts }),
};
};
diff --git a/lib/Xud.ts b/lib/Xud.ts
index 35a3d58b8..ce88ceb13 100644
--- a/lib/Xud.ts
+++ b/lib/Xud.ts
@@ -19,6 +19,7 @@ import SwapClientManager from './swaps/SwapClientManager';
import Swaps from './swaps/Swaps';
import { createSimnetChannels } from './utils/simnet-connext-channels';
import { UnitConverter } from './utils/UnitConverter';
+import Alerts from './alerts/Alerts';
const { version }: { version: string } = require('../package.json');
@@ -43,6 +44,7 @@ class Xud extends EventEmitter {
private shuttingDown = false;
private swapClientManager?: SwapClientManager;
private simnetChannels$?: Subscription;
+ private alerts!: Alerts;
/**
* Create an Exchange Union daemon.
@@ -198,6 +200,8 @@ class Xud extends EventEmitter {
// initialize pool and start listening/connecting only once other components are initialized
await this.pool.init();
+ this.alerts = new Alerts({ swapClientManager: this.swapClientManager, logger: loggers.alerts });
+
this.service = new Service({
version,
nodeKey,
@@ -207,6 +211,7 @@ class Xud extends EventEmitter {
swaps: this.swaps,
logger: loggers.service,
shutdown: this.beginShutdown,
+ alerts: this.alerts,
});
this.service.on('logLevel', (level) => {
diff --git a/lib/alerts/Alerts.ts b/lib/alerts/Alerts.ts
new file mode 100644
index 000000000..9ade5b5cb
--- /dev/null
+++ b/lib/alerts/Alerts.ts
@@ -0,0 +1,70 @@
+import { EventEmitter } from 'events';
+import { satsToCoinsStr } from '../cli/utils';
+import { AlertType, ChannelSide } from '../constants/enums';
+import Logger from '../Logger';
+import SwapClientManager from '../swaps/SwapClientManager';
+import { Alert, BalanceAlertEvent } from './types';
+
+interface Alerts {
+ on(event: 'alert', listener: (alert: Alert) => void): this;
+ emit(event: 'alert', alert: Alert): boolean;
+}
+
+// TODO this class still requires a cleanup if alert is not being thrown anymore after a while
+/**
+ * This class works as a middleware for thrown alerts from xud's main flow. Each alert will be caught here
+ * and re-thrown if last thrown time was before the minimum threshold that set in consts.ts
+ */
+class Alerts extends EventEmitter {
+ /** The minimum time in miliseconds to be passed to rethrow a balance alert. */
+ private static readonly MIN_BALANCE_ALERT_THRESHOLD_IN_MS = 10000;
+ private alerts = new Map();
+ private logger: Logger;
+
+ constructor({ swapClientManager, logger }: { swapClientManager: SwapClientManager; logger: Logger }) {
+ super();
+ this.logger = logger;
+ this.listenLowTradingBalanceAlerts(swapClientManager);
+ }
+
+ private listenLowTradingBalanceAlerts(swapClientManager: SwapClientManager) {
+ const lndClients = swapClientManager.getLndClientsMap().values();
+ for (const lndClient of lndClients) {
+ lndClient.on('lowTradingBalance', this.onLowTradingBalance);
+ }
+ swapClientManager.connextClient?.on('lowTradingBalance', this.onLowTradingBalance);
+ }
+
+ private onLowTradingBalance = (balanceAlertEvent: BalanceAlertEvent) => {
+ // TODO don't use JSON.stringify instead find a way to define unique ids per alert and keep in the map to avoid memory issues
+ const stringRepresentation = JSON.stringify(balanceAlertEvent);
+ this.logger.trace(`received low trading balance alert ${stringRepresentation}`);
+ if (this.alerts.get(stringRepresentation) === undefined || this.checkAlertThreshold(stringRepresentation)) {
+ this.logger.trace(`triggering low balance alert ${stringRepresentation}`);
+
+ const message = `${ChannelSide[balanceAlertEvent.side || 0]} trading balance (${satsToCoinsStr(
+ balanceAlertEvent.sideBalance || 0,
+ )} ${balanceAlertEvent.currency}) is lower than 10% of trading capacity (${satsToCoinsStr(
+ balanceAlertEvent.totalBalance || 0,
+ )} ${balanceAlertEvent.currency})`;
+
+ const balanceAlert = {
+ ...balanceAlertEvent,
+ message,
+ type: AlertType.LowTradingBalance,
+ date: Date.now(),
+ };
+
+ this.alerts.set(stringRepresentation, balanceAlert.date);
+ this.emit('alert', balanceAlert);
+ }
+ };
+
+ private checkAlertThreshold(stringRepresentation: string) {
+ const lastThrownTime = this.alerts.get(stringRepresentation) || 0;
+ const passedTime = Date.now() - lastThrownTime;
+ return passedTime > Alerts.MIN_BALANCE_ALERT_THRESHOLD_IN_MS;
+ }
+}
+
+export default Alerts;
diff --git a/lib/alerts/types.ts b/lib/alerts/types.ts
new file mode 100644
index 000000000..fadbc9a80
--- /dev/null
+++ b/lib/alerts/types.ts
@@ -0,0 +1,23 @@
+import { AlertType, ChannelSide } from '../constants/enums';
+
+type BaseAlert = {
+ type: AlertType;
+ message: string;
+ date: number;
+};
+
+export type BalanceAlertEvent = {
+ /** The total balance of the channel when the alert is triggered. */
+ totalBalance: number;
+ /** The side of the balance either local or remote. */
+ side: ChannelSide;
+ /** The balance that triggered the alert. */
+ sideBalance: number;
+ /** The alert threshold in percentage, e.g. 10 means %10. */
+ bound: number;
+ /** The currency of the channel. */
+ currency: string;
+};
+export type BalanceAlert = BaseAlert & BalanceAlertEvent;
+
+export type Alert = BalanceAlert;
diff --git a/lib/cli/commands/streamalerts.ts b/lib/cli/commands/streamalerts.ts
new file mode 100644
index 000000000..17011224c
--- /dev/null
+++ b/lib/cli/commands/streamalerts.ts
@@ -0,0 +1,84 @@
+import { Arguments, Argv } from 'yargs';
+import moment from 'moment';
+import { XudClient } from '../../proto/xudrpc_grpc_pb';
+import * as xudrpc from '../../proto/xudrpc_pb';
+import { loadXudClient } from '../command';
+import { AlertType, ChannelSide } from '../../constants/enums';
+import { onStreamError, waitForClient } from '../utils';
+
+export const command = 'streamalerts';
+
+export const describe = 'stream alert notifications from xud';
+
+export const builder = (argv: Argv) =>
+ argv
+ .option('pretty', { type: 'boolean' })
+ .example('$0 streamalerts -j', 'prints alert payload in a JSON structure')
+ .example('$0 streamalerts', 'prints alert message only');
+
+export const handler = async (argv: Arguments) => {
+ await ensureConnection(argv, true);
+};
+
+let client: XudClient;
+
+const ensureConnection = async (argv: Arguments, printError?: boolean) => {
+ if (!client) {
+ client = await loadXudClient(argv);
+ }
+
+ waitForClient(client, argv, ensureConnection, streamalerts, printError);
+};
+
+const structAlertJson = (alertObject: xudrpc.Alert.AsObject) => {
+ const result: {
+ type: string;
+ date: number;
+ payload:
+ | {
+ totalBalance?: number;
+ side?: string;
+ bound?: number;
+ sideBalance?: number;
+ channelPoint?: string;
+ currency?: string;
+ }
+ | undefined;
+ } = {
+ type: AlertType[alertObject.type],
+ date: alertObject.date,
+ payload: undefined,
+ };
+
+ if (alertObject.type === xudrpc.Alert.AlertType.LOW_TRADING_BALANCE) {
+ result.payload = {
+ totalBalance: alertObject.balanceAlert?.totalBalance,
+ side: ChannelSide[alertObject.balanceAlert?.side || 0],
+ sideBalance: alertObject.balanceAlert?.sideBalance,
+ bound: alertObject.balanceAlert?.bound,
+ currency: alertObject.balanceAlert?.currency,
+ };
+ }
+
+ return result;
+};
+
+const streamalerts = (argv: Arguments) => {
+ const request = new xudrpc.SubscribeAlertsRequest();
+ const alertsSubscription = client.subscribeAlerts(request);
+
+ alertsSubscription.on('data', (alert: xudrpc.Alert) => {
+ if (argv.json) {
+ console.log(JSON.stringify(structAlertJson(alert.toObject()), undefined, 2));
+ } else {
+ console.log(`(${moment(alert.getDate())}) ${AlertType[alert.getType()]}: ${alert.getMessage()}`);
+ }
+ });
+ alertsSubscription.on('end', reconnect.bind(undefined, argv));
+ alertsSubscription.on('error', onStreamError.bind(undefined, ensureConnection.bind(undefined, argv)));
+};
+
+const reconnect = async (argv: Arguments) => {
+ console.log('Stream has closed, trying to reconnect');
+ await ensureConnection(argv, false);
+};
diff --git a/lib/cli/commands/streamorders.ts b/lib/cli/commands/streamorders.ts
index 67dc829f7..71851949b 100644
--- a/lib/cli/commands/streamorders.ts
+++ b/lib/cli/commands/streamorders.ts
@@ -1,9 +1,8 @@
-import { ServiceError, status } from '@grpc/grpc-js';
-import { Arguments, Argv } from 'yargs';
import { XudClient } from 'lib/proto/xudrpc_grpc_pb';
+import { Arguments, Argv } from 'yargs';
import * as xudrpc from '../../proto/xudrpc_pb';
-import { setTimeoutPromise } from '../../utils/utils';
import { loadXudClient } from '../command';
+import { onStreamError, waitForClient } from '../utils';
export const command = 'streamorders [existing]';
@@ -26,20 +25,8 @@ const ensureConnection = async (argv: Arguments, printError?: boolean) => {
if (!client) {
client = await loadXudClient(argv);
}
- client.waitForReady(Date.now() + 3000, (error?: Error) => {
- if (error) {
- if (error.message === 'Failed to connect before the deadline') {
- console.error(`could not connect to xud at ${argv.rpchost}:${argv.rpcport}, is xud running?`);
- process.exit(1);
- }
- if (printError) console.error(`${error.name}: ${error.message}`);
- setTimeout(ensureConnection.bind(undefined, argv, printError), 3000);
- } else {
- console.log('Successfully connected, subscribing for orders');
- streamOrders(argv);
- }
- });
+ waitForClient(client, argv, ensureConnection, streamOrders, printError);
};
const streamOrders = (argv: Arguments) => {
@@ -57,15 +44,7 @@ const streamOrders = (argv: Arguments) => {
// adding end, close, error events only once,
// since they'll be thrown for three of subscriptions in the corresponding cases, catching once is enough.
ordersSubscription.on('end', reconnect.bind(undefined, argv));
- ordersSubscription.on('error', async (err: ServiceError) => {
- if (err.code === status.UNIMPLEMENTED) {
- console.error("xud is locked, run 'xucli unlock', 'xucli create', or 'xucli restore' then try again");
- process.exit(1);
- }
- console.warn(`Unexpected error occured: ${err.message}, reconnecting in 1 second`);
- await setTimeoutPromise(1000);
- await ensureConnection(argv);
- });
+ ordersSubscription.on('error', onStreamError.bind(undefined, ensureConnection.bind(undefined, argv)));
const swapsRequest = new xudrpc.SubscribeSwapsRequest();
swapsRequest.setIncludeTaker(true);
diff --git a/lib/cli/utils.ts b/lib/cli/utils.ts
index 12771b99b..01d76a90e 100644
--- a/lib/cli/utils.ts
+++ b/lib/cli/utils.ts
@@ -1,7 +1,11 @@
+import { ServiceError, status } from '@grpc/grpc-js';
import colors from 'colors/safe';
import { accessSync, watch } from 'fs';
import os from 'os';
import path from 'path';
+import { Arguments } from 'yargs';
+import { XudClient } from '../proto/xudrpc_grpc_pb';
+import { setTimeoutPromise } from '../utils/utils';
const SATOSHIS_PER_COIN = 10 ** 8;
@@ -100,3 +104,36 @@ be recovered with it and must be backed up and recovered separately. Keep it \
somewhere safe, it is your ONLY backup in case of data loss.
`);
}
+
+export const waitForClient = (
+ client: XudClient,
+ argv: Arguments,
+ ensureConnection: Function,
+ successCallback: Function,
+ printError?: boolean,
+) => {
+ client.waitForReady(Date.now() + 3000, (error?: Error) => {
+ if (error) {
+ if (error.message === 'Failed to connect before the deadline') {
+ console.error(`could not connect to xud at ${argv.rpchost}:${argv.rpcport}, is xud running?`);
+ process.exit(1);
+ }
+
+ if (printError) console.error(`${error.name}: ${error.message}`);
+ setTimeout(ensureConnection, 3000);
+ } else {
+ console.log('Successfully connected, streaming');
+ successCallback(argv);
+ }
+ });
+};
+
+export const onStreamError = async (ensureConnection: Function, err: ServiceError) => {
+ if (err.code === status.UNIMPLEMENTED) {
+ console.error("xud is locked, run 'xucli unlock', 'xucli create', or 'xucli restore' then try again");
+ process.exit(1);
+ }
+ console.warn(`Unexpected error occured: ${err.message}, reconnecting in 1 second`);
+ await setTimeoutPromise(1000);
+ await ensureConnection();
+};
diff --git a/lib/connextclient/ConnextClient.ts b/lib/connextclient/ConnextClient.ts
index 430cde48e..3e9213aca 100644
--- a/lib/connextclient/ConnextClient.ts
+++ b/lib/connextclient/ConnextClient.ts
@@ -3,6 +3,7 @@ import assert from 'assert';
import http from 'http';
import { combineLatest, defer, from, fromEvent, interval, Observable, of, Subscription, throwError, timer } from 'rxjs';
import { catchError, distinctUntilChanged, filter, mergeMap, mergeMapTo, pluck, take, timeout } from 'rxjs/operators';
+import { BalanceAlertEvent } from '../alerts/types';
import { SwapClientType, SwapRole, SwapState } from '../constants/enums';
import { CurrencyInstance } from '../db/types';
import Logger from '../Logger';
@@ -49,6 +50,7 @@ interface ConnextClient {
on(event: 'htlcAccepted', listener: (rHash: string, units: bigint, currency: string) => void): this;
on(event: 'connectionVerified', listener: (swapClientInfo: SwapClientInfo) => void): this;
on(event: 'depositConfirmed', listener: (hash: string) => void): this;
+ on(event: 'lowTradingBalance', listener: (alert: BalanceAlertEvent) => void): this;
once(event: 'initialized', listener: () => void): this;
emit(event: 'htlcAccepted', rHash: string, units: bigint, currency: string): boolean;
emit(event: 'connectionVerified', swapClientInfo: SwapClientInfo): boolean;
@@ -56,6 +58,7 @@ interface ConnextClient {
emit(event: 'preimage', preimageRequest: ProvidePreimageEvent): void;
emit(event: 'transferReceived', transferReceivedRequest: TransferReceivedEvent): void;
emit(event: 'depositConfirmed', hash: string): void;
+ emit(event: 'lowTradingBalance', alert: BalanceAlertEvent): boolean;
}
const getRouterNodeIdentifier = (network: string): string => {
@@ -334,6 +337,15 @@ class ConnextClient extends SwapClient {
channelBalancePromises.push(this.channelBalance(currency));
}
await Promise.all(channelBalancePromises);
+
+ for (const [currency] of this.tokenAddresses) {
+ const remoteBalance = this.inboundAmounts.get(currency) || 0;
+ const localBalance = this.outboundAmounts.get(currency) || 0;
+ const totalBalance = remoteBalance + localBalance;
+ const alertThreshold = totalBalance * 0.1;
+
+ this.checkLowBalance(remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+ }
} catch (e) {
this.logger.error('failed to update total outbound capacity', e);
}
diff --git a/lib/constants/enums.ts b/lib/constants/enums.ts
index e86a12080..1d74a1bfa 100644
--- a/lib/constants/enums.ts
+++ b/lib/constants/enums.ts
@@ -180,3 +180,12 @@ export enum DisconnectionReason {
AuthFailureInvalidSignature = 12,
WireProtocolErr = 13,
}
+
+export enum AlertType {
+ LowTradingBalance = 0,
+}
+
+export enum ChannelSide {
+ Remote,
+ Local,
+}
diff --git a/lib/grpc/GrpcService.ts b/lib/grpc/GrpcService.ts
index 24d4539e1..0ffd32269 100644
--- a/lib/grpc/GrpcService.ts
+++ b/lib/grpc/GrpcService.ts
@@ -2,7 +2,7 @@
import grpc, { ServerWritableStream, status } from '@grpc/grpc-js';
import { fromEvent } from 'rxjs';
import { take } from 'rxjs/operators';
-import { SwapFailureReason } from '../constants/enums';
+import { AlertType, SwapFailureReason } from '../constants/enums';
import { LndInfo } from '../lndclient/types';
import { isOwnOrder, Order, OrderPortion, PlaceOrderEventType, PlaceOrderResult } from '../orderbook/types';
import * as xudrpc from '../proto/xudrpc_pb';
@@ -10,6 +10,7 @@ import Service from '../service/Service';
import { ServiceOrder, ServicePlaceOrderEvent } from '../service/types';
import { SwapAccepted, SwapFailure, SwapSuccess } from '../swaps/types';
import getGrpcError from './getGrpcError';
+import { Alert } from '../alerts/types';
/**
* Creates an xudrpc Order message from an [[Order]].
@@ -995,6 +996,35 @@ class GrpcService implements grpc.UntypedServiceImplementation {
}
};
+ /*
+ * See [[Service.subscribeAlerts]]
+ */
+ public subscribeAlerts: grpc.handleServerStreamingCall = (call) => {
+ if (!this.isReady(this.service, call)) {
+ return;
+ }
+
+ const cancelled$ = getCancelled$(call);
+ this.service.subscribeAlerts((serviceAlert: Alert) => {
+ const alert = new xudrpc.Alert();
+ alert.setType(serviceAlert.type as number);
+ alert.setMessage(serviceAlert.message);
+ alert.setDate(serviceAlert.date);
+ if (serviceAlert.type === AlertType.LowTradingBalance) {
+ const balanceServiceAlert = serviceAlert as Alert;
+ const balanceAlert = new xudrpc.BalanceAlert();
+ balanceAlert.setBound(balanceServiceAlert.bound);
+ balanceAlert.setSide(balanceServiceAlert.side as number);
+ balanceAlert.setSideBalance(balanceServiceAlert.sideBalance);
+ balanceAlert.setTotalBalance(balanceServiceAlert.totalBalance);
+ balanceAlert.setCurrency(balanceServiceAlert.currency);
+ alert.setBalanceAlert(balanceAlert);
+ }
+ call.write(alert);
+ }, cancelled$);
+ this.addStream(call);
+ };
+
/*
* See [[Service.subscribeOrders]]
*/
diff --git a/lib/lndclient/LndClient.ts b/lib/lndclient/LndClient.ts
index 4b7ec7fcd..ea60979f3 100644
--- a/lib/lndclient/LndClient.ts
+++ b/lib/lndclient/LndClient.ts
@@ -3,17 +3,18 @@ import { ServiceClient } from '@grpc/grpc-js/build/src/make-client';
import assert from 'assert';
import crypto from 'crypto';
import { promises as fs, watch } from 'fs';
+import { BalanceAlertEvent } from 'lib/alerts/types';
import path from 'path';
import { SwapClientType, SwapRole, SwapState } from '../constants/enums';
import Logger from '../Logger';
import * as lndinvoicesGrpc from '../proto/lndinvoices_grpc_pb';
import * as lndinvoices from '../proto/lndinvoices_pb';
-import * as lndwalletGrpc from '../proto/lndwalletunlocker_grpc_pb';
-import * as lndwallet from '../proto/lndwalletunlocker_pb';
import * as lndrouterGrpc from '../proto/lndrouter_grpc_pb';
import * as lndrouter from '../proto/lndrouter_pb';
import * as lndGrpc from '../proto/lndrpc_grpc_pb';
import * as lndrpc from '../proto/lndrpc_pb';
+import * as lndwalletGrpc from '../proto/lndwalletunlocker_grpc_pb';
+import * as lndwallet from '../proto/lndwalletunlocker_pb';
import { BASE_MAX_CLIENT_WAIT_TIME, MAX_FEE_RATIO, MAX_PAYMENT_TIME } from '../swaps/consts';
import swapErrors from '../swaps/errors';
import SwapClient, {
@@ -44,6 +45,7 @@ interface LndClient {
on(event: 'channelBackup', listener: (channelBackup: Uint8Array) => void): this;
on(event: 'channelBackupEnd', listener: () => void): this;
on(event: 'locked', listener: () => void): this;
+ on(event: 'lowTradingBalance', listener: (alert: BalanceAlertEvent) => void): this;
once(event: 'initialized', listener: () => void): this;
@@ -53,6 +55,7 @@ interface LndClient {
emit(event: 'channelBackupEnd'): boolean;
emit(event: 'locked'): boolean;
emit(event: 'initialized'): boolean;
+ emit(event: 'lowTradingBalance', alert: BalanceAlertEvent): boolean;
}
const GRPC_CLIENT_OPTIONS = {
@@ -254,9 +257,21 @@ class LndClient extends SwapClient {
};
protected updateCapacity = async () => {
- await this.channelBalance().catch(async (err) => {
- this.logger.error('failed to update total outbound capacity', err);
- });
+ await this.channelBalance()
+ .then(() => {
+ const totalBalance = this.totalOutboundAmount + this.totalInboundAmount;
+ const alertThreshold = totalBalance * 0.1;
+ this.checkLowBalance(
+ this.totalInboundAmount,
+ this.totalOutboundAmount,
+ totalBalance,
+ alertThreshold,
+ this.currency,
+ );
+ })
+ .catch(async (err) => {
+ this.logger.error('failed to update total outbound capacity', err);
+ });
};
private unaryCall = (
diff --git a/lib/proto/xudrpc.swagger.json b/lib/proto/xudrpc.swagger.json
index 5f9499358..44a58a92b 100644
--- a/lib/proto/xudrpc.swagger.json
+++ b/lib/proto/xudrpc.swagger.json
@@ -663,6 +663,23 @@
]
}
},
+ "/v1/subscribealerts": {
+ "get": {
+ "summary": "Subscribes to alerts such as low balance.",
+ "operationId": "SubscribeAlerts",
+ "responses": {
+ "200": {
+ "description": "A successful response.(streaming responses)",
+ "schema": {
+ "$ref": "#/x-stream-definitions/xudrpcAlert"
+ }
+ }
+ },
+ "tags": [
+ "Xud"
+ ]
+ }
+ },
"/v1/subscribeorders": {
"get": {
"summary": "Subscribes to orders being added to and removed from the order book. This call allows the client\nto maintain an up-to-date view of the order book. For example, an exchange that wants to show\nits users a real time view of the orders available to them would subscribe to this streaming\ncall to be alerted as new orders are added and expired orders are removed.",
@@ -897,6 +914,23 @@
}
},
"definitions": {
+ "AlertAlertType": {
+ "type": "string",
+ "enum": [
+ "LOW_TRADING_BALANCE"
+ ],
+ "default": "LOW_TRADING_BALANCE",
+ "description": "The type of the alert."
+ },
+ "BalanceAlertSide": {
+ "type": "string",
+ "enum": [
+ "REMOTE",
+ "LOCAL"
+ ],
+ "default": "REMOTE",
+ "description": "The side of the low balance."
+ },
"CurrencySwapClient": {
"type": "string",
"enum": [
@@ -985,6 +1019,26 @@
"xudrpcAddPairResponse": {
"type": "object"
},
+ "xudrpcAlert": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "$ref": "#/definitions/AlertAlertType"
+ },
+ "message": {
+ "type": "string",
+ "description": "The human readable alert message."
+ },
+ "date": {
+ "type": "string",
+ "format": "int64",
+ "description": "The human readable alert message."
+ },
+ "balance_alert": {
+ "$ref": "#/definitions/xudrpcBalanceAlert"
+ }
+ }
+ },
"xudrpcBalance": {
"type": "object",
"properties": {
@@ -1020,6 +1074,38 @@
}
}
},
+ "xudrpcBalanceAlert": {
+ "type": "object",
+ "properties": {
+ "total_balance": {
+ "type": "string",
+ "format": "uint64",
+ "description": "The total balance."
+ },
+ "side": {
+ "$ref": "#/definitions/BalanceAlertSide"
+ },
+ "bound": {
+ "type": "integer",
+ "format": "int64",
+ "description": "The bound of the low balance in percentage."
+ },
+ "percent": {
+ "type": "integer",
+ "format": "int64",
+ "description": "The percent of the total trading balance."
+ },
+ "side_balance": {
+ "type": "string",
+ "format": "uint64",
+ "title": "The balance in satoshis on this side of the channel"
+ },
+ "currency": {
+ "type": "string",
+ "description": "The currency of the channel this alert is for."
+ }
+ }
+ },
"xudrpcBanRequest": {
"type": "object",
"properties": {
@@ -2152,6 +2238,18 @@
}
},
"x-stream-definitions": {
+ "xudrpcAlert": {
+ "type": "object",
+ "properties": {
+ "result": {
+ "$ref": "#/definitions/xudrpcAlert"
+ },
+ "error": {
+ "$ref": "#/definitions/runtimeStreamError"
+ }
+ },
+ "title": "Stream result of xudrpcAlert"
+ },
"xudrpcOrderUpdate": {
"type": "object",
"properties": {
diff --git a/lib/proto/xudrpc_grpc_pb.d.ts b/lib/proto/xudrpc_grpc_pb.d.ts
index 9cd8f5d17..f5f2d189d 100644
--- a/lib/proto/xudrpc_grpc_pb.d.ts
+++ b/lib/proto/xudrpc_grpc_pb.d.ts
@@ -104,6 +104,7 @@ interface IXudService extends grpc.ServiceDefinition;
responseDeserialize: grpc.deserialize;
}
+interface IXudService_ISubscribeAlerts extends grpc.MethodDefinition {
+ path: "/xudrpc.Xud/SubscribeAlerts";
+ requestStream: false;
+ responseStream: true;
+ requestSerialize: grpc.serialize;
+ requestDeserialize: grpc.deserialize;
+ responseSerialize: grpc.serialize;
+ responseDeserialize: grpc.deserialize;
+}
interface IXudService_ISubscribeOrders extends grpc.MethodDefinition {
path: "/xudrpc.Xud/SubscribeOrders";
requestStream: false;
@@ -460,6 +470,7 @@ export interface IXudServer extends grpc.UntypedServiceImplementation {
removePair: grpc.handleUnaryCall;
setLogLevel: grpc.handleUnaryCall;
shutdown: grpc.handleUnaryCall;
+ subscribeAlerts: grpc.handleServerStreamingCall;
subscribeOrders: grpc.handleServerStreamingCall;
subscribeSwapFailures: grpc.handleServerStreamingCall;
subscribeSwaps: grpc.handleServerStreamingCall;
@@ -551,6 +562,8 @@ export interface IXudClient {
shutdown(request: xudrpc_pb.ShutdownRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ShutdownResponse) => void): grpc.ClientUnaryCall;
shutdown(request: xudrpc_pb.ShutdownRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ShutdownResponse) => void): grpc.ClientUnaryCall;
shutdown(request: xudrpc_pb.ShutdownRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ShutdownResponse) => void): grpc.ClientUnaryCall;
+ subscribeAlerts(request: xudrpc_pb.SubscribeAlertsRequest, options?: Partial): grpc.ClientReadableStream;
+ subscribeAlerts(request: xudrpc_pb.SubscribeAlertsRequest, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream;
subscribeOrders(request: xudrpc_pb.SubscribeOrdersRequest, options?: Partial): grpc.ClientReadableStream;
subscribeOrders(request: xudrpc_pb.SubscribeOrdersRequest, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream;
subscribeSwapFailures(request: xudrpc_pb.SubscribeSwapsRequest, options?: Partial): grpc.ClientReadableStream;
@@ -655,6 +668,8 @@ export class XudClient extends grpc.Client implements IXudClient {
public shutdown(request: xudrpc_pb.ShutdownRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ShutdownResponse) => void): grpc.ClientUnaryCall;
public shutdown(request: xudrpc_pb.ShutdownRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ShutdownResponse) => void): grpc.ClientUnaryCall;
public shutdown(request: xudrpc_pb.ShutdownRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ShutdownResponse) => void): grpc.ClientUnaryCall;
+ public subscribeAlerts(request: xudrpc_pb.SubscribeAlertsRequest, options?: Partial): grpc.ClientReadableStream;
+ public subscribeAlerts(request: xudrpc_pb.SubscribeAlertsRequest, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream;
public subscribeOrders(request: xudrpc_pb.SubscribeOrdersRequest, options?: Partial): grpc.ClientReadableStream;
public subscribeOrders(request: xudrpc_pb.SubscribeOrdersRequest, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream;
public subscribeSwapFailures(request: xudrpc_pb.SubscribeSwapsRequest, options?: Partial): grpc.ClientReadableStream;
diff --git a/lib/proto/xudrpc_grpc_pb.js b/lib/proto/xudrpc_grpc_pb.js
index f945a9444..2ef6bc0f3 100644
--- a/lib/proto/xudrpc_grpc_pb.js
+++ b/lib/proto/xudrpc_grpc_pb.js
@@ -58,6 +58,17 @@ function deserialize_xudrpc_AddPairResponse(buffer_arg) {
return xudrpc_pb.AddPairResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
+function serialize_xudrpc_Alert(arg) {
+ if (!(arg instanceof xudrpc_pb.Alert)) {
+ throw new Error('Expected argument of type xudrpc.Alert');
+ }
+ return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_xudrpc_Alert(buffer_arg) {
+ return xudrpc_pb.Alert.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
function serialize_xudrpc_BanRequest(arg) {
if (!(arg instanceof xudrpc_pb.BanRequest)) {
throw new Error('Expected argument of type xudrpc.BanRequest');
@@ -630,6 +641,17 @@ function deserialize_xudrpc_ShutdownResponse(buffer_arg) {
return xudrpc_pb.ShutdownResponse.deserializeBinary(new Uint8Array(buffer_arg));
}
+function serialize_xudrpc_SubscribeAlertsRequest(arg) {
+ if (!(arg instanceof xudrpc_pb.SubscribeAlertsRequest)) {
+ throw new Error('Expected argument of type xudrpc.SubscribeAlertsRequest');
+ }
+ return Buffer.from(arg.serializeBinary());
+}
+
+function deserialize_xudrpc_SubscribeAlertsRequest(buffer_arg) {
+ return xudrpc_pb.SubscribeAlertsRequest.deserializeBinary(new Uint8Array(buffer_arg));
+}
+
function serialize_xudrpc_SubscribeOrdersRequest(arg) {
if (!(arg instanceof xudrpc_pb.SubscribeOrdersRequest)) {
throw new Error('Expected argument of type xudrpc.SubscribeOrdersRequest');
@@ -1223,6 +1245,18 @@ shutdown: {
responseSerialize: serialize_xudrpc_ShutdownResponse,
responseDeserialize: deserialize_xudrpc_ShutdownResponse,
},
+ // Subscribes to alerts such as low balance.
+subscribeAlerts: {
+ path: '/xudrpc.Xud/SubscribeAlerts',
+ requestStream: false,
+ responseStream: true,
+ requestType: xudrpc_pb.SubscribeAlertsRequest,
+ responseType: xudrpc_pb.Alert,
+ requestSerialize: serialize_xudrpc_SubscribeAlertsRequest,
+ requestDeserialize: deserialize_xudrpc_SubscribeAlertsRequest,
+ responseSerialize: serialize_xudrpc_Alert,
+ responseDeserialize: deserialize_xudrpc_Alert,
+ },
// Subscribes to orders being added to and removed from the order book. This call allows the client
// to maintain an up-to-date view of the order book. For example, an exchange that wants to show
// its users a real time view of the orders available to them would subscribe to this streaming
diff --git a/lib/proto/xudrpc_pb.d.ts b/lib/proto/xudrpc_pb.d.ts
index 4312f7955..6892c270e 100644
--- a/lib/proto/xudrpc_pb.d.ts
+++ b/lib/proto/xudrpc_pb.d.ts
@@ -66,6 +66,57 @@ export namespace AddPairResponse {
}
}
+export class Alert extends jspb.Message {
+ getType(): Alert.AlertType;
+ setType(value: Alert.AlertType): Alert;
+
+ getMessage(): string;
+ setMessage(value: string): Alert;
+
+ getDate(): number;
+ setDate(value: number): Alert;
+
+
+ hasBalanceAlert(): boolean;
+ clearBalanceAlert(): void;
+ getBalanceAlert(): BalanceAlert | undefined;
+ setBalanceAlert(value?: BalanceAlert): Alert;
+
+
+ getPayloadCase(): Alert.PayloadCase;
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): Alert.AsObject;
+ static toObject(includeInstance: boolean, msg: Alert): Alert.AsObject;
+ static extensions: {[key: number]: jspb.ExtensionFieldInfo};
+ static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo};
+ static serializeBinaryToWriter(message: Alert, writer: jspb.BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): Alert;
+ static deserializeBinaryFromReader(message: Alert, reader: jspb.BinaryReader): Alert;
+}
+
+export namespace Alert {
+ export type AsObject = {
+ type: Alert.AlertType,
+ message: string,
+ date: number,
+ balanceAlert?: BalanceAlert.AsObject,
+ }
+
+ export enum AlertType {
+ LOW_TRADING_BALANCE = 0,
+ }
+
+
+ export enum PayloadCase {
+ PAYLOAD_NOT_SET = 0,
+
+ BALANCE_ALERT = 4,
+
+ }
+
+}
+
export class Balance extends jspb.Message {
getTotalBalance(): number;
setTotalBalance(value: number): Balance;
@@ -107,6 +158,53 @@ export namespace Balance {
}
}
+export class BalanceAlert extends jspb.Message {
+ getTotalBalance(): number;
+ setTotalBalance(value: number): BalanceAlert;
+
+ getSide(): BalanceAlert.Side;
+ setSide(value: BalanceAlert.Side): BalanceAlert;
+
+ getBound(): number;
+ setBound(value: number): BalanceAlert;
+
+ getPercent(): number;
+ setPercent(value: number): BalanceAlert;
+
+ getSideBalance(): number;
+ setSideBalance(value: number): BalanceAlert;
+
+ getCurrency(): string;
+ setCurrency(value: string): BalanceAlert;
+
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): BalanceAlert.AsObject;
+ static toObject(includeInstance: boolean, msg: BalanceAlert): BalanceAlert.AsObject;
+ static extensions: {[key: number]: jspb.ExtensionFieldInfo};
+ static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo};
+ static serializeBinaryToWriter(message: BalanceAlert, writer: jspb.BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): BalanceAlert;
+ static deserializeBinaryFromReader(message: BalanceAlert, reader: jspb.BinaryReader): BalanceAlert;
+}
+
+export namespace BalanceAlert {
+ export type AsObject = {
+ totalBalance: number,
+ side: BalanceAlert.Side,
+ bound: number,
+ percent: number,
+ sideBalance: number,
+ currency: string,
+ }
+
+ export enum Side {
+ REMOTE = 0,
+ LOCAL = 1,
+ }
+
+}
+
export class BanRequest extends jspb.Message {
getNodeIdentifier(): string;
setNodeIdentifier(value: string): BanRequest;
@@ -1901,6 +1999,23 @@ export namespace SubscribeOrdersRequest {
}
}
+export class SubscribeAlertsRequest extends jspb.Message {
+
+ serializeBinary(): Uint8Array;
+ toObject(includeInstance?: boolean): SubscribeAlertsRequest.AsObject;
+ static toObject(includeInstance: boolean, msg: SubscribeAlertsRequest): SubscribeAlertsRequest.AsObject;
+ static extensions: {[key: number]: jspb.ExtensionFieldInfo};
+ static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo};
+ static serializeBinaryToWriter(message: SubscribeAlertsRequest, writer: jspb.BinaryWriter): void;
+ static deserializeBinary(bytes: Uint8Array): SubscribeAlertsRequest;
+ static deserializeBinaryFromReader(message: SubscribeAlertsRequest, reader: jspb.BinaryReader): SubscribeAlertsRequest;
+}
+
+export namespace SubscribeAlertsRequest {
+ export type AsObject = {
+ }
+}
+
export class SubscribeSwapsAcceptedRequest extends jspb.Message {
serializeBinary(): Uint8Array;
diff --git a/lib/proto/xudrpc_pb.js b/lib/proto/xudrpc_pb.js
index 5f50a15f3..2c2e48149 100644
--- a/lib/proto/xudrpc_pb.js
+++ b/lib/proto/xudrpc_pb.js
@@ -19,7 +19,12 @@ goog.object.extend(proto, annotations_pb);
goog.exportSymbol('proto.xudrpc.AddCurrencyResponse', null, global);
goog.exportSymbol('proto.xudrpc.AddPairRequest', null, global);
goog.exportSymbol('proto.xudrpc.AddPairResponse', null, global);
+goog.exportSymbol('proto.xudrpc.Alert', null, global);
+goog.exportSymbol('proto.xudrpc.Alert.AlertType', null, global);
+goog.exportSymbol('proto.xudrpc.Alert.PayloadCase', null, global);
goog.exportSymbol('proto.xudrpc.Balance', null, global);
+goog.exportSymbol('proto.xudrpc.BalanceAlert', null, global);
+goog.exportSymbol('proto.xudrpc.BalanceAlert.Side', null, global);
goog.exportSymbol('proto.xudrpc.BanRequest', null, global);
goog.exportSymbol('proto.xudrpc.BanResponse', null, global);
goog.exportSymbol('proto.xudrpc.Chain', null, global);
@@ -90,6 +95,7 @@ goog.exportSymbol('proto.xudrpc.SetLogLevelRequest', null, global);
goog.exportSymbol('proto.xudrpc.SetLogLevelResponse', null, global);
goog.exportSymbol('proto.xudrpc.ShutdownRequest', null, global);
goog.exportSymbol('proto.xudrpc.ShutdownResponse', null, global);
+goog.exportSymbol('proto.xudrpc.SubscribeAlertsRequest', null, global);
goog.exportSymbol('proto.xudrpc.SubscribeOrdersRequest', null, global);
goog.exportSymbol('proto.xudrpc.SubscribeSwapsAcceptedRequest', null, global);
goog.exportSymbol('proto.xudrpc.SubscribeSwapsRequest', null, global);
@@ -171,6 +177,27 @@ if (goog.DEBUG && !COMPILED) {
*/
proto.xudrpc.AddPairResponse.displayName = 'proto.xudrpc.AddPairResponse';
}
+/**
+ * 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.Alert = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, proto.xudrpc.Alert.oneofGroups_);
+};
+goog.inherits(proto.xudrpc.Alert, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.xudrpc.Alert.displayName = 'proto.xudrpc.Alert';
+}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@@ -192,6 +219,27 @@ if (goog.DEBUG && !COMPILED) {
*/
proto.xudrpc.Balance.displayName = 'proto.xudrpc.Balance';
}
+/**
+ * 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.BalanceAlert = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.xudrpc.BalanceAlert, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.xudrpc.BalanceAlert.displayName = 'proto.xudrpc.BalanceAlert';
+}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@@ -1536,6 +1584,27 @@ if (goog.DEBUG && !COMPILED) {
*/
proto.xudrpc.SubscribeOrdersRequest.displayName = 'proto.xudrpc.SubscribeOrdersRequest';
}
+/**
+ * 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.SubscribeAlertsRequest = function(opt_data) {
+ jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.xudrpc.SubscribeAlertsRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+ /**
+ * @public
+ * @override
+ */
+ proto.xudrpc.SubscribeAlertsRequest.displayName = 'proto.xudrpc.SubscribeAlertsRequest';
+}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@@ -2176,82 +2245,635 @@ proto.xudrpc.AddPairResponse.prototype.toObject = function(opt_includeInstance)
/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- * the JSPB instance for transitional soy proto support:
- * http://goto/soy-param-migration
- * @param {!proto.xudrpc.AddPairResponse} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.xudrpc.AddPairResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.AddPairResponse.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.AddPairResponse}
+ */
+proto.xudrpc.AddPairResponse.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.xudrpc.AddPairResponse;
+ return proto.xudrpc.AddPairResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.xudrpc.AddPairResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.xudrpc.AddPairResponse}
+ */
+proto.xudrpc.AddPairResponse.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.AddPairResponse.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.xudrpc.AddPairResponse.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.AddPairResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.AddPairResponse.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+};
+
+
+
+/**
+ * Oneof group definitions for this message. Each group defines the field
+ * numbers belonging to that group. When of these fields' value is set, all
+ * other fields in the group are cleared. During deserialization, if multiple
+ * fields are encountered for a group, only the last value seen will be kept.
+ * @private {!Array>}
+ * @const
+ */
+proto.xudrpc.Alert.oneofGroups_ = [[4]];
+
+/**
+ * @enum {number}
+ */
+proto.xudrpc.Alert.PayloadCase = {
+ PAYLOAD_NOT_SET: 0,
+ BALANCE_ALERT: 4
+};
+
+/**
+ * @return {proto.xudrpc.Alert.PayloadCase}
+ */
+proto.xudrpc.Alert.prototype.getPayloadCase = function() {
+ return /** @type {proto.xudrpc.Alert.PayloadCase} */(jspb.Message.computeOneofCase(this, proto.xudrpc.Alert.oneofGroups_[0]));
+};
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.xudrpc.Alert.prototype.toObject = function(opt_includeInstance) {
+ return proto.xudrpc.Alert.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.xudrpc.Alert} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.Alert.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ type: jspb.Message.getFieldWithDefault(msg, 1, 0),
+ message: jspb.Message.getFieldWithDefault(msg, 2, ""),
+ date: jspb.Message.getFieldWithDefault(msg, 3, 0),
+ balanceAlert: (f = msg.getBalanceAlert()) && proto.xudrpc.BalanceAlert.toObject(includeInstance, f)
+ };
+
+ 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.Alert}
+ */
+proto.xudrpc.Alert.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.xudrpc.Alert;
+ return proto.xudrpc.Alert.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.xudrpc.Alert} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.xudrpc.Alert}
+ */
+proto.xudrpc.Alert.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {!proto.xudrpc.Alert.AlertType} */ (reader.readEnum());
+ msg.setType(value);
+ break;
+ case 2:
+ var value = /** @type {string} */ (reader.readString());
+ msg.setMessage(value);
+ break;
+ case 3:
+ var value = /** @type {number} */ (reader.readInt64());
+ msg.setDate(value);
+ break;
+ case 4:
+ var value = new proto.xudrpc.BalanceAlert;
+ reader.readMessage(value,proto.xudrpc.BalanceAlert.deserializeBinaryFromReader);
+ msg.setBalanceAlert(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.xudrpc.Alert.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.xudrpc.Alert.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.Alert} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.Alert.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getType();
+ if (f !== 0.0) {
+ writer.writeEnum(
+ 1,
+ f
+ );
+ }
+ f = message.getMessage();
+ if (f.length > 0) {
+ writer.writeString(
+ 2,
+ f
+ );
+ }
+ f = message.getDate();
+ if (f !== 0) {
+ writer.writeInt64(
+ 3,
+ f
+ );
+ }
+ f = message.getBalanceAlert();
+ if (f != null) {
+ writer.writeMessage(
+ 4,
+ f,
+ proto.xudrpc.BalanceAlert.serializeBinaryToWriter
+ );
+ }
+};
+
+
+/**
+ * @enum {number}
+ */
+proto.xudrpc.Alert.AlertType = {
+ LOW_TRADING_BALANCE: 0
+};
+
+/**
+ * optional AlertType type = 1;
+ * @return {!proto.xudrpc.Alert.AlertType}
+ */
+proto.xudrpc.Alert.prototype.getType = function() {
+ return /** @type {!proto.xudrpc.Alert.AlertType} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {!proto.xudrpc.Alert.AlertType} value
+ * @return {!proto.xudrpc.Alert} returns this
+ */
+proto.xudrpc.Alert.prototype.setType = function(value) {
+ return jspb.Message.setProto3EnumField(this, 1, value);
+};
+
+
+/**
+ * optional string message = 2;
+ * @return {string}
+ */
+proto.xudrpc.Alert.prototype.getMessage = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.xudrpc.Alert} returns this
+ */
+proto.xudrpc.Alert.prototype.setMessage = function(value) {
+ return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional int64 date = 3;
+ * @return {number}
+ */
+proto.xudrpc.Alert.prototype.getDate = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.xudrpc.Alert} returns this
+ */
+proto.xudrpc.Alert.prototype.setDate = function(value) {
+ return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional BalanceAlert balance_alert = 4;
+ * @return {?proto.xudrpc.BalanceAlert}
+ */
+proto.xudrpc.Alert.prototype.getBalanceAlert = function() {
+ return /** @type{?proto.xudrpc.BalanceAlert} */ (
+ jspb.Message.getWrapperField(this, proto.xudrpc.BalanceAlert, 4));
+};
+
+
+/**
+ * @param {?proto.xudrpc.BalanceAlert|undefined} value
+ * @return {!proto.xudrpc.Alert} returns this
+*/
+proto.xudrpc.Alert.prototype.setBalanceAlert = function(value) {
+ return jspb.Message.setOneofWrapperField(this, 4, proto.xudrpc.Alert.oneofGroups_[0], value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.xudrpc.Alert} returns this
+ */
+proto.xudrpc.Alert.prototype.clearBalanceAlert = function() {
+ return this.setBalanceAlert(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.xudrpc.Alert.prototype.hasBalanceAlert = function() {
+ return jspb.Message.getField(this, 4) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.xudrpc.Balance.prototype.toObject = function(opt_includeInstance) {
+ return proto.xudrpc.Balance.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.xudrpc.Balance} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.Balance.toObject = function(includeInstance, msg) {
+ var f, obj = {
+ totalBalance: jspb.Message.getFieldWithDefault(msg, 1, 0),
+ channelBalance: jspb.Message.getFieldWithDefault(msg, 2, 0),
+ pendingChannelBalance: jspb.Message.getFieldWithDefault(msg, 3, 0),
+ inactiveChannelBalance: jspb.Message.getFieldWithDefault(msg, 4, 0),
+ walletBalance: jspb.Message.getFieldWithDefault(msg, 5, 0),
+ unconfirmedWalletBalance: jspb.Message.getFieldWithDefault(msg, 6, 0)
+ };
+
+ 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.Balance}
+ */
+proto.xudrpc.Balance.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.xudrpc.Balance;
+ return proto.xudrpc.Balance.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.xudrpc.Balance} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.xudrpc.Balance}
+ */
+proto.xudrpc.Balance.deserializeBinaryFromReader = function(msg, reader) {
+ while (reader.nextField()) {
+ if (reader.isEndGroup()) {
+ break;
+ }
+ var field = reader.getFieldNumber();
+ switch (field) {
+ case 1:
+ var value = /** @type {number} */ (reader.readUint64());
+ msg.setTotalBalance(value);
+ break;
+ case 2:
+ var value = /** @type {number} */ (reader.readUint64());
+ msg.setChannelBalance(value);
+ break;
+ case 3:
+ var value = /** @type {number} */ (reader.readUint64());
+ msg.setPendingChannelBalance(value);
+ break;
+ case 4:
+ var value = /** @type {number} */ (reader.readUint64());
+ msg.setInactiveChannelBalance(value);
+ break;
+ case 5:
+ var value = /** @type {number} */ (reader.readUint64());
+ msg.setWalletBalance(value);
+ break;
+ case 6:
+ var value = /** @type {number} */ (reader.readUint64());
+ msg.setUnconfirmedWalletBalance(value);
+ break;
+ default:
+ reader.skipField();
+ break;
+ }
+ }
+ return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.xudrpc.Balance.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.xudrpc.Balance.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.Balance} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.Balance.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+ f = message.getTotalBalance();
+ if (f !== 0) {
+ writer.writeUint64(
+ 1,
+ f
+ );
+ }
+ f = message.getChannelBalance();
+ if (f !== 0) {
+ writer.writeUint64(
+ 2,
+ f
+ );
+ }
+ f = message.getPendingChannelBalance();
+ if (f !== 0) {
+ writer.writeUint64(
+ 3,
+ f
+ );
+ }
+ f = message.getInactiveChannelBalance();
+ if (f !== 0) {
+ writer.writeUint64(
+ 4,
+ f
+ );
+ }
+ f = message.getWalletBalance();
+ if (f !== 0) {
+ writer.writeUint64(
+ 5,
+ f
+ );
+ }
+ f = message.getUnconfirmedWalletBalance();
+ if (f !== 0) {
+ writer.writeUint64(
+ 6,
+ f
+ );
+ }
+};
+
+
+/**
+ * optional uint64 total_balance = 1;
+ * @return {number}
+ */
+proto.xudrpc.Balance.prototype.getTotalBalance = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.xudrpc.Balance} returns this
+ */
+proto.xudrpc.Balance.prototype.setTotalBalance = function(value) {
+ return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional uint64 channel_balance = 2;
+ * @return {number}
+ */
+proto.xudrpc.Balance.prototype.getChannelBalance = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.xudrpc.Balance} returns this
+ */
+proto.xudrpc.Balance.prototype.setChannelBalance = function(value) {
+ return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional uint64 pending_channel_balance = 3;
+ * @return {number}
+ */
+proto.xudrpc.Balance.prototype.getPendingChannelBalance = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.xudrpc.Balance} returns this
+ */
+proto.xudrpc.Balance.prototype.setPendingChannelBalance = function(value) {
+ return jspb.Message.setProto3IntField(this, 3, value);
+};
+
+
+/**
+ * optional uint64 inactive_channel_balance = 4;
+ * @return {number}
+ */
+proto.xudrpc.Balance.prototype.getInactiveChannelBalance = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.xudrpc.Balance} returns this
*/
-proto.xudrpc.AddPairResponse.toObject = function(includeInstance, msg) {
- var f, obj = {
-
- };
-
- if (includeInstance) {
- obj.$jspbMessageInstance = msg;
- }
- return obj;
+proto.xudrpc.Balance.prototype.setInactiveChannelBalance = function(value) {
+ return jspb.Message.setProto3IntField(this, 4, value);
};
-}
/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.xudrpc.AddPairResponse}
+ * optional uint64 wallet_balance = 5;
+ * @return {number}
*/
-proto.xudrpc.AddPairResponse.deserializeBinary = function(bytes) {
- var reader = new jspb.BinaryReader(bytes);
- var msg = new proto.xudrpc.AddPairResponse;
- return proto.xudrpc.AddPairResponse.deserializeBinaryFromReader(msg, reader);
+proto.xudrpc.Balance.prototype.getWalletBalance = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
};
/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.xudrpc.AddPairResponse} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.xudrpc.AddPairResponse}
+ * @param {number} value
+ * @return {!proto.xudrpc.Balance} returns this
*/
-proto.xudrpc.AddPairResponse.deserializeBinaryFromReader = function(msg, reader) {
- while (reader.nextField()) {
- if (reader.isEndGroup()) {
- break;
- }
- var field = reader.getFieldNumber();
- switch (field) {
- default:
- reader.skipField();
- break;
- }
- }
- return msg;
+proto.xudrpc.Balance.prototype.setWalletBalance = function(value) {
+ return jspb.Message.setProto3IntField(this, 5, value);
};
/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
+ * optional uint64 unconfirmed_wallet_balance = 6;
+ * @return {number}
*/
-proto.xudrpc.AddPairResponse.prototype.serializeBinary = function() {
- var writer = new jspb.BinaryWriter();
- proto.xudrpc.AddPairResponse.serializeBinaryToWriter(this, writer);
- return writer.getResultBuffer();
+proto.xudrpc.Balance.prototype.getUnconfirmedWalletBalance = function() {
+ return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
};
/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.xudrpc.AddPairResponse} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
+ * @param {number} value
+ * @return {!proto.xudrpc.Balance} returns this
*/
-proto.xudrpc.AddPairResponse.serializeBinaryToWriter = function(message, writer) {
- var f = undefined;
+proto.xudrpc.Balance.prototype.setUnconfirmedWalletBalance = function(value) {
+ return jspb.Message.setProto3IntField(this, 6, value);
};
@@ -2271,8 +2893,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) {
* http://goto/soy-param-migration
* @return {!Object}
*/
-proto.xudrpc.Balance.prototype.toObject = function(opt_includeInstance) {
- return proto.xudrpc.Balance.toObject(opt_includeInstance, this);
+proto.xudrpc.BalanceAlert.prototype.toObject = function(opt_includeInstance) {
+ return proto.xudrpc.BalanceAlert.toObject(opt_includeInstance, this);
};
@@ -2281,18 +2903,18 @@ proto.xudrpc.Balance.prototype.toObject = function(opt_includeInstance) {
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
* the JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
- * @param {!proto.xudrpc.Balance} msg The msg instance to transform.
+ * @param {!proto.xudrpc.BalanceAlert} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
-proto.xudrpc.Balance.toObject = function(includeInstance, msg) {
+proto.xudrpc.BalanceAlert.toObject = function(includeInstance, msg) {
var f, obj = {
totalBalance: jspb.Message.getFieldWithDefault(msg, 1, 0),
- channelBalance: jspb.Message.getFieldWithDefault(msg, 2, 0),
- pendingChannelBalance: jspb.Message.getFieldWithDefault(msg, 3, 0),
- inactiveChannelBalance: jspb.Message.getFieldWithDefault(msg, 4, 0),
- walletBalance: jspb.Message.getFieldWithDefault(msg, 5, 0),
- unconfirmedWalletBalance: jspb.Message.getFieldWithDefault(msg, 6, 0)
+ side: jspb.Message.getFieldWithDefault(msg, 2, 0),
+ bound: jspb.Message.getFieldWithDefault(msg, 3, 0),
+ percent: jspb.Message.getFieldWithDefault(msg, 4, 0),
+ sideBalance: jspb.Message.getFieldWithDefault(msg, 5, 0),
+ currency: jspb.Message.getFieldWithDefault(msg, 6, "")
};
if (includeInstance) {
@@ -2306,23 +2928,23 @@ proto.xudrpc.Balance.toObject = function(includeInstance, msg) {
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.xudrpc.Balance}
+ * @return {!proto.xudrpc.BalanceAlert}
*/
-proto.xudrpc.Balance.deserializeBinary = function(bytes) {
+proto.xudrpc.BalanceAlert.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
- var msg = new proto.xudrpc.Balance;
- return proto.xudrpc.Balance.deserializeBinaryFromReader(msg, reader);
+ var msg = new proto.xudrpc.BalanceAlert;
+ return proto.xudrpc.BalanceAlert.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
- * @param {!proto.xudrpc.Balance} msg The message object to deserialize into.
+ * @param {!proto.xudrpc.BalanceAlert} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.xudrpc.Balance}
+ * @return {!proto.xudrpc.BalanceAlert}
*/
-proto.xudrpc.Balance.deserializeBinaryFromReader = function(msg, reader) {
+proto.xudrpc.BalanceAlert.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
@@ -2334,24 +2956,24 @@ proto.xudrpc.Balance.deserializeBinaryFromReader = function(msg, reader) {
msg.setTotalBalance(value);
break;
case 2:
- var value = /** @type {number} */ (reader.readUint64());
- msg.setChannelBalance(value);
+ var value = /** @type {!proto.xudrpc.BalanceAlert.Side} */ (reader.readEnum());
+ msg.setSide(value);
break;
case 3:
- var value = /** @type {number} */ (reader.readUint64());
- msg.setPendingChannelBalance(value);
+ var value = /** @type {number} */ (reader.readUint32());
+ msg.setBound(value);
break;
case 4:
- var value = /** @type {number} */ (reader.readUint64());
- msg.setInactiveChannelBalance(value);
+ var value = /** @type {number} */ (reader.readUint32());
+ msg.setPercent(value);
break;
case 5:
var value = /** @type {number} */ (reader.readUint64());
- msg.setWalletBalance(value);
+ msg.setSideBalance(value);
break;
case 6:
- var value = /** @type {number} */ (reader.readUint64());
- msg.setUnconfirmedWalletBalance(value);
+ var value = /** @type {string} */ (reader.readString());
+ msg.setCurrency(value);
break;
default:
reader.skipField();
@@ -2366,9 +2988,9 @@ proto.xudrpc.Balance.deserializeBinaryFromReader = function(msg, reader) {
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
-proto.xudrpc.Balance.prototype.serializeBinary = function() {
+proto.xudrpc.BalanceAlert.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
- proto.xudrpc.Balance.serializeBinaryToWriter(this, writer);
+ proto.xudrpc.BalanceAlert.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
@@ -2376,11 +2998,11 @@ proto.xudrpc.Balance.prototype.serializeBinary = function() {
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
- * @param {!proto.xudrpc.Balance} message
+ * @param {!proto.xudrpc.BalanceAlert} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
-proto.xudrpc.Balance.serializeBinaryToWriter = function(message, writer) {
+proto.xudrpc.BalanceAlert.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
f = message.getTotalBalance();
if (f !== 0) {
@@ -2389,37 +3011,37 @@ proto.xudrpc.Balance.serializeBinaryToWriter = function(message, writer) {
f
);
}
- f = message.getChannelBalance();
- if (f !== 0) {
- writer.writeUint64(
+ f = message.getSide();
+ if (f !== 0.0) {
+ writer.writeEnum(
2,
f
);
}
- f = message.getPendingChannelBalance();
+ f = message.getBound();
if (f !== 0) {
- writer.writeUint64(
+ writer.writeUint32(
3,
f
);
}
- f = message.getInactiveChannelBalance();
+ f = message.getPercent();
if (f !== 0) {
- writer.writeUint64(
+ writer.writeUint32(
4,
f
);
}
- f = message.getWalletBalance();
+ f = message.getSideBalance();
if (f !== 0) {
writer.writeUint64(
5,
f
);
}
- f = message.getUnconfirmedWalletBalance();
- if (f !== 0) {
- writer.writeUint64(
+ f = message.getCurrency();
+ if (f.length > 0) {
+ writer.writeString(
6,
f
);
@@ -2427,111 +3049,119 @@ proto.xudrpc.Balance.serializeBinaryToWriter = function(message, writer) {
};
+/**
+ * @enum {number}
+ */
+proto.xudrpc.BalanceAlert.Side = {
+ REMOTE: 0,
+ LOCAL: 1
+};
+
/**
* optional uint64 total_balance = 1;
* @return {number}
*/
-proto.xudrpc.Balance.prototype.getTotalBalance = function() {
+proto.xudrpc.BalanceAlert.prototype.getTotalBalance = function() {
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
};
/**
* @param {number} value
- * @return {!proto.xudrpc.Balance} returns this
+ * @return {!proto.xudrpc.BalanceAlert} returns this
*/
-proto.xudrpc.Balance.prototype.setTotalBalance = function(value) {
+proto.xudrpc.BalanceAlert.prototype.setTotalBalance = function(value) {
return jspb.Message.setProto3IntField(this, 1, value);
};
/**
- * optional uint64 channel_balance = 2;
- * @return {number}
+ * optional Side side = 2;
+ * @return {!proto.xudrpc.BalanceAlert.Side}
*/
-proto.xudrpc.Balance.prototype.getChannelBalance = function() {
- return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+proto.xudrpc.BalanceAlert.prototype.getSide = function() {
+ return /** @type {!proto.xudrpc.BalanceAlert.Side} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
};
/**
- * @param {number} value
- * @return {!proto.xudrpc.Balance} returns this
+ * @param {!proto.xudrpc.BalanceAlert.Side} value
+ * @return {!proto.xudrpc.BalanceAlert} returns this
*/
-proto.xudrpc.Balance.prototype.setChannelBalance = function(value) {
- return jspb.Message.setProto3IntField(this, 2, value);
+proto.xudrpc.BalanceAlert.prototype.setSide = function(value) {
+ return jspb.Message.setProto3EnumField(this, 2, value);
};
/**
- * optional uint64 pending_channel_balance = 3;
+ * optional uint32 bound = 3;
* @return {number}
*/
-proto.xudrpc.Balance.prototype.getPendingChannelBalance = function() {
+proto.xudrpc.BalanceAlert.prototype.getBound = function() {
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
};
/**
* @param {number} value
- * @return {!proto.xudrpc.Balance} returns this
+ * @return {!proto.xudrpc.BalanceAlert} returns this
*/
-proto.xudrpc.Balance.prototype.setPendingChannelBalance = function(value) {
+proto.xudrpc.BalanceAlert.prototype.setBound = function(value) {
return jspb.Message.setProto3IntField(this, 3, value);
};
/**
- * optional uint64 inactive_channel_balance = 4;
+ * optional uint32 percent = 4;
* @return {number}
*/
-proto.xudrpc.Balance.prototype.getInactiveChannelBalance = function() {
+proto.xudrpc.BalanceAlert.prototype.getPercent = function() {
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
};
/**
* @param {number} value
- * @return {!proto.xudrpc.Balance} returns this
+ * @return {!proto.xudrpc.BalanceAlert} returns this
*/
-proto.xudrpc.Balance.prototype.setInactiveChannelBalance = function(value) {
+proto.xudrpc.BalanceAlert.prototype.setPercent = function(value) {
return jspb.Message.setProto3IntField(this, 4, value);
};
/**
- * optional uint64 wallet_balance = 5;
+ * optional uint64 side_balance = 5;
* @return {number}
*/
-proto.xudrpc.Balance.prototype.getWalletBalance = function() {
+proto.xudrpc.BalanceAlert.prototype.getSideBalance = function() {
return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
};
/**
* @param {number} value
- * @return {!proto.xudrpc.Balance} returns this
+ * @return {!proto.xudrpc.BalanceAlert} returns this
*/
-proto.xudrpc.Balance.prototype.setWalletBalance = function(value) {
+proto.xudrpc.BalanceAlert.prototype.setSideBalance = function(value) {
return jspb.Message.setProto3IntField(this, 5, value);
};
/**
- * optional uint64 unconfirmed_wallet_balance = 6;
- * @return {number}
+ * optional string currency = 6;
+ * @return {string}
*/
-proto.xudrpc.Balance.prototype.getUnconfirmedWalletBalance = function() {
- return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
+proto.xudrpc.BalanceAlert.prototype.getCurrency = function() {
+ return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
};
/**
- * @param {number} value
- * @return {!proto.xudrpc.Balance} returns this
+ * @param {string} value
+ * @return {!proto.xudrpc.BalanceAlert} returns this
*/
-proto.xudrpc.Balance.prototype.setUnconfirmedWalletBalance = function(value) {
- return jspb.Message.setProto3IntField(this, 6, value);
+proto.xudrpc.BalanceAlert.prototype.setCurrency = function(value) {
+ return jspb.Message.setProto3StringField(this, 6, value);
};
@@ -14161,6 +14791,107 @@ proto.xudrpc.SubscribeOrdersRequest.prototype.setExisting = function(value) {
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ * net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ * JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.xudrpc.SubscribeAlertsRequest.prototype.toObject = function(opt_includeInstance) {
+ return proto.xudrpc.SubscribeAlertsRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ * the JSPB instance for transitional soy proto support:
+ * http://goto/soy-param-migration
+ * @param {!proto.xudrpc.SubscribeAlertsRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.SubscribeAlertsRequest.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.SubscribeAlertsRequest}
+ */
+proto.xudrpc.SubscribeAlertsRequest.deserializeBinary = function(bytes) {
+ var reader = new jspb.BinaryReader(bytes);
+ var msg = new proto.xudrpc.SubscribeAlertsRequest;
+ return proto.xudrpc.SubscribeAlertsRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.xudrpc.SubscribeAlertsRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.xudrpc.SubscribeAlertsRequest}
+ */
+proto.xudrpc.SubscribeAlertsRequest.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.SubscribeAlertsRequest.prototype.serializeBinary = function() {
+ var writer = new jspb.BinaryWriter();
+ proto.xudrpc.SubscribeAlertsRequest.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.SubscribeAlertsRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.xudrpc.SubscribeAlertsRequest.serializeBinaryToWriter = function(message, writer) {
+ var f = undefined;
+};
+
+
+
+
+
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.
diff --git a/lib/service/Service.ts b/lib/service/Service.ts
index 0301fb130..3d907d3e6 100644
--- a/lib/service/Service.ts
+++ b/lib/service/Service.ts
@@ -23,6 +23,7 @@ import swapsErrors from '../swaps/errors';
import { ChannelBalance } from '../swaps/SwapClient';
import SwapClientManager from '../swaps/SwapClientManager';
import Swaps from '../swaps/Swaps';
+import Alerts from '../alerts/Alerts';
import { SwapAccepted, SwapDeal, SwapFailure, SwapSuccess, TradingLimits } from '../swaps/types';
import { isNodePubKey } from '../utils/aliasUtils';
import { parseUri, toUri, UriParts } from '../utils/uriUtils';
@@ -38,6 +39,7 @@ import {
ServiceTrade,
XudInfo,
} from './types';
+import { Alert } from '../alerts/types';
/** Functions to check argument validity and throw [[INVALID_ARGUMENT]] when invalid. */
const argChecks = {
@@ -102,6 +104,7 @@ class Service extends EventEmitter {
private swaps: Swaps;
private logger: Logger;
private nodekey: NodeKey;
+ private alerts: Alerts;
/** Create an instance of available RPC methods and bind all exposed functions. */
constructor(components: ServiceComponents) {
@@ -114,6 +117,7 @@ class Service extends EventEmitter {
this.swaps = components.swaps;
this.logger = components.logger;
this.nodekey = components.nodeKey;
+ this.alerts = components.alerts;
this.version = components.version;
}
@@ -812,6 +816,27 @@ class Service extends EventEmitter {
return this.pool.discoverNodes(nodePubKey);
};
+ /*
+ * Subscribe to alerts.
+ */
+ public subscribeAlerts = (callback: (payload: Alert) => void, cancelled$: Observable) => {
+ const observables: Observable[] = [];
+ observables.push(fromEvent(this.alerts, 'alert'));
+
+ const mergedObservable$ = this.getMergedObservable$(observables, cancelled$);
+
+ mergedObservable$.subscribe({
+ next: (alert) => {
+ callback(alert);
+ },
+ error: this.logger.error,
+ });
+ };
+
+ private getMergedObservable$(observables: Observable[], cancelled$: Observable) {
+ return merge(...observables).pipe(takeUntil(cancelled$));
+ }
+
/*
* Subscribe to orders being added to the order book.
*/
diff --git a/lib/service/types.ts b/lib/service/types.ts
index 706ee206e..ad1b954c7 100644
--- a/lib/service/types.ts
+++ b/lib/service/types.ts
@@ -8,6 +8,7 @@ import Pool from '../p2p/Pool';
import SwapClientManager from '../swaps/SwapClientManager';
import Swaps from '../swaps/Swaps';
import NodeKey from '../nodekey/NodeKey';
+import Alerts from '../alerts/Alerts';
/**
* The components required by the API service layer.
@@ -21,6 +22,7 @@ export type ServiceComponents = {
swaps: Swaps;
logger: Logger;
nodeKey: NodeKey;
+ alerts: Alerts;
/** The function to be called to shutdown the parent process */
shutdown: () => void;
};
diff --git a/lib/swaps/SwapClient.ts b/lib/swaps/SwapClient.ts
index 8cecff130..8ff792f89 100644
--- a/lib/swaps/SwapClient.ts
+++ b/lib/swaps/SwapClient.ts
@@ -1,5 +1,6 @@
import { EventEmitter } from 'events';
-import { SwapClientType } from '../constants/enums';
+import { BalanceAlertEvent } from 'lib/alerts/types';
+import { ChannelSide, SwapClientType } from '../constants/enums';
import Logger from '../Logger';
import { setTimeoutPromise } from '../utils/utils';
import { CloseChannelParams, OpenChannelParams, Route, SwapCapacities, SwapDeal } from './types';
@@ -72,9 +73,11 @@ export type WithdrawArguments = {
interface SwapClient {
on(event: 'connectionVerified', listener: (swapClientInfo: SwapClientInfo) => void): this;
on(event: 'htlcAccepted', listener: (rHash: string, units: bigint, currency?: string) => void): this;
+ on(event: 'lowTradingBalance', listener: (alert: BalanceAlertEvent) => void): this;
once(event: 'initialized', listener: () => void): this;
emit(event: 'connectionVerified', swapClientInfo: SwapClientInfo): boolean;
emit(event: 'htlcAccepted', rHash: string, units: bigint, currency?: string): boolean;
+ emit(event: 'lowTradingBalance', alert: BalanceAlertEvent): boolean;
emit(event: 'initialized'): boolean;
}
@@ -230,6 +233,34 @@ abstract class SwapClient extends EventEmitter {
}
};
+ protected checkLowBalance = (
+ remoteBalance: number,
+ localBalance: number,
+ totalBalance: number,
+ alertThreshold: number,
+ currency: string,
+ ) => {
+ if (localBalance < alertThreshold) {
+ this.emit('lowTradingBalance', {
+ totalBalance,
+ currency,
+ side: ChannelSide.Local,
+ sideBalance: localBalance,
+ bound: 10,
+ });
+ }
+
+ if (remoteBalance < alertThreshold) {
+ this.emit('lowTradingBalance', {
+ totalBalance,
+ currency,
+ side: ChannelSide.Remote,
+ sideBalance: remoteBalance,
+ bound: 10,
+ });
+ }
+ };
+
private updateCapacityTimerCallback = async () => {
if (this.isConnected()) {
await this.updateCapacity();
diff --git a/proto/xudrpc.proto b/proto/xudrpc.proto
index 6080c0287..9391a324e 100644
--- a/proto/xudrpc.proto
+++ b/proto/xudrpc.proto
@@ -294,6 +294,13 @@ service Xud {
};
}
+ /* Subscribes to alerts such as low balance. */
+ rpc SubscribeAlerts(SubscribeAlertsRequest) returns (stream Alert) {
+ option (google.api.http) = {
+ get: "/v1/subscribealerts"
+ };
+ }
+
/* Subscribes to orders being added to and removed from the order book. This call allows the client
* to maintain an up-to-date view of the order book. For example, an exchange that wants to show
* its users a real time view of the orders available to them would subscribe to this streaming
@@ -401,6 +408,22 @@ message AddPairRequest {
}
message AddPairResponse {}
+message Alert {
+ // The type of the alert.
+ enum AlertType {
+ LOW_TRADING_BALANCE = 0;
+ }
+ AlertType type = 1 [json_name = "type"];
+ // The human readable alert message.
+ string message = 2 [json_name = "message"];
+ // The human readable alert message.
+ int64 date = 3 [json_name = "date"];
+ // The structured payload.
+ oneof payload {
+ BalanceAlert balance_alert = 4 [json_name = "balance_alert"];
+ }
+}
+
message Balance {
// Total balance denominated in satoshis.
uint64 total_balance = 1 [json_name = "total_balance"];
@@ -416,6 +439,25 @@ message Balance {
uint64 unconfirmed_wallet_balance = 6 [json_name = "unconfirmed_wallet_balance"];
}
+message BalanceAlert {
+ // The total balance.
+ uint64 total_balance = 1 [json_name = "total_balance"];
+ // The side of the low balance.
+ enum Side {
+ REMOTE = 0;
+ LOCAL = 1;
+ }
+ Side side = 2 [json_name = "side"];
+ // The bound of the low balance in percentage.
+ uint32 bound = 3 [json_name = "bound"];
+ // The percent of the total trading balance.
+ uint32 percent = 4 [json_name = "percent"];
+ // The balance in satoshis on this side of the channel
+ uint64 side_balance = 5 [json_name = "side_balance"];
+ // The currency of the channel this alert is for.
+ string currency = 6 [json_name = "currency"];
+}
+
message BanRequest {
// The node pub key or alias of the node to ban.
string node_identifier = 1 [json_name = "node_identifier"];
@@ -868,6 +910,9 @@ message SubscribeOrdersRequest {
bool existing = 1 [json_name = "existing"];
}
+message SubscribeAlertsRequest {
+}
+
message SubscribeSwapsAcceptedRequest { }
message SubscribeSwapsRequest {
diff --git a/test/integration/Service.spec.ts b/test/integration/Service.spec.ts
index 79c0d87b7..7bd418921 100644
--- a/test/integration/Service.spec.ts
+++ b/test/integration/Service.spec.ts
@@ -5,6 +5,9 @@ import p2pErrors from '../../lib/p2p/errors';
import Service from '../../lib/service/Service';
import Xud from '../../lib/Xud';
import { getTempDir } from '../utils';
+import { TestScheduler } from 'rxjs/testing';
+import { Observable } from 'rxjs';
+import { Alert } from '../../lib/alerts/types';
chai.use(chaiAsPromised);
@@ -210,4 +213,38 @@ describe('API Service', () => {
});
await expect(shutdownPromise).to.be.fulfilled;
});
+
+ let testScheduler: TestScheduler;
+
+ describe('getMergedObservable$', () => {
+ beforeEach(() => {
+ testScheduler = new TestScheduler((actual, expected) => {
+ expect(actual).to.deep.equal(expected);
+ });
+ });
+
+ it('should continue without cancelled$', async () => {
+ testScheduler.run(({ cold, expectObservable }) => {
+ const firstLowBalanceEvent = cold('-a--b---c---') as Observable;
+ const secondLowBalanceEvent = cold('--a-b|') as Observable;
+ const cancelled = cold('-') as Observable;
+
+ const lowBalanceObservables: Observable[] = [firstLowBalanceEvent, secondLowBalanceEvent];
+ const finalObservable = service['getMergedObservable$'](lowBalanceObservables, cancelled);
+ expectObservable(finalObservable).toBe('-aa-(bb)c---');
+ });
+ });
+
+ it('should cancel with cancelled$', async () => {
+ testScheduler.run(({ cold, expectObservable }) => {
+ const firstLowBalanceEvent = cold('-a--b---c---') as Observable;
+ const secondLowBalanceEvent = cold('--a-b|') as Observable;
+ const cancelled = cold('---a') as Observable;
+
+ const lowBalanceObservables: Observable[] = [firstLowBalanceEvent, secondLowBalanceEvent];
+ const finalObservable = service['getMergedObservable$'](lowBalanceObservables, cancelled);
+ expectObservable(finalObservable).toBe('-aa|');
+ });
+ });
+ });
});
diff --git a/test/jest/LndClient.spec.ts b/test/jest/LndClient.spec.ts
index ba647eef1..8d3794d9b 100644
--- a/test/jest/LndClient.spec.ts
+++ b/test/jest/LndClient.spec.ts
@@ -2,7 +2,7 @@ import LndClient from '../../lib/lndclient/LndClient';
import { LndClientConfig } from '../../lib/lndclient/types';
import Logger from '../../lib/Logger';
import { getValidDeal } from '../utils';
-import { SwapRole } from '../../lib/constants/enums';
+import { ChannelSide, SwapRole } from '../../lib/constants/enums';
import { ClientStatus } from '../../lib/swaps/SwapClient';
const openChannelSyncResponse = {
@@ -279,4 +279,112 @@ describe('LndClient', () => {
expect(lnd['maxChannelInboundAmount']).toEqual(295);
});
});
+
+ describe('checkLowBalance', () => {
+ test('emits lowTradingBalance on local balance is less than alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 10;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 110;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(1);
+ expect(lnd['emit']).toHaveBeenCalledWith('lowTradingBalance', {
+ totalBalance,
+ currency,
+ side: ChannelSide.Local,
+ sideBalance: localBalance,
+ bound: 10,
+ });
+ });
+ test('emits lowBalance on local balance is less than alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 10;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 110;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(1);
+ expect(lnd['emit']).toHaveBeenCalledWith('lowTradingBalance', {
+ totalBalance,
+ currency,
+ side: ChannelSide.Local,
+ sideBalance: localBalance,
+ bound: 10,
+ });
+ });
+ test('dont emit on local balance equals alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 12;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 110;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(0);
+ });
+ test('dont emit on local balance is higher than alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 12.5;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 110;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(0);
+ });
+ test('emits on remote balance is less than alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 110;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 10;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(1);
+ expect(lnd['emit']).toHaveBeenCalledWith('lowTradingBalance', {
+ totalBalance,
+ currency,
+ side: ChannelSide.Remote,
+ sideBalance: remoteBalance,
+ bound: 10,
+ });
+ });
+ test('dont emit on remote balance equals alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 110;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 12;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(0);
+ });
+ test('dont emit on remote balance is higher than alert threshold of total balance ', async () => {
+ lnd['emit'] = jest.fn().mockImplementation();
+ const totalBalance = 120;
+ const localBalance = 110;
+ const alertThreshold = totalBalance * 0.1;
+ const remoteBalance = 12.5;
+
+ const currency = 'BTC';
+ lnd['checkLowBalance'](remoteBalance, localBalance, totalBalance, alertThreshold, currency);
+
+ expect(lnd['emit']).toHaveBeenCalledTimes(0);
+ });
+ });
});
diff --git a/test/jest/Orderbook.spec.ts b/test/jest/Orderbook.spec.ts
index 45cd2e7c5..3b65377ec 100644
--- a/test/jest/Orderbook.spec.ts
+++ b/test/jest/Orderbook.spec.ts
@@ -124,6 +124,7 @@ const loggers = {
swaps: logger,
http: logger,
service: logger,
+ alerts: logger,
};
const localId = '97945230-8144-11e9-beb7-49ba94e5bd74';
diff --git a/test/jest/Service.spec.ts b/test/jest/Service.spec.ts
index dc68f8469..28e000177 100644
--- a/test/jest/Service.spec.ts
+++ b/test/jest/Service.spec.ts
@@ -9,6 +9,7 @@ import SwapClient from '../../lib/swaps/SwapClient';
import SwapClientManager from '../../lib/swaps/SwapClientManager';
import Swaps from '../../lib/swaps/Swaps';
import NodeKey from '../../lib/nodekey/NodeKey';
+import Alerts from '../../lib/alerts/Alerts';
jest.mock('../../lib/nodekey/NodeKey');
const mockedNodeKey = >(NodeKey);
@@ -16,6 +17,8 @@ jest.mock('../../lib/orderbook/OrderBook');
const mockedOrderbook = >(Orderbook);
jest.mock('../../lib/swaps/Swaps');
const mockedSwaps = >(Swaps);
+jest.mock('../../lib/alerts/Alerts');
+const mockedAlerts = >(Alerts);
jest.mock('../../lib/swaps/SwapClientManager', () => {
return jest.fn().mockImplementation(() => {
return {
@@ -67,6 +70,7 @@ describe('Service', () => {
shutdown: jest.fn(),
nodeKey: new mockedNodeKey(),
logger: new mockedLogger(),
+ alerts: new mockedAlerts(),
};
peer = new mockedPeer();
components.pool.getPeer = jest.fn().mockReturnValue(peer);
diff --git a/test/jest/SwapClientManager.spec.ts b/test/jest/SwapClientManager.spec.ts
index dbd6e2a65..a6356acfc 100644
--- a/test/jest/SwapClientManager.spec.ts
+++ b/test/jest/SwapClientManager.spec.ts
@@ -70,6 +70,7 @@ const loggers = {
swaps: logger,
http: logger,
service: logger,
+ alerts: logger,
};
describe('Swaps.SwapClientManager', () => {
diff --git a/test/simulation/xudrpc/xudrpc.pb.go b/test/simulation/xudrpc/xudrpc.pb.go
index 6ac0fc977..b9e3276bc 100644
--- a/test/simulation/xudrpc/xudrpc.pb.go
+++ b/test/simulation/xudrpc/xudrpc.pb.go
@@ -119,6 +119,55 @@ func (LogLevel) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_6960a02cc0a63cf6, []int{2}
}
+// The type of the alert.
+type Alert_AlertType int32
+
+const (
+ Alert_LOW_TRADING_BALANCE Alert_AlertType = 0
+)
+
+var Alert_AlertType_name = map[int32]string{
+ 0: "LOW_TRADING_BALANCE",
+}
+
+var Alert_AlertType_value = map[string]int32{
+ "LOW_TRADING_BALANCE": 0,
+}
+
+func (x Alert_AlertType) String() string {
+ return proto.EnumName(Alert_AlertType_name, int32(x))
+}
+
+func (Alert_AlertType) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{3, 0}
+}
+
+// The side of the low balance.
+type BalanceAlert_Side int32
+
+const (
+ BalanceAlert_REMOTE BalanceAlert_Side = 0
+ BalanceAlert_LOCAL BalanceAlert_Side = 1
+)
+
+var BalanceAlert_Side_name = map[int32]string{
+ 0: "REMOTE",
+ 1: "LOCAL",
+}
+
+var BalanceAlert_Side_value = map[string]int32{
+ "REMOTE": 0,
+ "LOCAL": 1,
+}
+
+func (x BalanceAlert_Side) String() string {
+ return proto.EnumName(BalanceAlert_Side_name, int32(x))
+}
+
+func (BalanceAlert_Side) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{5, 0}
+}
+
type Currency_SwapClient int32
const (
@@ -141,7 +190,7 @@ func (x Currency_SwapClient) String() string {
}
func (Currency_SwapClient) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{16, 0}
+ return fileDescriptor_6960a02cc0a63cf6, []int{18, 0}
}
type ListOrdersRequest_Owner int32
@@ -169,7 +218,7 @@ func (x ListOrdersRequest_Owner) String() string {
}
func (ListOrdersRequest_Owner) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{32, 0}
+ return fileDescriptor_6960a02cc0a63cf6, []int{34, 0}
}
type AddCurrencyResponse struct {
@@ -283,6 +332,99 @@ func (m *AddPairResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_AddPairResponse proto.InternalMessageInfo
+type Alert struct {
+ Type Alert_AlertType `protobuf:"varint,1,opt,name=type,proto3,enum=xudrpc.Alert_AlertType" json:"type,omitempty"`
+ // The human readable alert message.
+ Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+ // The human readable alert message.
+ Date int64 `protobuf:"varint,3,opt,name=date,proto3" json:"date,omitempty"`
+ // The structured payload.
+ //
+ // Types that are valid to be assigned to Payload:
+ // *Alert_BalanceAlert
+ Payload isAlert_Payload `protobuf_oneof:"payload"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Alert) Reset() { *m = Alert{} }
+func (m *Alert) String() string { return proto.CompactTextString(m) }
+func (*Alert) ProtoMessage() {}
+func (*Alert) Descriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{3}
+}
+
+func (m *Alert) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_Alert.Unmarshal(m, b)
+}
+func (m *Alert) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_Alert.Marshal(b, m, deterministic)
+}
+func (m *Alert) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Alert.Merge(m, src)
+}
+func (m *Alert) XXX_Size() int {
+ return xxx_messageInfo_Alert.Size(m)
+}
+func (m *Alert) XXX_DiscardUnknown() {
+ xxx_messageInfo_Alert.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Alert proto.InternalMessageInfo
+
+func (m *Alert) GetType() Alert_AlertType {
+ if m != nil {
+ return m.Type
+ }
+ return Alert_LOW_TRADING_BALANCE
+}
+
+func (m *Alert) GetMessage() string {
+ if m != nil {
+ return m.Message
+ }
+ return ""
+}
+
+func (m *Alert) GetDate() int64 {
+ if m != nil {
+ return m.Date
+ }
+ return 0
+}
+
+type isAlert_Payload interface {
+ isAlert_Payload()
+}
+
+type Alert_BalanceAlert struct {
+ BalanceAlert *BalanceAlert `protobuf:"bytes,4,opt,name=balance_alert,proto3,oneof"`
+}
+
+func (*Alert_BalanceAlert) isAlert_Payload() {}
+
+func (m *Alert) GetPayload() isAlert_Payload {
+ if m != nil {
+ return m.Payload
+ }
+ return nil
+}
+
+func (m *Alert) GetBalanceAlert() *BalanceAlert {
+ if x, ok := m.GetPayload().(*Alert_BalanceAlert); ok {
+ return x.BalanceAlert
+ }
+ return nil
+}
+
+// XXX_OneofWrappers is for the internal use of the proto package.
+func (*Alert) XXX_OneofWrappers() []interface{} {
+ return []interface{}{
+ (*Alert_BalanceAlert)(nil),
+ }
+}
+
type Balance struct {
// Total balance denominated in satoshis.
TotalBalance uint64 `protobuf:"varint,1,opt,name=total_balance,proto3" json:"total_balance,omitempty"`
@@ -305,7 +447,7 @@ func (m *Balance) Reset() { *m = Balance{} }
func (m *Balance) String() string { return proto.CompactTextString(m) }
func (*Balance) ProtoMessage() {}
func (*Balance) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{3}
+ return fileDescriptor_6960a02cc0a63cf6, []int{4}
}
func (m *Balance) XXX_Unmarshal(b []byte) error {
@@ -368,6 +510,90 @@ func (m *Balance) GetUnconfirmedWalletBalance() uint64 {
return 0
}
+type BalanceAlert struct {
+ // The total balance.
+ TotalBalance uint64 `protobuf:"varint,1,opt,name=total_balance,proto3" json:"total_balance,omitempty"`
+ Side BalanceAlert_Side `protobuf:"varint,2,opt,name=side,proto3,enum=xudrpc.BalanceAlert_Side" json:"side,omitempty"`
+ // The bound of the low balance in percentage.
+ Bound uint32 `protobuf:"varint,3,opt,name=bound,proto3" json:"bound,omitempty"`
+ // The percent of the total trading balance.
+ Percent uint32 `protobuf:"varint,4,opt,name=percent,proto3" json:"percent,omitempty"`
+ // The balance in satoshis on this side of the channel
+ SideBalance uint64 `protobuf:"varint,5,opt,name=side_balance,proto3" json:"side_balance,omitempty"`
+ // The currency of the channel this alert is for.
+ Currency string `protobuf:"bytes,6,opt,name=currency,proto3" json:"currency,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *BalanceAlert) Reset() { *m = BalanceAlert{} }
+func (m *BalanceAlert) String() string { return proto.CompactTextString(m) }
+func (*BalanceAlert) ProtoMessage() {}
+func (*BalanceAlert) Descriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{5}
+}
+
+func (m *BalanceAlert) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_BalanceAlert.Unmarshal(m, b)
+}
+func (m *BalanceAlert) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_BalanceAlert.Marshal(b, m, deterministic)
+}
+func (m *BalanceAlert) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BalanceAlert.Merge(m, src)
+}
+func (m *BalanceAlert) XXX_Size() int {
+ return xxx_messageInfo_BalanceAlert.Size(m)
+}
+func (m *BalanceAlert) XXX_DiscardUnknown() {
+ xxx_messageInfo_BalanceAlert.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BalanceAlert proto.InternalMessageInfo
+
+func (m *BalanceAlert) GetTotalBalance() uint64 {
+ if m != nil {
+ return m.TotalBalance
+ }
+ return 0
+}
+
+func (m *BalanceAlert) GetSide() BalanceAlert_Side {
+ if m != nil {
+ return m.Side
+ }
+ return BalanceAlert_REMOTE
+}
+
+func (m *BalanceAlert) GetBound() uint32 {
+ if m != nil {
+ return m.Bound
+ }
+ return 0
+}
+
+func (m *BalanceAlert) GetPercent() uint32 {
+ if m != nil {
+ return m.Percent
+ }
+ return 0
+}
+
+func (m *BalanceAlert) GetSideBalance() uint64 {
+ if m != nil {
+ return m.SideBalance
+ }
+ return 0
+}
+
+func (m *BalanceAlert) GetCurrency() string {
+ if m != nil {
+ return m.Currency
+ }
+ return ""
+}
+
type BanRequest struct {
// The node pub key or alias of the node to ban.
NodeIdentifier string `protobuf:"bytes,1,opt,name=node_identifier,proto3" json:"node_identifier,omitempty"`
@@ -380,7 +606,7 @@ func (m *BanRequest) Reset() { *m = BanRequest{} }
func (m *BanRequest) String() string { return proto.CompactTextString(m) }
func (*BanRequest) ProtoMessage() {}
func (*BanRequest) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{4}
+ return fileDescriptor_6960a02cc0a63cf6, []int{6}
}
func (m *BanRequest) XXX_Unmarshal(b []byte) error {
@@ -418,7 +644,7 @@ func (m *BanResponse) Reset() { *m = BanResponse{} }
func (m *BanResponse) String() string { return proto.CompactTextString(m) }
func (*BanResponse) ProtoMessage() {}
func (*BanResponse) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{5}
+ return fileDescriptor_6960a02cc0a63cf6, []int{7}
}
func (m *BanResponse) XXX_Unmarshal(b []byte) error {
@@ -453,7 +679,7 @@ func (m *Chain) Reset() { *m = Chain{} }
func (m *Chain) String() string { return proto.CompactTextString(m) }
func (*Chain) ProtoMessage() {}
func (*Chain) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{6}
+ return fileDescriptor_6960a02cc0a63cf6, []int{8}
}
func (m *Chain) XXX_Unmarshal(b []byte) error {
@@ -506,7 +732,7 @@ func (m *Channels) Reset() { *m = Channels{} }
func (m *Channels) String() string { return proto.CompactTextString(m) }
func (*Channels) ProtoMessage() {}
func (*Channels) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{7}
+ return fileDescriptor_6960a02cc0a63cf6, []int{9}
}
func (m *Channels) XXX_Unmarshal(b []byte) error {
@@ -567,7 +793,7 @@ 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}
+ return fileDescriptor_6960a02cc0a63cf6, []int{10}
}
func (m *ChangePasswordRequest) XXX_Unmarshal(b []byte) error {
@@ -612,7 +838,7 @@ 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}
+ return fileDescriptor_6960a02cc0a63cf6, []int{11}
}
func (m *ChangePasswordResponse) XXX_Unmarshal(b []byte) error {
@@ -658,7 +884,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{10}
+ return fileDescriptor_6960a02cc0a63cf6, []int{12}
}
func (m *CloseChannelRequest) XXX_Unmarshal(b []byte) error {
@@ -733,7 +959,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{11}
+ return fileDescriptor_6960a02cc0a63cf6, []int{13}
}
func (m *CloseChannelResponse) XXX_Unmarshal(b []byte) error {
@@ -773,7 +999,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{12}
+ return fileDescriptor_6960a02cc0a63cf6, []int{14}
}
func (m *ConnectRequest) XXX_Unmarshal(b []byte) error {
@@ -811,7 +1037,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{13}
+ return fileDescriptor_6960a02cc0a63cf6, []int{15}
}
func (m *ConnectResponse) XXX_Unmarshal(b []byte) error {
@@ -845,7 +1071,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{14}
+ return fileDescriptor_6960a02cc0a63cf6, []int{16}
}
func (m *CreateNodeRequest) XXX_Unmarshal(b []byte) error {
@@ -889,7 +1115,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{15}
+ return fileDescriptor_6960a02cc0a63cf6, []int{17}
}
func (m *CreateNodeResponse) XXX_Unmarshal(b []byte) error {
@@ -953,7 +1179,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{16}
+ return fileDescriptor_6960a02cc0a63cf6, []int{18}
}
func (m *Currency) XXX_Unmarshal(b []byte) error {
@@ -1014,7 +1240,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{17}
+ return fileDescriptor_6960a02cc0a63cf6, []int{19}
}
func (m *DepositRequest) XXX_Unmarshal(b []byte) error {
@@ -1054,7 +1280,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{18}
+ return fileDescriptor_6960a02cc0a63cf6, []int{20}
}
func (m *DepositResponse) XXX_Unmarshal(b []byte) error {
@@ -1094,7 +1320,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{19}
+ return fileDescriptor_6960a02cc0a63cf6, []int{21}
}
func (m *DiscoverNodesRequest) XXX_Unmarshal(b []byte) error {
@@ -1133,7 +1359,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{20}
+ return fileDescriptor_6960a02cc0a63cf6, []int{22}
}
func (m *DiscoverNodesResponse) XXX_Unmarshal(b []byte) error {
@@ -1179,7 +1405,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{21}
+ return fileDescriptor_6960a02cc0a63cf6, []int{23}
}
func (m *ExecuteSwapRequest) XXX_Unmarshal(b []byte) error {
@@ -1241,7 +1467,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{22}
+ return fileDescriptor_6960a02cc0a63cf6, []int{24}
}
func (m *GetBalanceRequest) XXX_Unmarshal(b []byte) error {
@@ -1281,7 +1507,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{23}
+ return fileDescriptor_6960a02cc0a63cf6, []int{25}
}
func (m *GetBalanceResponse) XXX_Unmarshal(b []byte) error {
@@ -1319,7 +1545,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{24}
+ return fileDescriptor_6960a02cc0a63cf6, []int{26}
}
func (m *GetInfoRequest) XXX_Unmarshal(b []byte) error {
@@ -1369,7 +1595,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{25}
+ return fileDescriptor_6960a02cc0a63cf6, []int{27}
}
func (m *GetInfoResponse) XXX_Unmarshal(b []byte) error {
@@ -1477,7 +1703,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{26}
+ return fileDescriptor_6960a02cc0a63cf6, []int{28}
}
func (m *GetMnemonicRequest) XXX_Unmarshal(b []byte) error {
@@ -1509,7 +1735,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{27}
+ return fileDescriptor_6960a02cc0a63cf6, []int{29}
}
func (m *GetMnemonicResponse) XXX_Unmarshal(b []byte) error {
@@ -1549,7 +1775,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{28}
+ return fileDescriptor_6960a02cc0a63cf6, []int{30}
}
func (m *GetNodeInfoRequest) XXX_Unmarshal(b []byte) error {
@@ -1592,7 +1818,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{29}
+ return fileDescriptor_6960a02cc0a63cf6, []int{31}
}
func (m *GetNodeInfoResponse) XXX_Unmarshal(b []byte) error {
@@ -1637,7 +1863,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{30}
+ return fileDescriptor_6960a02cc0a63cf6, []int{32}
}
func (m *ListCurrenciesRequest) XXX_Unmarshal(b []byte) error {
@@ -1670,7 +1896,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{31}
+ return fileDescriptor_6960a02cc0a63cf6, []int{33}
}
func (m *ListCurrenciesResponse) XXX_Unmarshal(b []byte) error {
@@ -1716,7 +1942,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{32}
+ return fileDescriptor_6960a02cc0a63cf6, []int{34}
}
func (m *ListOrdersRequest) XXX_Unmarshal(b []byte) error {
@@ -1777,7 +2003,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{33}
+ return fileDescriptor_6960a02cc0a63cf6, []int{35}
}
func (m *ListOrdersResponse) XXX_Unmarshal(b []byte) error {
@@ -1815,7 +2041,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{34}
+ return fileDescriptor_6960a02cc0a63cf6, []int{36}
}
func (m *ListPairsRequest) XXX_Unmarshal(b []byte) error {
@@ -1848,7 +2074,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{35}
+ return fileDescriptor_6960a02cc0a63cf6, []int{37}
}
func (m *ListPairsResponse) XXX_Unmarshal(b []byte) error {
@@ -1886,7 +2112,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{36}
+ return fileDescriptor_6960a02cc0a63cf6, []int{38}
}
func (m *ListPeersRequest) XXX_Unmarshal(b []byte) error {
@@ -1919,7 +2145,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{37}
+ return fileDescriptor_6960a02cc0a63cf6, []int{39}
}
func (m *ListPeersResponse) XXX_Unmarshal(b []byte) error {
@@ -1964,7 +2190,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{38}
+ return fileDescriptor_6960a02cc0a63cf6, []int{40}
}
func (m *LndInfo) XXX_Unmarshal(b []byte) error {
@@ -2048,7 +2274,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{39}
+ return fileDescriptor_6960a02cc0a63cf6, []int{41}
}
func (m *NodeIdentifier) XXX_Unmarshal(b []byte) error {
@@ -2103,7 +2329,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{40}
+ return fileDescriptor_6960a02cc0a63cf6, []int{42}
}
func (m *OpenChannelRequest) XXX_Unmarshal(b []byte) error {
@@ -2171,7 +2397,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{41}
+ return fileDescriptor_6960a02cc0a63cf6, []int{43}
}
func (m *OpenChannelResponse) XXX_Unmarshal(b []byte) error {
@@ -2229,7 +2455,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{42}
+ return fileDescriptor_6960a02cc0a63cf6, []int{44}
}
func (m *Order) XXX_Unmarshal(b []byte) error {
@@ -2340,7 +2566,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{43}
+ return fileDescriptor_6960a02cc0a63cf6, []int{45}
}
func (m *OrderRemoval) XXX_Unmarshal(b []byte) error {
@@ -2410,7 +2636,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{44}
+ return fileDescriptor_6960a02cc0a63cf6, []int{46}
}
func (m *Orders) XXX_Unmarshal(b []byte) error {
@@ -2459,7 +2685,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{45}
+ return fileDescriptor_6960a02cc0a63cf6, []int{47}
}
func (m *OrdersCount) XXX_Unmarshal(b []byte) error {
@@ -2508,7 +2734,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{46}
+ return fileDescriptor_6960a02cc0a63cf6, []int{48}
}
func (m *OrderUpdate) XXX_Unmarshal(b []byte) error {
@@ -2603,7 +2829,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{47}
+ return fileDescriptor_6960a02cc0a63cf6, []int{49}
}
func (m *Peer) XXX_Unmarshal(b []byte) error {
@@ -2707,7 +2933,7 @@ func (m *Peer_LndUris) Reset() { *m = Peer_LndUris{} }
func (m *Peer_LndUris) String() string { return proto.CompactTextString(m) }
func (*Peer_LndUris) ProtoMessage() {}
func (*Peer_LndUris) Descriptor() ([]byte, []int) {
- return fileDescriptor_6960a02cc0a63cf6, []int{47, 1}
+ return fileDescriptor_6960a02cc0a63cf6, []int{49, 1}
}
func (m *Peer_LndUris) XXX_Unmarshal(b []byte) error {
@@ -2767,7 +2993,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{48}
+ return fileDescriptor_6960a02cc0a63cf6, []int{50}
}
func (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {
@@ -2855,7 +3081,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{49}
+ return fileDescriptor_6960a02cc0a63cf6, []int{51}
}
func (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {
@@ -2920,7 +3146,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{50}
+ return fileDescriptor_6960a02cc0a63cf6, []int{52}
}
func (m *PlaceOrderEvent) XXX_Unmarshal(b []byte) error {
@@ -3028,7 +3254,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{51}
+ return fileDescriptor_6960a02cc0a63cf6, []int{53}
}
func (m *ConnextInfo) XXX_Unmarshal(b []byte) error {
@@ -3089,7 +3315,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{52}
+ return fileDescriptor_6960a02cc0a63cf6, []int{54}
}
func (m *RemoveCurrencyRequest) XXX_Unmarshal(b []byte) error {
@@ -3127,7 +3353,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{53}
+ return fileDescriptor_6960a02cc0a63cf6, []int{55}
}
func (m *RemoveCurrencyResponse) XXX_Unmarshal(b []byte) error {
@@ -3163,7 +3389,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{54}
+ return fileDescriptor_6960a02cc0a63cf6, []int{56}
}
func (m *RemoveOrderRequest) XXX_Unmarshal(b []byte) error {
@@ -3217,7 +3443,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{55}
+ return fileDescriptor_6960a02cc0a63cf6, []int{57}
}
func (m *RemoveOrderResponse) XXX_Unmarshal(b []byte) error {
@@ -3276,7 +3502,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{56}
+ return fileDescriptor_6960a02cc0a63cf6, []int{58}
}
func (m *RemoveAllOrdersRequest) XXX_Unmarshal(b []byte) error {
@@ -3311,7 +3537,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{57}
+ return fileDescriptor_6960a02cc0a63cf6, []int{59}
}
func (m *RemoveAllOrdersResponse) XXX_Unmarshal(b []byte) error {
@@ -3358,7 +3584,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{58}
+ return fileDescriptor_6960a02cc0a63cf6, []int{60}
}
func (m *RemovePairRequest) XXX_Unmarshal(b []byte) error {
@@ -3396,7 +3622,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{59}
+ return fileDescriptor_6960a02cc0a63cf6, []int{61}
}
func (m *RemovePairResponse) XXX_Unmarshal(b []byte) error {
@@ -3436,7 +3662,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{60}
+ return fileDescriptor_6960a02cc0a63cf6, []int{62}
}
func (m *RestoreNodeRequest) XXX_Unmarshal(b []byte) error {
@@ -3499,7 +3725,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{61}
+ return fileDescriptor_6960a02cc0a63cf6, []int{63}
}
func (m *RestoreNodeResponse) XXX_Unmarshal(b []byte) error {
@@ -3545,7 +3771,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{62}
+ return fileDescriptor_6960a02cc0a63cf6, []int{64}
}
func (m *SetLogLevelRequest) XXX_Unmarshal(b []byte) error {
@@ -3583,7 +3809,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{63}
+ return fileDescriptor_6960a02cc0a63cf6, []int{65}
}
func (m *SetLogLevelResponse) XXX_Unmarshal(b []byte) error {
@@ -3614,7 +3840,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{64}
+ return fileDescriptor_6960a02cc0a63cf6, []int{66}
}
func (m *ShutdownRequest) XXX_Unmarshal(b []byte) error {
@@ -3645,7 +3871,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{65}
+ return fileDescriptor_6960a02cc0a63cf6, []int{67}
}
func (m *ShutdownResponse) XXX_Unmarshal(b []byte) error {
@@ -3678,7 +3904,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{66}
+ return fileDescriptor_6960a02cc0a63cf6, []int{68}
}
func (m *SubscribeOrdersRequest) XXX_Unmarshal(b []byte) error {
@@ -3706,6 +3932,37 @@ func (m *SubscribeOrdersRequest) GetExisting() bool {
return false
}
+type SubscribeAlertsRequest struct {
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *SubscribeAlertsRequest) Reset() { *m = SubscribeAlertsRequest{} }
+func (m *SubscribeAlertsRequest) String() string { return proto.CompactTextString(m) }
+func (*SubscribeAlertsRequest) ProtoMessage() {}
+func (*SubscribeAlertsRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_6960a02cc0a63cf6, []int{69}
+}
+
+func (m *SubscribeAlertsRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_SubscribeAlertsRequest.Unmarshal(m, b)
+}
+func (m *SubscribeAlertsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_SubscribeAlertsRequest.Marshal(b, m, deterministic)
+}
+func (m *SubscribeAlertsRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_SubscribeAlertsRequest.Merge(m, src)
+}
+func (m *SubscribeAlertsRequest) XXX_Size() int {
+ return xxx_messageInfo_SubscribeAlertsRequest.Size(m)
+}
+func (m *SubscribeAlertsRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_SubscribeAlertsRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SubscribeAlertsRequest proto.InternalMessageInfo
+
type SubscribeSwapsAcceptedRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@@ -3716,7 +3973,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{67}
+ return fileDescriptor_6960a02cc0a63cf6, []int{70}
}
func (m *SubscribeSwapsAcceptedRequest) XXX_Unmarshal(b []byte) error {
@@ -3750,7 +4007,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{68}
+ return fileDescriptor_6960a02cc0a63cf6, []int{71}
}
func (m *SubscribeSwapsRequest) XXX_Unmarshal(b []byte) error {
@@ -3810,7 +4067,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{69}
+ return fileDescriptor_6960a02cc0a63cf6, []int{72}
}
func (m *SwapAccepted) XXX_Unmarshal(b []byte) error {
@@ -3928,7 +4185,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{70}
+ return fileDescriptor_6960a02cc0a63cf6, []int{73}
}
func (m *SwapFailure) XXX_Unmarshal(b []byte) error {
@@ -4020,7 +4277,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{71}
+ return fileDescriptor_6960a02cc0a63cf6, []int{74}
}
func (m *SwapSuccess) XXX_Unmarshal(b []byte) error {
@@ -4164,7 +4421,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{72}
+ return fileDescriptor_6960a02cc0a63cf6, []int{75}
}
func (m *Trade) XXX_Unmarshal(b []byte) error {
@@ -4267,7 +4524,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{73}
+ return fileDescriptor_6960a02cc0a63cf6, []int{76}
}
func (m *TradeHistoryRequest) XXX_Unmarshal(b []byte) error {
@@ -4306,7 +4563,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{74}
+ return fileDescriptor_6960a02cc0a63cf6, []int{77}
}
func (m *TradeHistoryResponse) XXX_Unmarshal(b []byte) error {
@@ -4352,7 +4609,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{75}
+ return fileDescriptor_6960a02cc0a63cf6, []int{78}
}
func (m *TradingLimits) XXX_Unmarshal(b []byte) error {
@@ -4414,7 +4671,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{76}
+ return fileDescriptor_6960a02cc0a63cf6, []int{79}
}
func (m *TradingLimitsRequest) XXX_Unmarshal(b []byte) error {
@@ -4454,7 +4711,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{77}
+ return fileDescriptor_6960a02cc0a63cf6, []int{80}
}
func (m *TradingLimitsResponse) XXX_Unmarshal(b []byte) error {
@@ -4496,7 +4753,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{78}
+ return fileDescriptor_6960a02cc0a63cf6, []int{81}
}
func (m *UnbanRequest) XXX_Unmarshal(b []byte) error {
@@ -4541,7 +4798,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{79}
+ return fileDescriptor_6960a02cc0a63cf6, []int{82}
}
func (m *UnbanResponse) XXX_Unmarshal(b []byte) error {
@@ -4575,7 +4832,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{80}
+ return fileDescriptor_6960a02cc0a63cf6, []int{83}
}
func (m *UnlockNodeRequest) XXX_Unmarshal(b []byte) error {
@@ -4617,7 +4874,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{81}
+ return fileDescriptor_6960a02cc0a63cf6, []int{84}
}
func (m *UnlockNodeResponse) XXX_Unmarshal(b []byte) error {
@@ -4673,7 +4930,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{82}
+ return fileDescriptor_6960a02cc0a63cf6, []int{85}
}
func (m *WithdrawRequest) XXX_Unmarshal(b []byte) error {
@@ -4741,7 +4998,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{83}
+ return fileDescriptor_6960a02cc0a63cf6, []int{86}
}
func (m *WithdrawResponse) XXX_Unmarshal(b []byte) error {
@@ -4773,12 +5030,16 @@ func init() {
proto.RegisterEnum("xudrpc.OrderSide", OrderSide_name, OrderSide_value)
proto.RegisterEnum("xudrpc.Role", Role_name, Role_value)
proto.RegisterEnum("xudrpc.LogLevel", LogLevel_name, LogLevel_value)
+ proto.RegisterEnum("xudrpc.Alert_AlertType", Alert_AlertType_name, Alert_AlertType_value)
+ proto.RegisterEnum("xudrpc.BalanceAlert_Side", BalanceAlert_Side_name, BalanceAlert_Side_value)
proto.RegisterEnum("xudrpc.Currency_SwapClient", Currency_SwapClient_name, Currency_SwapClient_value)
proto.RegisterEnum("xudrpc.ListOrdersRequest_Owner", ListOrdersRequest_Owner_name, ListOrdersRequest_Owner_value)
proto.RegisterType((*AddCurrencyResponse)(nil), "xudrpc.AddCurrencyResponse")
proto.RegisterType((*AddPairRequest)(nil), "xudrpc.AddPairRequest")
proto.RegisterType((*AddPairResponse)(nil), "xudrpc.AddPairResponse")
+ proto.RegisterType((*Alert)(nil), "xudrpc.Alert")
proto.RegisterType((*Balance)(nil), "xudrpc.Balance")
+ proto.RegisterType((*BalanceAlert)(nil), "xudrpc.BalanceAlert")
proto.RegisterType((*BanRequest)(nil), "xudrpc.BanRequest")
proto.RegisterType((*BanResponse)(nil), "xudrpc.BanResponse")
proto.RegisterType((*Chain)(nil), "xudrpc.Chain")
@@ -4848,6 +5109,7 @@ func init() {
proto.RegisterType((*ShutdownRequest)(nil), "xudrpc.ShutdownRequest")
proto.RegisterType((*ShutdownResponse)(nil), "xudrpc.ShutdownResponse")
proto.RegisterType((*SubscribeOrdersRequest)(nil), "xudrpc.SubscribeOrdersRequest")
+ proto.RegisterType((*SubscribeAlertsRequest)(nil), "xudrpc.SubscribeAlertsRequest")
proto.RegisterType((*SubscribeSwapsAcceptedRequest)(nil), "xudrpc.SubscribeSwapsAcceptedRequest")
proto.RegisterType((*SubscribeSwapsRequest)(nil), "xudrpc.SubscribeSwapsRequest")
proto.RegisterType((*SwapAccepted)(nil), "xudrpc.SwapAccepted")
@@ -4871,271 +5133,286 @@ func init() {
func init() { proto.RegisterFile("xudrpc.proto", fileDescriptor_6960a02cc0a63cf6) }
var fileDescriptor_6960a02cc0a63cf6 = []byte{
- // 4221 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x3b, 0x4d, 0x8f, 0x1c, 0x49,
- 0x56, 0x9d, 0x55, 0x5d, 0xdd, 0xd5, 0xaf, 0x3e, 0xba, 0x3a, 0xfa, 0xc3, 0x35, 0x35, 0x9e, 0x19,
- 0x6f, 0x30, 0x1e, 0x79, 0x3c, 0x33, 0xb6, 0xf1, 0xb0, 0xcc, 0x8e, 0x17, 0x8f, 0xa6, 0xbb, 0xdd,
- 0x3b, 0xf6, 0x4c, 0xaf, 0x6d, 0x65, 0xdb, 0x63, 0xb3, 0x82, 0x4d, 0x65, 0x65, 0x86, 0xbb, 0x13,
- 0x67, 0x67, 0xd6, 0x64, 0x66, 0xb9, 0x6d, 0xb8, 0xa0, 0x15, 0x27, 0x38, 0x70, 0x40, 0x9c, 0xe1,
- 0x84, 0x90, 0x58, 0x71, 0xe5, 0x84, 0xc4, 0x99, 0x2b, 0x07, 0x24, 0xc4, 0x05, 0x89, 0x5f, 0x80,
- 0x10, 0x37, 0x24, 0xf4, 0xe2, 0x23, 0x23, 0x22, 0x33, 0xab, 0xd7, 0x1e, 0x01, 0xb7, 0x8a, 0x17,
- 0x2f, 0xdf, 0x8b, 0x78, 0x5f, 0xf1, 0xde, 0x8b, 0x28, 0xe8, 0xbf, 0x9c, 0x87, 0xd9, 0x2c, 0xb8,
- 0x36, 0xcb, 0xd2, 0x22, 0x25, 0x2b, 0x62, 0x34, 0xd9, 0xf0, 0x93, 0x24, 0x2d, 0xfc, 0x22, 0x4a,
- 0x93, 0x5c, 0x4c, 0xd1, 0x6d, 0xd8, 0xdc, 0x0d, 0xc3, 0xfd, 0x79, 0x96, 0xb1, 0x24, 0x78, 0xe5,
- 0xb2, 0x7c, 0x96, 0x26, 0x39, 0xa3, 0x3f, 0x87, 0xe1, 0x6e, 0x18, 0x3e, 0xf4, 0xa3, 0xcc, 0x65,
- 0xdf, 0xcd, 0x59, 0x5e, 0x90, 0xf7, 0x61, 0x30, 0xf5, 0x73, 0xe6, 0x05, 0x12, 0x75, 0xec, 0x5c,
- 0x72, 0xae, 0xac, 0xb9, 0x36, 0x90, 0x7c, 0x00, 0xc3, 0xef, 0xe6, 0x69, 0x61, 0xa0, 0xb5, 0x38,
- 0x5a, 0x05, 0x4a, 0x37, 0x60, 0xbd, 0xa4, 0x2f, 0x59, 0xfe, 0x5d, 0x0b, 0x56, 0xf7, 0xfc, 0xd8,
- 0x4f, 0x02, 0x86, 0xcc, 0x8a, 0xb4, 0xf0, 0x63, 0x6f, 0x2a, 0x00, 0x9c, 0xd9, 0xb2, 0x6b, 0x03,
- 0xc9, 0x15, 0x58, 0x0f, 0x4e, 0xfc, 0x24, 0x61, 0x1a, 0xaf, 0xc5, 0xf1, 0xaa, 0x60, 0xf2, 0x23,
- 0xb8, 0x30, 0x63, 0x49, 0x18, 0x25, 0xc7, 0x5e, 0xf5, 0x8b, 0x36, 0xff, 0x62, 0xd1, 0x34, 0xb9,
- 0x05, 0xe3, 0x28, 0xf1, 0x83, 0x22, 0x7a, 0xc1, 0x6a, 0x9f, 0x2e, 0xf3, 0x4f, 0x17, 0xce, 0xa3,
- 0x30, 0xce, 0xfc, 0x38, 0x66, 0x45, 0xf9, 0x45, 0x87, 0x7f, 0x51, 0x81, 0x92, 0x2f, 0x60, 0x32,
- 0x4f, 0x82, 0x34, 0x79, 0x16, 0x65, 0xa7, 0x2c, 0xf4, 0x2a, 0xdf, 0xac, 0xf0, 0x6f, 0xce, 0xc1,
- 0xa0, 0xbf, 0x09, 0xb0, 0xe7, 0x27, 0x4a, 0x51, 0x57, 0x60, 0x3d, 0x49, 0x43, 0xe6, 0x45, 0x21,
- 0x4b, 0x8a, 0xe8, 0x59, 0xc4, 0x32, 0xa9, 0xaa, 0x2a, 0x98, 0x0e, 0xa0, 0xc7, 0xbf, 0x93, 0x0a,
- 0xf8, 0x0c, 0x3a, 0xfb, 0x27, 0x7e, 0x94, 0x90, 0x2d, 0xe8, 0x04, 0xf8, 0x43, 0x7e, 0x27, 0x06,
- 0x64, 0x0c, 0xab, 0x09, 0x2b, 0xce, 0xd2, 0xec, 0xb9, 0xd4, 0xa9, 0x1a, 0xd2, 0x19, 0x74, 0xf7,
- 0xc5, 0xd6, 0x73, 0xb2, 0x03, 0x2b, 0x42, 0x1a, 0xfc, 0xe3, 0x81, 0x2b, 0x47, 0x64, 0x02, 0x5d,
- 0x25, 0x27, 0xfe, 0xf9, 0xc0, 0x2d, 0xc7, 0x48, 0x59, 0x8a, 0x9f, 0x6b, 0x63, 0xe0, 0xaa, 0x21,
- 0x52, 0x0b, 0xe2, 0x34, 0x67, 0x21, 0x97, 0xf5, 0xc0, 0x95, 0x23, 0xea, 0xc1, 0x36, 0x72, 0x3c,
- 0x66, 0x0f, 0xfd, 0x3c, 0x3f, 0x4b, 0xb3, 0x50, 0x6d, 0x9e, 0x42, 0x3f, 0x61, 0x67, 0xde, 0x4c,
- 0x82, 0xe5, 0x0e, 0x2c, 0x18, 0xe2, 0xa4, 0x71, 0xa8, 0x71, 0xc4, 0x6e, 0x2c, 0x18, 0x1d, 0xc3,
- 0x4e, 0x95, 0x81, 0x94, 0xd2, 0xdf, 0x3b, 0xb0, 0xb9, 0x8f, 0xab, 0x90, 0x5b, 0x7e, 0x63, 0xb1,
- 0xa3, 0x28, 0x2a, 0xde, 0x51, 0x8e, 0x51, 0xf4, 0xcf, 0xd2, 0x4c, 0x9a, 0x65, 0xd7, 0x15, 0x03,
- 0x72, 0x09, 0x7a, 0x21, 0xcb, 0x8b, 0x28, 0xe1, 0xae, 0xcb, 0x65, 0xb1, 0xe6, 0x9a, 0x20, 0x2e,
- 0xf6, 0xd3, 0x74, 0x9e, 0x14, 0xd2, 0xc4, 0xe4, 0x88, 0x8c, 0xa0, 0xfd, 0x8c, 0x29, 0x1b, 0xc2,
- 0x9f, 0xf4, 0x4b, 0xd8, 0xb2, 0x97, 0x2f, 0xf6, 0x85, 0xeb, 0x2f, 0x32, 0x3f, 0xc9, 0x51, 0x27,
- 0x69, 0xe2, 0x45, 0x61, 0x3e, 0x76, 0x2e, 0xb5, 0x71, 0xfd, 0x15, 0x30, 0xfd, 0x18, 0x86, 0xfb,
- 0x69, 0x92, 0xb0, 0xa0, 0x50, 0x7b, 0x9f, 0x40, 0x97, 0x6f, 0x72, 0x9e, 0x45, 0x72, 0xd3, 0xe5,
- 0x18, 0x3d, 0xbd, 0xc4, 0x96, 0x22, 0xbc, 0x0e, 0x1b, 0xfb, 0x19, 0xf3, 0x0b, 0x76, 0x3f, 0x0d,
- 0x99, 0x41, 0xa3, 0xa2, 0xb5, 0x72, 0x4c, 0xff, 0xdc, 0x01, 0x62, 0x7e, 0x21, 0x97, 0xfc, 0x6b,
- 0x30, 0xc8, 0x19, 0x0b, 0xbd, 0xd3, 0x84, 0x9d, 0xa6, 0x49, 0x14, 0xc8, 0x05, 0xf7, 0x11, 0xf8,
- 0x53, 0x09, 0x23, 0x1f, 0xc2, 0x28, 0x4a, 0xa2, 0x22, 0xf2, 0xe3, 0xe8, 0xf7, 0x59, 0xe8, 0xc5,
- 0x49, 0x98, 0x8f, 0x5b, 0x62, 0x63, 0x06, 0xfc, 0x30, 0x09, 0x73, 0x72, 0x1d, 0x36, 0x4d, 0xd4,
- 0x00, 0x97, 0xfd, 0xb2, 0x90, 0xaa, 0x20, 0xc6, 0xd4, 0xbe, 0x98, 0xa1, 0xff, 0xec, 0x40, 0x57,
- 0x85, 0x4e, 0x4b, 0xad, 0x4e, 0x45, 0xad, 0xb7, 0xa1, 0x97, 0x9f, 0xf9, 0x33, 0x2f, 0x88, 0x23,
- 0x96, 0x14, 0x5c, 0xeb, 0xc3, 0x9b, 0x6f, 0x5f, 0x93, 0x41, 0x5a, 0x91, 0xb8, 0x76, 0x74, 0xe6,
- 0xcf, 0xf6, 0x39, 0x8a, 0x6b, 0xe2, 0x8b, 0x70, 0xf8, 0x9c, 0x25, 0x9e, 0x1f, 0x86, 0x19, 0xcb,
- 0x73, 0xbe, 0xa4, 0x35, 0xd7, 0x06, 0x62, 0xb8, 0x09, 0x59, 0x10, 0x9d, 0xfa, 0xb1, 0x37, 0x8b,
- 0xfd, 0x80, 0xe5, 0xd2, 0x69, 0x2a, 0x50, 0x4a, 0x01, 0x34, 0x23, 0xb2, 0x0a, 0xed, 0xc3, 0xfb,
- 0x77, 0x46, 0x4b, 0xa4, 0x07, 0xab, 0xfb, 0x0f, 0xee, 0xdf, 0x3f, 0x78, 0xfa, 0x68, 0xd4, 0x42,
- 0x1d, 0xdf, 0x61, 0xb3, 0x34, 0x8f, 0x4c, 0x1d, 0x2f, 0xda, 0x1e, 0xfd, 0x08, 0xd6, 0x4b, 0x6c,
- 0xa9, 0x9b, 0x31, 0xac, 0xaa, 0xc5, 0x0a, 0x6c, 0x35, 0x44, 0x03, 0xbc, 0x13, 0xe5, 0x41, 0xfa,
- 0x82, 0x65, 0xa8, 0xcd, 0xfc, 0xcd, 0xe3, 0xd6, 0x0f, 0x61, 0xbb, 0x42, 0x41, 0x32, 0xbd, 0x08,
- 0x6b, 0xc9, 0xfc, 0xd4, 0x43, 0xfc, 0x5c, 0xc6, 0x1f, 0x0d, 0xa0, 0x7f, 0xec, 0x00, 0x39, 0x78,
- 0xc9, 0x82, 0x79, 0xc1, 0x70, 0xff, 0xc6, 0xc6, 0xd2, 0x2c, 0x64, 0x99, 0x17, 0x95, 0x86, 0xa7,
- 0xc6, 0x3c, 0x32, 0xf9, 0x11, 0x9f, 0x92, 0x31, 0x4f, 0x0e, 0x31, 0x88, 0xcc, 0x18, 0xcb, 0xbc,
- 0xd9, 0x7c, 0xea, 0x3d, 0x67, 0xaf, 0xa4, 0x46, 0x2c, 0x18, 0x52, 0xfe, 0x6e, 0xee, 0x27, 0x45,
- 0x54, 0xbc, 0x92, 0x67, 0x45, 0x39, 0x46, 0x1f, 0xf8, 0x8a, 0x15, 0xf2, 0xbc, 0x7b, 0x1d, 0x19,
- 0xff, 0xb5, 0x03, 0xc4, 0xfc, 0x42, 0x6e, 0xf9, 0x0e, 0x74, 0xe5, 0x31, 0x20, 0xfc, 0xb5, 0x77,
- 0xf3, 0x8a, 0x32, 0xab, 0x3a, 0xf6, 0x35, 0x39, 0xce, 0x0f, 0x92, 0x22, 0x7b, 0xe5, 0x96, 0x5f,
- 0x4e, 0x0e, 0x61, 0x60, 0x4d, 0x61, 0xdc, 0xc0, 0x5d, 0x89, 0x45, 0xe0, 0x4f, 0x72, 0x19, 0x3a,
- 0x2f, 0xfc, 0x78, 0x2e, 0xa2, 0x77, 0xef, 0xe6, 0xba, 0xe2, 0xa2, 0x58, 0x88, 0xd9, 0x5b, 0xad,
- 0x1f, 0x39, 0x74, 0x04, 0xc3, 0xaf, 0x58, 0x71, 0x2f, 0x79, 0x96, 0xca, 0x8d, 0xd1, 0x7f, 0x69,
- 0xc3, 0x7a, 0x09, 0xd2, 0x16, 0xf2, 0x82, 0x65, 0x39, 0x06, 0x34, 0x69, 0x21, 0x72, 0xc8, 0x83,
- 0x38, 0xaa, 0x5c, 0xc9, 0x56, 0x06, 0x68, 0x13, 0x46, 0x08, 0x2c, 0xcf, 0xb3, 0x08, 0x3d, 0x01,
- 0x5d, 0x99, 0xff, 0x56, 0xea, 0x47, 0x1d, 0x28, 0xdb, 0xd7, 0x80, 0x72, 0xd6, 0x8f, 0xb2, 0x9c,
- 0x47, 0x49, 0x35, 0x8b, 0x00, 0xf2, 0x11, 0xac, 0x70, 0xad, 0xe7, 0x3c, 0x56, 0xf6, 0x6e, 0x6e,
- 0xaa, 0xfd, 0x3d, 0xe0, 0xd0, 0x7d, 0x8c, 0xa6, 0xae, 0x44, 0x21, 0x37, 0xa1, 0x1d, 0x27, 0xe1,
- 0x78, 0x95, 0xcb, 0xfb, 0x92, 0x21, 0x6f, 0x73, 0x83, 0xd7, 0x0e, 0x93, 0x50, 0xc8, 0x19, 0x91,
- 0x31, 0xb2, 0xfb, 0x71, 0xe4, 0xe7, 0xe3, 0x35, 0x71, 0xa8, 0xf2, 0x81, 0x79, 0xa8, 0x82, 0x75,
- 0xa8, 0x92, 0x1b, 0xb0, 0xa9, 0x72, 0x12, 0x1e, 0x0a, 0x4e, 0xfc, 0xfc, 0x84, 0xe5, 0xe3, 0x1e,
- 0xdf, 0x6f, 0xd3, 0x14, 0xf9, 0x04, 0x56, 0x55, 0xc8, 0xea, 0xdb, 0x7b, 0x90, 0xf1, 0x8a, 0xaf,
- 0x4e, 0xe1, 0x4c, 0xbe, 0x82, 0xae, 0x5a, 0xe1, 0x1b, 0xa8, 0xfb, 0x30, 0x09, 0x39, 0x19, 0x43,
- 0xdd, 0x5b, 0xdc, 0x30, 0x55, 0xc0, 0x55, 0x2a, 0xff, 0x31, 0x6c, 0x5a, 0x50, 0xa9, 0xf5, 0xf7,
- 0x9b, 0x63, 0xb6, 0x0d, 0xa4, 0x5f, 0x70, 0x92, 0xe8, 0xdc, 0x86, 0x15, 0xbd, 0x41, 0x84, 0x70,
- 0x39, 0x73, 0xfd, 0x7d, 0x79, 0x60, 0xac, 0x67, 0x6c, 0x36, 0x17, 0x19, 0xf0, 0x51, 0x90, 0x66,
- 0x22, 0x4b, 0xd9, 0x70, 0x41, 0x83, 0xf1, 0x28, 0x9d, 0xe2, 0xd1, 0x28, 0x5c, 0xbe, 0xeb, 0xca,
- 0x11, 0xbd, 0x00, 0xdb, 0x87, 0x51, 0x5e, 0xc8, 0x60, 0x1d, 0x95, 0x81, 0x8b, 0x7e, 0x0d, 0x3b,
- 0xd5, 0x09, 0xc9, 0xef, 0x06, 0x40, 0x50, 0x42, 0xa5, 0x7b, 0x8e, 0xaa, 0x51, 0xdf, 0x35, 0x70,
- 0xe8, 0x3f, 0x3a, 0xb0, 0x81, 0xc4, 0x84, 0xd5, 0xa9, 0x8d, 0x1b, 0x61, 0xc8, 0xb1, 0xc3, 0xd0,
- 0x0f, 0xa1, 0x93, 0x9e, 0x25, 0x2c, 0x93, 0x47, 0xca, 0x7b, 0xa5, 0x9a, 0xaa, 0x34, 0xae, 0x3d,
- 0x40, 0x34, 0x57, 0x60, 0xa3, 0x31, 0xc6, 0xd1, 0x69, 0x54, 0xc8, 0x7c, 0x4b, 0x0c, 0x50, 0xbe,
- 0x51, 0x12, 0xc4, 0xf3, 0x90, 0x79, 0xdc, 0x3a, 0xe5, 0x09, 0xd2, 0x75, 0xab, 0x60, 0xfa, 0x3e,
- 0x74, 0x38, 0x3d, 0xd2, 0x85, 0xe5, 0xbd, 0x07, 0x8f, 0xee, 0x8e, 0x96, 0xf0, 0x1c, 0x79, 0xf0,
- 0xe4, 0xfe, 0xc8, 0x41, 0xd0, 0xc3, 0x83, 0x03, 0x77, 0xd4, 0xa2, 0x7f, 0xe1, 0x00, 0x31, 0x17,
- 0x22, 0xa5, 0xf2, 0x45, 0xe9, 0x6a, 0x42, 0x22, 0x1f, 0x34, 0x2d, 0x5a, 0xfa, 0x90, 0x18, 0x0a,
- 0x37, 0x92, 0x5f, 0x4d, 0xee, 0x41, 0xcf, 0x00, 0x37, 0xd8, 0xee, 0xfb, 0xb6, 0xed, 0x0e, 0x6d,
- 0x57, 0x36, 0x4d, 0x97, 0xc0, 0x08, 0x99, 0x62, 0x1d, 0x52, 0xaa, 0xf3, 0x43, 0xa1, 0x01, 0x09,
- 0x93, 0x6b, 0xde, 0x82, 0x8e, 0x08, 0x1c, 0xc2, 0x5c, 0xc5, 0xa0, 0xfc, 0x9c, 0x69, 0x39, 0xd3,
- 0xcf, 0xe4, 0xe7, 0xcc, 0xdc, 0x32, 0x85, 0x8e, 0x88, 0x4a, 0x62, 0xc7, 0x7d, 0xb5, 0x22, 0xc4,
- 0x72, 0xc5, 0x14, 0xfd, 0x57, 0x07, 0x56, 0xa5, 0x77, 0xa1, 0x0d, 0xe6, 0x85, 0x5f, 0xcc, 0xd5,
- 0xe1, 0x29, 0x47, 0xe4, 0x63, 0xe8, 0xca, 0x22, 0x23, 0x97, 0x9b, 0xd3, 0xe6, 0x24, 0xe1, 0x6e,
- 0x89, 0x41, 0x2e, 0xc3, 0x0a, 0x4f, 0xdd, 0x45, 0x94, 0xec, 0xdd, 0x1c, 0x18, 0xb8, 0x51, 0xe2,
- 0xca, 0x49, 0xcc, 0x2e, 0xa7, 0x71, 0x1a, 0x3c, 0x3f, 0x61, 0xd1, 0xf1, 0x49, 0x21, 0x03, 0xa7,
- 0x09, 0x2a, 0x83, 0x6d, 0xc7, 0x08, 0xb6, 0x46, 0xf8, 0x5e, 0xb1, 0xc3, 0x77, 0x19, 0xe9, 0x56,
- 0x8d, 0x48, 0x47, 0xbf, 0x86, 0x21, 0xf7, 0x47, 0x9d, 0x07, 0x57, 0xc3, 0xbc, 0xd3, 0x10, 0xe6,
- 0x4b, 0x5a, 0x2d, 0x93, 0xd6, 0x5f, 0x39, 0x40, 0x1e, 0xcc, 0x58, 0xf2, 0x7f, 0x92, 0x82, 0xeb,
- 0x54, 0xba, 0x6d, 0xa5, 0xd2, 0x97, 0xa0, 0x37, 0x9b, 0xe7, 0x27, 0x9e, 0x9c, 0x14, 0x07, 0xba,
- 0x09, 0x52, 0xc9, 0x76, 0x47, 0x27, 0xdb, 0xb7, 0x61, 0xd3, 0x5a, 0xa7, 0x34, 0x87, 0x0f, 0x60,
- 0x68, 0x27, 0xd5, 0x72, 0x9d, 0x15, 0x28, 0xfd, 0x87, 0x16, 0x74, 0xb8, 0xd1, 0x72, 0xfb, 0xcb,
- 0x22, 0x59, 0x08, 0x3b, 0xae, 0x18, 0x58, 0x09, 0x46, 0xcb, 0x4e, 0x30, 0xcc, 0x98, 0xd1, 0xb6,
- 0x63, 0xc6, 0x10, 0x5a, 0x51, 0x28, 0x8b, 0x88, 0x56, 0x14, 0x92, 0x2f, 0xeb, 0x62, 0xeb, 0x70,
- 0xdb, 0xda, 0x51, 0xf6, 0x62, 0x2b, 0xae, 0x51, 0x9c, 0x71, 0x1a, 0xf8, 0x31, 0x32, 0x13, 0xc6,
- 0x50, 0x8e, 0xc9, 0xbb, 0x00, 0x01, 0x4f, 0xdd, 0x43, 0xcf, 0x2f, 0xb8, 0x49, 0x2c, 0xbb, 0x06,
- 0x84, 0x5c, 0x86, 0xe5, 0x3c, 0x0a, 0xd9, 0xb8, 0xcb, 0x03, 0xd8, 0x86, 0xe5, 0xab, 0x47, 0x51,
- 0xc8, 0x5c, 0x3e, 0x8d, 0xc6, 0x12, 0xe5, 0x5e, 0x7a, 0x96, 0x78, 0x3c, 0x0a, 0xf0, 0x53, 0xb4,
- 0xeb, 0x5a, 0x30, 0x34, 0xd3, 0x93, 0x34, 0x0e, 0xf9, 0x49, 0xba, 0xec, 0xf2, 0xdf, 0xf4, 0x2f,
- 0x1d, 0xe8, 0x73, 0x5a, 0x2e, 0x3b, 0x4d, 0x5f, 0xf8, 0xb1, 0x25, 0x33, 0x67, 0xb1, 0xcc, 0x2a,
- 0xe9, 0x9e, 0x99, 0x24, 0xb6, 0x2b, 0x49, 0xa2, 0xb9, 0xfb, 0xe5, 0xca, 0xee, 0xab, 0xcb, 0xee,
- 0xd4, 0x97, 0x4d, 0x4f, 0x60, 0x45, 0x44, 0x26, 0xf2, 0x09, 0xc0, 0x74, 0xfe, 0xca, 0xb3, 0xa2,
- 0xe3, 0xc0, 0x92, 0x88, 0x6b, 0x20, 0x90, 0xeb, 0xd0, 0xcb, 0x59, 0x1c, 0x2b, 0xfc, 0x56, 0x13,
- 0xbe, 0x89, 0x41, 0x3f, 0x55, 0x91, 0x93, 0xa7, 0x33, 0x28, 0x2f, 0x0c, 0x3d, 0x32, 0x53, 0xe6,
- 0xbf, 0xd1, 0x86, 0xd3, 0xb3, 0x44, 0x96, 0xe8, 0xf8, 0x93, 0xfe, 0xc2, 0x91, 0x5f, 0x3d, 0x9e,
- 0x85, 0x7e, 0xc1, 0x30, 0x33, 0x10, 0x7b, 0x71, 0xb8, 0x91, 0xd8, 0xfc, 0xee, 0x2e, 0xb9, 0x62,
- 0x96, 0xfc, 0x16, 0x0c, 0x84, 0x84, 0x32, 0x21, 0x78, 0x19, 0xaf, 0xb6, 0xec, 0xe5, 0x89, 0xb9,
- 0xbb, 0x4b, 0xae, 0x8d, 0xbc, 0x37, 0x84, 0xbe, 0x00, 0xcc, 0x39, 0x53, 0xfa, 0x5f, 0x6d, 0x58,
- 0xc6, 0x60, 0xb9, 0xb8, 0xae, 0x78, 0xad, 0xac, 0xf1, 0x4b, 0xe8, 0xc7, 0x49, 0xa8, 0x86, 0x2a,
- 0x2e, 0x5e, 0x34, 0xc3, 0x31, 0x66, 0x38, 0x0f, 0xe7, 0xd3, 0x6f, 0xd8, 0x2b, 0x79, 0xec, 0x58,
- 0x5f, 0x20, 0xff, 0x28, 0x99, 0xa6, 0xf3, 0x24, 0x94, 0x67, 0xa3, 0x1a, 0xea, 0x23, 0xa2, 0x63,
- 0x1c, 0x11, 0x18, 0x35, 0x5e, 0xce, 0x43, 0xcf, 0x0e, 0x95, 0x26, 0x88, 0x7c, 0x0c, 0x1b, 0x39,
- 0x0b, 0xd2, 0x24, 0xcc, 0x45, 0xc5, 0x19, 0x14, 0x2c, 0xe4, 0x7e, 0x32, 0x70, 0xeb, 0x13, 0x0b,
- 0xd2, 0xc8, 0x1b, 0xd0, 0xc5, 0x55, 0xf2, 0x20, 0x0d, 0x7c, 0x4f, 0x5b, 0xd5, 0x3d, 0x3d, 0xce,
- 0xa2, 0xdc, 0x2d, 0xb1, 0xc8, 0x35, 0x20, 0x32, 0x11, 0x34, 0xfd, 0xbe, 0xc7, 0x89, 0x36, 0xcc,
- 0x4c, 0x6e, 0xc3, 0x7a, 0x45, 0x30, 0x0d, 0x07, 0xef, 0x96, 0x79, 0xf0, 0xae, 0x19, 0x07, 0xed,
- 0xe4, 0x33, 0x7e, 0xb6, 0xe1, 0x1a, 0xce, 0xad, 0x93, 0x47, 0xd0, 0x9e, 0x67, 0x91, 0xac, 0xcf,
- 0xf1, 0x27, 0xfd, 0xc3, 0x16, 0x6c, 0x3c, 0xc4, 0xba, 0x55, 0xda, 0x8b, 0x88, 0xf4, 0xff, 0x9b,
- 0xe1, 0xd0, 0x74, 0xed, 0xe5, 0x8a, 0x6b, 0xab, 0xe0, 0xd4, 0x39, 0x3f, 0x38, 0x5d, 0x85, 0x51,
- 0xc6, 0x78, 0x75, 0xed, 0x95, 0xa4, 0x84, 0xa6, 0x6b, 0x70, 0xcc, 0xeb, 0xa3, 0xd3, 0x53, 0x16,
- 0x46, 0x7e, 0x81, 0x50, 0x2f, 0xc0, 0xea, 0x29, 0xe6, 0x0a, 0xef, 0xba, 0x4d, 0x53, 0x28, 0x02,
- 0x62, 0x8a, 0x40, 0x1e, 0x22, 0x9f, 0xc3, 0x28, 0x4a, 0x0a, 0x96, 0x25, 0x7e, 0xec, 0x9d, 0xfa,
- 0x45, 0x70, 0xc2, 0x16, 0x84, 0x8c, 0x1a, 0x1a, 0xf9, 0x31, 0x0c, 0x79, 0xe1, 0x90, 0xcf, 0x83,
- 0x80, 0xe5, 0x98, 0xe7, 0x89, 0xd8, 0x51, 0x16, 0x0c, 0x58, 0x1f, 0x1f, 0x89, 0x49, 0xb7, 0x82,
- 0x4a, 0x3e, 0xc3, 0x24, 0xfa, 0xd4, 0x8f, 0x12, 0xac, 0x3f, 0x44, 0x24, 0x68, 0x37, 0x44, 0x02,
- 0xb7, 0x8a, 0x45, 0x3e, 0x87, 0x01, 0x27, 0xf5, 0xcc, 0x8f, 0xe2, 0x79, 0xc6, 0x93, 0xcb, 0x1a,
- 0xd3, 0x9f, 0x88, 0x39, 0xd7, 0xc6, 0xa4, 0xff, 0xe1, 0xc0, 0xba, 0x16, 0xc1, 0xc1, 0x0b, 0x96,
- 0xe0, 0xc1, 0xd1, 0xe1, 0xfb, 0x59, 0x18, 0x87, 0xf8, 0x2c, 0xf9, 0x1c, 0xfa, 0xe6, 0x06, 0x64,
- 0x18, 0x6a, 0xda, 0xe9, 0xdd, 0x25, 0xd7, 0x42, 0x25, 0x9f, 0xbf, 0xde, 0x4e, 0xef, 0x2e, 0x35,
- 0xed, 0xb5, 0x6f, 0xee, 0x80, 0x1b, 0x56, 0xf3, 0x56, 0x4b, 0xae, 0x12, 0x75, 0x6f, 0x15, 0x3a,
- 0x0c, 0x37, 0x48, 0x53, 0xe8, 0x19, 0x85, 0xdb, 0xc2, 0x9c, 0xd0, 0x88, 0x88, 0x2d, 0x3b, 0x22,
- 0x1a, 0x29, 0xda, 0x72, 0x2d, 0x45, 0x13, 0x1d, 0xde, 0x8e, 0xd1, 0xe1, 0xa5, 0x9f, 0xc2, 0x36,
- 0x0f, 0xc8, 0x4c, 0x5f, 0x07, 0xfc, 0xea, 0xbe, 0xc4, 0x18, 0x76, 0xaa, 0x1f, 0xc9, 0x36, 0xdf,
- 0x21, 0x10, 0x31, 0x63, 0xb9, 0xee, 0x79, 0xed, 0x96, 0x73, 0x1c, 0x98, 0xfe, 0x8d, 0x03, 0x9b,
- 0x16, 0x39, 0xe9, 0x06, 0xef, 0xc2, 0x48, 0xe1, 0x78, 0x69, 0xe2, 0xf1, 0x04, 0xc0, 0xd1, 0x09,
- 0x00, 0x06, 0x3a, 0xad, 0x9c, 0x0a, 0xf5, 0x86, 0x19, 0xe1, 0xcb, 0xc8, 0x26, 0xd4, 0xd8, 0x22,
- 0x11, 0xac, 0xc1, 0xcd, 0xa0, 0xb2, 0x6c, 0x05, 0x15, 0x2d, 0x95, 0xdd, 0x38, 0xb6, 0xea, 0x30,
- 0x3a, 0x87, 0x0b, 0xb5, 0x19, 0xb9, 0x95, 0x8f, 0x61, 0x43, 0xb1, 0x50, 0x22, 0x51, 0x05, 0x47,
- 0x7d, 0x02, 0xb1, 0xe5, 0x7e, 0x0d, 0x6c, 0x11, 0x39, 0xeb, 0x13, 0xf4, 0x13, 0xd8, 0x10, 0x6c,
- 0xcd, 0x3b, 0x9d, 0x85, 0x75, 0x25, 0xd6, 0xf4, 0x26, 0xba, 0xd4, 0xe8, 0x1f, 0xb5, 0x10, 0x9c,
- 0x17, 0x69, 0x66, 0xb5, 0x6e, 0x5f, 0xab, 0x0f, 0x6b, 0xf6, 0x77, 0x5b, 0x76, 0x7f, 0x97, 0x7c,
- 0x03, 0x3d, 0x3c, 0x98, 0xa6, 0x7e, 0xf0, 0x7c, 0x3e, 0x53, 0xa7, 0xf2, 0x55, 0xe5, 0x2c, 0x75,
- 0x8e, 0x78, 0x9e, 0xed, 0x09, 0x64, 0x71, 0x46, 0x43, 0x5c, 0x02, 0xc8, 0x0f, 0xf8, 0xe5, 0x97,
- 0x17, 0xfa, 0x85, 0x3f, 0xf5, 0x73, 0xd1, 0xfb, 0xee, 0xf3, 0x23, 0xf7, 0x8e, 0x04, 0xc9, 0xc3,
- 0xcc, 0xa4, 0xf0, 0xab, 0x0e, 0xb3, 0xbe, 0x59, 0x35, 0x32, 0xb4, 0x44, 0x63, 0x4d, 0xba, 0x1d,
- 0x9d, 0x09, 0xb0, 0x6c, 0x33, 0x4b, 0x31, 0x28, 0x20, 0xef, 0x31, 0x7f, 0x88, 0xe6, 0x25, 0x91,
- 0x54, 0xb7, 0x46, 0xf4, 0x19, 0xd6, 0x15, 0x5c, 0x75, 0x97, 0xef, 0x00, 0x39, 0x62, 0xc5, 0x61,
- 0x7a, 0x7c, 0xc8, 0x5e, 0xe8, 0x22, 0xe7, 0x1a, 0xac, 0xc5, 0xe9, 0xb1, 0x17, 0x23, 0x8c, 0x2f,
- 0x77, 0xa8, 0x6b, 0xc0, 0x12, 0x57, 0xa3, 0xd0, 0x6d, 0xd8, 0xb4, 0xa8, 0x48, 0x55, 0x6e, 0xc0,
- 0xfa, 0xd1, 0xc9, 0xbc, 0x08, 0xd3, 0x33, 0x75, 0x71, 0x84, 0xd5, 0xac, 0x06, 0x49, 0xb4, 0xdf,
- 0x80, 0x9d, 0xa3, 0xf9, 0x34, 0x0f, 0xb2, 0x68, 0xca, 0xec, 0x9e, 0xc4, 0x04, 0xba, 0xec, 0x65,
- 0x94, 0x17, 0x51, 0x72, 0xcc, 0x97, 0xd1, 0x75, 0xcb, 0x31, 0x7d, 0x0f, 0xde, 0x29, 0xbf, 0xc2,
- 0x50, 0x97, 0xef, 0x06, 0x01, 0x9b, 0x15, 0x4c, 0x5d, 0xd3, 0xd0, 0xdb, 0xb0, 0x6d, 0x23, 0x18,
- 0xb7, 0x8c, 0xaa, 0xd7, 0x50, 0xf8, 0xcf, 0x65, 0x92, 0xd9, 0x75, 0x6d, 0x20, 0xfd, 0xef, 0x16,
- 0xf4, 0xf1, 0x33, 0x45, 0x96, 0xbc, 0x55, 0x0b, 0x2a, 0xab, 0x7c, 0x7c, 0xcf, 0xce, 0xce, 0x5b,
- 0x95, 0xec, 0xfc, 0xdc, 0xa4, 0x60, 0x51, 0xeb, 0x56, 0x27, 0x1f, 0x1d, 0x33, 0xf9, 0xa8, 0x36,
- 0x84, 0x57, 0x1a, 0x1a, 0xc2, 0x3b, 0xb0, 0x92, 0xf1, 0x6e, 0x9d, 0x2c, 0x8d, 0xe5, 0x08, 0x63,
- 0x8e, 0x28, 0x21, 0xbd, 0x8c, 0x05, 0x2c, 0x7a, 0x81, 0x32, 0xed, 0x8a, 0x98, 0x53, 0x85, 0x63,
- 0xed, 0x28, 0x61, 0xb9, 0xbc, 0x33, 0x5b, 0x13, 0x97, 0x8a, 0x36, 0x94, 0x27, 0x78, 0x32, 0x22,
- 0x1b, 0x54, 0x41, 0x26, 0x78, 0xb5, 0x19, 0x5c, 0x43, 0x09, 0x55, 0x94, 0x45, 0x3a, 0x58, 0x83,
- 0x63, 0x2c, 0xee, 0x19, 0x47, 0xd8, 0xf7, 0x6c, 0xa1, 0x9b, 0x32, 0x6e, 0x57, 0x64, 0x5c, 0x95,
- 0xe6, 0x72, 0x83, 0x34, 0x3f, 0x80, 0xa1, 0x3c, 0x33, 0xbd, 0x8c, 0xf9, 0x79, 0xaa, 0x4e, 0xb3,
- 0x0a, 0x94, 0xfe, 0x6d, 0x5b, 0xac, 0x56, 0x1e, 0xf3, 0xff, 0xbf, 0xc6, 0xa2, 0x55, 0xde, 0xb1,
- 0x54, 0x7e, 0x05, 0xd6, 0x2d, 0xd5, 0xb2, 0x50, 0x6a, 0xbc, 0x0a, 0xc6, 0x0a, 0x42, 0xab, 0xb6,
- 0x90, 0xda, 0x36, 0x41, 0x35, 0x61, 0x41, 0x83, 0xb0, 0x2e, 0xc1, 0x72, 0x96, 0xc6, 0x8c, 0xab,
- 0x74, 0xa8, 0x1b, 0x50, 0x6e, 0x1a, 0x33, 0x97, 0xcf, 0xe0, 0x79, 0x52, 0x31, 0x0b, 0x16, 0xf2,
- 0x46, 0xf2, 0x9a, 0x5b, 0x9f, 0x40, 0x47, 0x35, 0xcd, 0xa2, 0x18, 0x0f, 0xc4, 0x95, 0x94, 0x05,
- 0xc4, 0xe2, 0x3f, 0xf3, 0x66, 0x19, 0x8b, 0x4e, 0xfd, 0x63, 0x36, 0x1e, 0x72, 0x14, 0x03, 0xa2,
- 0x5d, 0x69, 0xdd, 0x70, 0x25, 0xfa, 0x9f, 0x2d, 0xe8, 0x3c, 0xca, 0xfc, 0x90, 0x61, 0x85, 0x7b,
- 0x8a, 0x1e, 0xef, 0x2d, 0xae, 0x38, 0x5d, 0x13, 0x03, 0x3f, 0x28, 0x8c, 0x0f, 0x5a, 0x8d, 0x1f,
- 0x18, 0x18, 0x86, 0x7e, 0xda, 0x96, 0x7e, 0xce, 0xd3, 0xa9, 0x61, 0x09, 0x1d, 0xdb, 0x12, 0xca,
- 0xfd, 0xac, 0x98, 0xa1, 0x41, 0xc9, 0x7e, 0x75, 0xa1, 0xec, 0x2f, 0x41, 0x8f, 0x89, 0x9b, 0x29,
- 0xde, 0x25, 0x11, 0x96, 0x60, 0x82, 0xca, 0x4a, 0x64, 0xed, 0xfc, 0x4a, 0xe4, 0x16, 0xf4, 0x03,
- 0x34, 0x0c, 0x96, 0xcd, 0xfc, 0xac, 0x10, 0xa6, 0xb0, 0xb8, 0x91, 0x63, 0xe1, 0xd2, 0x8f, 0x60,
- 0x93, 0x4b, 0xfd, 0x6e, 0x84, 0xe7, 0xd0, 0x2b, 0xa3, 0xd6, 0x12, 0xbd, 0x62, 0xc7, 0xe8, 0x15,
- 0xd3, 0xdb, 0xb0, 0x65, 0x23, 0xcb, 0x43, 0xf0, 0x32, 0xac, 0x14, 0x08, 0xaf, 0xd5, 0x22, 0x1c,
- 0xdb, 0x95, 0x93, 0xf4, 0x4f, 0x1d, 0x18, 0x20, 0x24, 0x4a, 0x8e, 0x0f, 0x91, 0x1e, 0x2f, 0x0b,
- 0x4f, 0xfd, 0x97, 0x5e, 0xce, 0xe2, 0x58, 0xf5, 0x65, 0xd4, 0x18, 0x05, 0x8e, 0xbf, 0xa7, 0x73,
- 0x95, 0xb8, 0xa9, 0x21, 0x9a, 0x61, 0xc6, 0x72, 0x96, 0x61, 0x6a, 0xc4, 0x3f, 0x15, 0x81, 0xc4,
- 0x06, 0xa2, 0x83, 0x94, 0x00, 0x24, 0x22, 0x14, 0x6a, 0xc1, 0xe8, 0x4d, 0xb1, 0xa1, 0x72, 0x41,
- 0xaf, 0x93, 0xfb, 0xfe, 0xd2, 0x81, 0xed, 0xca, 0x47, 0x52, 0x0c, 0xbb, 0xb0, 0xc2, 0xe5, 0xa4,
- 0xc4, 0xf0, 0xa1, 0x29, 0x86, 0x1a, 0xfa, 0x35, 0x31, 0x94, 0x6d, 0x6e, 0xf1, 0xe1, 0xe4, 0x21,
- 0xf4, 0x0c, 0x70, 0x43, 0x82, 0xf2, 0x91, 0xdd, 0xe6, 0xde, 0x6e, 0x66, 0x61, 0xe4, 0x2d, 0xdf,
- 0x42, 0xff, 0x71, 0x32, 0xfd, 0x1e, 0x2f, 0x45, 0xc8, 0x45, 0x58, 0xcb, 0x98, 0x6c, 0x42, 0xc8,
- 0x74, 0x45, 0x03, 0xe8, 0x3a, 0x0c, 0x24, 0x5d, 0x7d, 0xc1, 0xff, 0x38, 0x89, 0xd3, 0xe0, 0xf9,
- 0xeb, 0x5e, 0xf0, 0xff, 0x0c, 0x88, 0xf9, 0x81, 0x4e, 0xa8, 0xe6, 0x1c, 0x5a, 0x49, 0xa8, 0x14,
- 0x90, 0x27, 0x54, 0xef, 0x41, 0xcf, 0x44, 0x11, 0xf7, 0x81, 0xa0, 0x11, 0xe8, 0x9f, 0x38, 0xb0,
- 0xfe, 0x24, 0x2a, 0x4e, 0xc2, 0xcc, 0x3f, 0x7b, 0x0d, 0xa5, 0x56, 0x1f, 0x5b, 0xb4, 0xce, 0x7b,
- 0x6c, 0xd1, 0xae, 0x3e, 0xb6, 0xf0, 0xe3, 0x58, 0xf6, 0x85, 0xf0, 0xa7, 0xd9, 0x11, 0x1e, 0x88,
- 0x8e, 0xf0, 0x2d, 0x18, 0xe9, 0xc5, 0xbc, 0x59, 0x3b, 0xf8, 0xea, 0x15, 0x58, 0x2b, 0xfd, 0x9d,
- 0xac, 0x42, 0x7b, 0xef, 0xf1, 0x6f, 0x8f, 0x96, 0x48, 0x17, 0x96, 0x8f, 0x0e, 0x0e, 0x0f, 0xc5,
- 0xcd, 0x0b, 0xbf, 0x8c, 0x69, 0x5d, 0xbd, 0x0a, 0xcb, 0x18, 0x5d, 0xc8, 0x1a, 0x74, 0x1e, 0xed,
- 0x7e, 0x73, 0xe0, 0x8e, 0x96, 0xf0, 0xe7, 0x4f, 0xf9, 0x4f, 0x87, 0xf4, 0xa1, 0x7b, 0xef, 0xfe,
- 0xa3, 0x03, 0xf7, 0xfe, 0xee, 0xe1, 0xa8, 0x75, 0xf5, 0x09, 0x74, 0x55, 0x76, 0x88, 0x48, 0xbb,
- 0x87, 0x07, 0xee, 0x23, 0x81, 0x7f, 0xe0, 0xba, 0x0f, 0x5c, 0x41, 0xf7, 0xc9, 0xae, 0x7b, 0x7f,
- 0xd4, 0xc2, 0x5f, 0xf7, 0xee, 0xff, 0xe4, 0xc1, 0xa8, 0x4d, 0x7a, 0xb0, 0xfa, 0xed, 0x81, 0xbb,
- 0xf7, 0xe0, 0xe8, 0x60, 0xb4, 0x8c, 0xb8, 0x77, 0x0e, 0xf6, 0x1e, 0x7f, 0x35, 0xea, 0x70, 0x8e,
- 0xee, 0xee, 0xfe, 0xc1, 0x68, 0xe5, 0xe6, 0xbf, 0x39, 0xb0, 0xfa, 0x74, 0x1e, 0xde, 0x4b, 0xa2,
- 0x82, 0x1c, 0x00, 0xe8, 0x07, 0x1c, 0xe4, 0xad, 0xf2, 0x22, 0xa2, 0xfa, 0x0c, 0x64, 0x32, 0x69,
- 0x9a, 0x92, 0x66, 0xb5, 0x44, 0xee, 0x42, 0xcf, 0xc8, 0xbc, 0xc9, 0x64, 0x71, 0x89, 0x30, 0x79,
- 0xbb, 0x71, 0xae, 0xa4, 0x74, 0x00, 0xa0, 0x2d, 0x4e, 0x2f, 0xa8, 0x66, 0xb6, 0x7a, 0x41, 0x75,
- 0x03, 0xa5, 0x4b, 0x37, 0x7f, 0x39, 0x81, 0xf6, 0xd3, 0x79, 0x48, 0x9e, 0x42, 0xcf, 0x78, 0x46,
- 0x47, 0x6a, 0x97, 0x7c, 0x7a, 0x39, 0x4d, 0xaf, 0xed, 0x26, 0xbf, 0xf8, 0xa7, 0x7f, 0xff, 0xb3,
- 0xd6, 0x16, 0x5d, 0xbf, 0xfe, 0xe2, 0xd7, 0xaf, 0xfb, 0x61, 0xa8, 0x6c, 0xf1, 0x96, 0x73, 0x95,
- 0xb8, 0xb0, 0x2a, 0x5f, 0xca, 0x91, 0x1d, 0x83, 0x86, 0x51, 0xc6, 0x4d, 0x2e, 0xd4, 0xe0, 0x92,
- 0xee, 0x0e, 0xa7, 0x3b, 0xa2, 0x3d, 0x49, 0x17, 0x8f, 0x29, 0xa4, 0xb9, 0x07, 0xed, 0x3d, 0x3f,
- 0x21, 0x44, 0xdf, 0xe1, 0xab, 0x98, 0x30, 0xd9, 0xb4, 0x60, 0x92, 0x0e, 0xe1, 0x74, 0xfa, 0x74,
- 0x15, 0xe9, 0x4c, 0xfd, 0x04, 0x69, 0x1c, 0xc3, 0xd0, 0x7e, 0x21, 0x45, 0xde, 0x31, 0xaf, 0xa2,
- 0x6a, 0x4f, 0xb3, 0x26, 0xef, 0x2e, 0x9a, 0xae, 0x2c, 0x76, 0x88, 0x4c, 0x02, 0x8e, 0x83, 0xf1,
- 0x81, 0x04, 0xd0, 0x37, 0x1f, 0x2c, 0x11, 0xfd, 0x6c, 0xa6, 0xfe, 0x0a, 0x6b, 0x72, 0xb1, 0x79,
- 0x52, 0xb2, 0x18, 0x73, 0x16, 0x84, 0x8e, 0x38, 0x0b, 0xc4, 0x90, 0x77, 0x65, 0x28, 0x65, 0xf9,
- 0x4a, 0x49, 0x4b, 0xd9, 0x7e, 0xe4, 0xa4, 0xa5, 0x5c, 0x7d, 0xce, 0x64, 0x49, 0x59, 0xc6, 0x44,
- 0x94, 0xd0, 0xcf, 0x61, 0xf0, 0x84, 0x3f, 0xd4, 0x93, 0x6f, 0x63, 0x34, 0x65, 0xfb, 0x69, 0x8d,
- 0xa6, 0x5c, 0x79, 0x44, 0x43, 0x2f, 0x72, 0xca, 0x3b, 0x74, 0x03, 0x29, 0x8b, 0x47, 0x7f, 0xa1,
- 0x40, 0x91, 0x96, 0xf1, 0xbd, 0x29, 0x5b, 0x6b, 0x36, 0x68, 0xfe, 0x1e, 0x0c, 0xac, 0xa7, 0x35,
- 0xa4, 0x14, 0x68, 0xd3, 0x9b, 0x9d, 0xc9, 0x3b, 0x0b, 0x66, 0x9b, 0xd6, 0x1f, 0x4a, 0x14, 0xfe,
- 0x18, 0x07, 0x79, 0x3d, 0x05, 0xd0, 0x4f, 0x54, 0xb4, 0x0b, 0xd6, 0x9e, 0xc5, 0x68, 0x17, 0xac,
- 0xbf, 0x68, 0xa1, 0x9b, 0x9c, 0xc5, 0x80, 0xf4, 0x84, 0x69, 0x0a, 0x5a, 0x87, 0xb0, 0x2a, 0x1f,
- 0x63, 0x68, 0xc9, 0xd8, 0x2f, 0x52, 0xb4, 0x64, 0x2a, 0xaf, 0x36, 0xe8, 0x88, 0x13, 0x04, 0xd2,
- 0x45, 0x82, 0x11, 0x92, 0xf8, 0x1d, 0xe8, 0x19, 0x2f, 0x19, 0x88, 0xb9, 0x9a, 0xca, 0xa3, 0x07,
- 0xed, 0xe5, 0x0d, 0x4f, 0x1f, 0xe8, 0x16, 0xa7, 0x3c, 0x24, 0x7d, 0xa4, 0xac, 0x7a, 0x25, 0x92,
- 0xba, 0x7a, 0xaa, 0x60, 0x51, 0xaf, 0xbc, 0x7f, 0xb0, 0xa8, 0x57, 0xdf, 0x36, 0xd8, 0xd4, 0x51,
- 0xc6, 0x7c, 0xed, 0x4f, 0x00, 0xf4, 0xad, 0xba, 0x96, 0x71, 0xed, 0x79, 0x80, 0x96, 0x71, 0xfd,
- 0x12, 0x5e, 0xb9, 0x3f, 0x01, 0x24, 0x2d, 0xef, 0x9e, 0x8e, 0x61, 0x68, 0x3f, 0x7a, 0xd0, 0xee,
- 0xdf, 0xf8, 0x4a, 0x42, 0xbb, 0x7f, 0xf3, 0x5b, 0x09, 0x65, 0x91, 0x44, 0xb8, 0xbf, 0x26, 0x7b,
- 0x04, 0x6b, 0xe5, 0x75, 0x3c, 0x19, 0x9b, 0x44, 0xcc, 0x5b, 0xfb, 0xc9, 0x5b, 0x0d, 0x33, 0xaa,
- 0xd5, 0xc1, 0x29, 0xf7, 0xc8, 0x1a, 0x52, 0x16, 0xb7, 0x32, 0x8a, 0x28, 0x7f, 0x18, 0x64, 0x13,
- 0x35, 0xee, 0xf2, 0x2b, 0x44, 0xcd, 0x1b, 0xfd, 0x0a, 0x51, 0x4e, 0xc7, 0x83, 0x9e, 0x71, 0xd9,
- 0xab, 0x35, 0x59, 0xbf, 0xa9, 0xd6, 0x9a, 0x6c, 0xb8, 0x1d, 0xa6, 0x17, 0x38, 0xe9, 0x0d, 0x71,
- 0x1a, 0xa4, 0x33, 0x96, 0xa8, 0x20, 0xf5, 0xbb, 0x00, 0xba, 0x09, 0xae, 0x95, 0x59, 0xbb, 0x1e,
- 0xd1, 0xc6, 0x5d, 0xe9, 0x99, 0xd3, 0xb7, 0x38, 0xe9, 0x4d, 0x11, 0x63, 0xf9, 0xc5, 0x04, 0x57,
- 0xe7, 0x2d, 0xe7, 0xea, 0x0d, 0x87, 0x3c, 0x83, 0xa1, 0xc6, 0x3f, 0x7a, 0x95, 0x04, 0xe7, 0xb1,
- 0x98, 0x34, 0x4d, 0xc9, 0x0d, 0xbc, 0xc3, 0xb9, 0x5c, 0xa0, 0xc4, 0xe6, 0x92, 0xbf, 0x4a, 0x02,
- 0xf4, 0xfb, 0x9f, 0x41, 0xcf, 0x78, 0x86, 0xa7, 0xe5, 0x54, 0x7f, 0x9b, 0x37, 0x69, 0x6a, 0xd3,
- 0xdb, 0xa7, 0xa5, 0xac, 0x91, 0xf2, 0x33, 0x7f, 0x86, 0xb4, 0x13, 0x18, 0xda, 0xdd, 0x68, 0x6d,
- 0x96, 0x8d, 0xad, 0x6d, 0x6d, 0x96, 0x0b, 0x9a, 0xd8, 0xd6, 0x5e, 0x44, 0x13, 0xd6, 0x3c, 0x9d,
- 0xa7, 0x98, 0x90, 0x94, 0x4d, 0x69, 0x33, 0x21, 0xa9, 0x36, 0xbe, 0xcd, 0x84, 0xa4, 0xd6, 0xc5,
- 0xb6, 0xf7, 0x24, 0xd8, 0x28, 0xcd, 0x90, 0x0c, 0xd6, 0x2b, 0x1d, 0x63, 0x52, 0x59, 0x75, 0xb5,
- 0xc9, 0x3c, 0x79, 0x6f, 0xe1, 0xbc, 0xe4, 0xf7, 0x2e, 0xe7, 0x37, 0xa6, 0x9b, 0x9a, 0x9f, 0x1f,
- 0xc7, 0x42, 0x4d, 0xe2, 0xec, 0x02, 0xdd, 0xff, 0xd5, 0x76, 0x50, 0x6b, 0x21, 0x4f, 0x26, 0x4d,
- 0x53, 0x92, 0x89, 0x65, 0x6d, 0x82, 0x89, 0xca, 0x40, 0xa6, 0xd0, 0x33, 0xba, 0x92, 0x5a, 0x6e,
- 0xf5, 0x86, 0xa7, 0x96, 0x5b, 0x53, 0x1b, 0xd3, 0x92, 0x5b, 0xce, 0x8a, 0x38, 0x3d, 0xe6, 0x6d,
- 0x4f, 0xe4, 0xf1, 0x2d, 0x74, 0x55, 0x3f, 0x93, 0x94, 0x1e, 0x51, 0x69, 0x7a, 0x4e, 0xc6, 0xf5,
- 0x89, 0x8a, 0x1b, 0xf2, 0x80, 0x9a, 0xcb, 0x59, 0xa4, 0xcb, 0x60, 0xbd, 0xd2, 0x13, 0xd5, 0xfa,
- 0x68, 0x6e, 0x96, 0x4e, 0xec, 0xd7, 0x84, 0xe2, 0x22, 0x9d, 0xbe, 0xcd, 0x19, 0x6c, 0x13, 0xae,
- 0x83, 0x5c, 0x7d, 0x28, 0x74, 0x70, 0xc3, 0x21, 0xb3, 0x4a, 0x8f, 0x54, 0x36, 0xdb, 0x8c, 0x40,
- 0xdb, 0xd8, 0x42, 0x9d, 0x34, 0x5d, 0x32, 0xd1, 0x1f, 0x70, 0x5e, 0x6f, 0x93, 0xb7, 0x2c, 0x5e,
- 0xe8, 0x35, 0xea, 0x8e, 0xed, 0x86, 0x43, 0xa6, 0x30, 0xb4, 0x49, 0xbe, 0x11, 0xab, 0x8a, 0x7b,
- 0x12, 0x52, 0x63, 0x85, 0x3c, 0xfe, 0xc0, 0x68, 0x28, 0x5b, 0xad, 0x61, 0x72, 0xb9, 0x99, 0x57,
- 0xa5, 0x75, 0x3c, 0xd9, 0x32, 0x79, 0xaa, 0x49, 0x4a, 0x39, 0xd3, 0x8b, 0x64, 0x52, 0x67, 0xea,
- 0x4b, 0x1c, 0x1e, 0xe1, 0xfa, 0x66, 0xd3, 0x42, 0xa7, 0x92, 0x0d, 0x7d, 0x0f, 0x9d, 0x4a, 0x36,
- 0xf5, 0x39, 0x94, 0xf2, 0x44, 0x2a, 0xc9, 0x9b, 0x1a, 0x27, 0x02, 0x43, 0xe4, 0xc6, 0x95, 0xe6,
- 0xc6, 0xc5, 0x05, 0xe5, 0x7f, 0x25, 0x8b, 0x6a, 0x6c, 0x0e, 0x28, 0x37, 0x22, 0x1b, 0x8a, 0x55,
- 0x94, 0x1c, 0x8b, 0x1e, 0x01, 0xf9, 0x1a, 0x3a, 0xbc, 0xf2, 0x26, 0x5b, 0xba, 0x4a, 0xd1, 0x05,
- 0xfe, 0x64, 0xbb, 0x02, 0xb5, 0x53, 0x05, 0xca, 0xcf, 0xae, 0x79, 0x22, 0x13, 0xfa, 0x29, 0x0c,
- 0x45, 0xba, 0xaa, 0xea, 0x53, 0xed, 0x34, 0x95, 0xf2, 0x59, 0x3b, 0x4d, 0xb5, 0x94, 0xb5, 0xc3,
- 0xa5, 0xc8, 0x58, 0xcf, 0x24, 0xce, 0x2d, 0xe7, 0xea, 0x74, 0x85, 0xff, 0xe9, 0xe8, 0xd3, 0xff,
- 0x09, 0x00, 0x00, 0xff, 0xff, 0x02, 0x93, 0x8d, 0xb2, 0x9f, 0x34, 0x00, 0x00,
+ // 4455 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x7b, 0xcd, 0x8f, 0x1c, 0x49,
+ 0x56, 0x78, 0x67, 0x7d, 0x74, 0x55, 0xbf, 0xfa, 0xe8, 0xea, 0xe8, 0x0f, 0x97, 0xcb, 0x1f, 0xe3,
+ 0x8d, 0x9f, 0x3d, 0xf2, 0xd8, 0x33, 0xb6, 0x7f, 0x3d, 0x2c, 0xb3, 0xe3, 0x5d, 0x8f, 0xa6, 0xbb,
+ 0x5d, 0x6b, 0x7b, 0xa6, 0xa6, 0xdb, 0xca, 0xb6, 0xc7, 0x66, 0x05, 0x9b, 0xca, 0xca, 0x0c, 0x77,
+ 0x27, 0xce, 0xce, 0xac, 0xc9, 0xcc, 0x72, 0xbb, 0xe1, 0x82, 0x56, 0x9c, 0x40, 0x88, 0x03, 0xe2,
+ 0x0c, 0x27, 0x84, 0x04, 0xe2, 0xca, 0x09, 0x89, 0x33, 0x37, 0xc4, 0x01, 0x09, 0x71, 0x41, 0xe2,
+ 0x2f, 0x58, 0x21, 0x6e, 0x48, 0x28, 0xbe, 0x32, 0x22, 0x32, 0xb3, 0x7a, 0xed, 0x11, 0x70, 0x69,
+ 0x55, 0xbc, 0x78, 0xf9, 0x5e, 0xc4, 0xfb, 0x8a, 0xf7, 0x5e, 0x44, 0x43, 0xf7, 0xed, 0xdc, 0x4f,
+ 0x66, 0xde, 0x9d, 0x59, 0x12, 0x67, 0x31, 0x5a, 0xe6, 0xa3, 0xd1, 0x9a, 0x1b, 0x45, 0x71, 0xe6,
+ 0x66, 0x41, 0x1c, 0xa5, 0x7c, 0x0a, 0x6f, 0xc2, 0xfa, 0x8e, 0xef, 0xef, 0xcd, 0x93, 0x84, 0x44,
+ 0xde, 0x99, 0x4d, 0xd2, 0x59, 0x1c, 0xa5, 0x04, 0xff, 0x1c, 0xfa, 0x3b, 0xbe, 0xff, 0xd4, 0x0d,
+ 0x12, 0x9b, 0x7c, 0x37, 0x27, 0x69, 0x86, 0xae, 0x43, 0x6f, 0xea, 0xa6, 0xc4, 0xf1, 0x04, 0xea,
+ 0xd0, 0xba, 0x66, 0xdd, 0x5c, 0xb1, 0x4d, 0x20, 0xfa, 0x10, 0xfa, 0xdf, 0xcd, 0xe3, 0x4c, 0x43,
+ 0xab, 0x31, 0xb4, 0x02, 0x14, 0xaf, 0xc1, 0x6a, 0x4e, 0x5f, 0xb0, 0xfc, 0x47, 0x0b, 0x9a, 0x3b,
+ 0x21, 0x49, 0x32, 0x74, 0x1b, 0x1a, 0xd9, 0xd9, 0x8c, 0x30, 0x0e, 0xfd, 0xed, 0x0b, 0x77, 0xc4,
+ 0x5e, 0xd8, 0x24, 0xff, 0xfb, 0xec, 0x6c, 0x46, 0x6c, 0x86, 0x84, 0x86, 0xd0, 0x3a, 0x21, 0x69,
+ 0xea, 0x1e, 0x11, 0xc1, 0x4a, 0x0e, 0x11, 0x82, 0x86, 0xef, 0x66, 0x64, 0x58, 0xbf, 0x66, 0xdd,
+ 0xac, 0xdb, 0xec, 0x37, 0xfa, 0x09, 0xdd, 0x45, 0xe8, 0x46, 0x1e, 0x71, 0x5c, 0x4a, 0x68, 0xd8,
+ 0xb8, 0x66, 0xdd, 0xec, 0x6c, 0x6f, 0x48, 0x1e, 0xbb, 0x7c, 0x92, 0x31, 0x79, 0xbc, 0x64, 0x9b,
+ 0xc8, 0xf8, 0x3a, 0xac, 0xe4, 0xec, 0xd1, 0x05, 0x58, 0x9f, 0x1c, 0xbc, 0x70, 0x9e, 0xd9, 0x3b,
+ 0x0f, 0x9f, 0xec, 0x3f, 0x72, 0x76, 0x77, 0x26, 0x3b, 0xfb, 0x7b, 0xe3, 0xc1, 0xd2, 0xee, 0x0a,
+ 0xb4, 0x66, 0xee, 0x59, 0x18, 0xbb, 0x3e, 0xfe, 0xdb, 0x1a, 0xb4, 0x04, 0x49, 0x2a, 0xc0, 0x2c,
+ 0xce, 0xdc, 0xd0, 0x11, 0x34, 0xd9, 0xf6, 0x1a, 0xb6, 0x09, 0x44, 0x37, 0x61, 0xd5, 0x3b, 0x76,
+ 0xa3, 0x88, 0x28, 0xbc, 0x1a, 0xc3, 0x2b, 0x82, 0xd1, 0x8f, 0xe0, 0xc2, 0x8c, 0x44, 0x7e, 0x10,
+ 0x1d, 0x39, 0xc5, 0x2f, 0xea, 0xec, 0x8b, 0x45, 0xd3, 0xe8, 0x3e, 0x0c, 0x83, 0xc8, 0xf5, 0xb2,
+ 0xe0, 0x0d, 0x29, 0x7d, 0xda, 0x60, 0x9f, 0x2e, 0x9c, 0xa7, 0x0a, 0x3e, 0x75, 0xc3, 0x90, 0x64,
+ 0xf9, 0x17, 0x4d, 0xf6, 0x45, 0x01, 0x8a, 0xbe, 0x80, 0xd1, 0x3c, 0xf2, 0xe2, 0xe8, 0x55, 0x90,
+ 0x9c, 0x10, 0xdf, 0x29, 0x7c, 0xb3, 0xcc, 0xbe, 0x39, 0x07, 0x03, 0xff, 0xd2, 0x82, 0xae, 0xae,
+ 0x8c, 0x77, 0x14, 0xdf, 0x27, 0xd0, 0x48, 0x03, 0x9f, 0xcb, 0xac, 0xbf, 0x7d, 0xb1, 0x4a, 0xad,
+ 0x77, 0x0e, 0x03, 0x9f, 0xd8, 0x0c, 0x0d, 0x6d, 0x40, 0x73, 0x1a, 0xcf, 0x23, 0x9f, 0x49, 0xac,
+ 0x67, 0xf3, 0x01, 0x35, 0xa9, 0x19, 0x49, 0x3c, 0x12, 0x71, 0xf3, 0xe8, 0xd9, 0x72, 0x88, 0x30,
+ 0x74, 0xe9, 0x77, 0x85, 0xbd, 0x1b, 0x30, 0x34, 0x82, 0x76, 0x6e, 0xfc, 0xcb, 0xcc, 0x22, 0xf3,
+ 0x31, 0xbe, 0x02, 0x0d, 0xca, 0x1d, 0x01, 0x2c, 0xdb, 0xe3, 0x6f, 0x0e, 0x9e, 0x8d, 0x07, 0x4b,
+ 0x68, 0x05, 0x9a, 0x93, 0x83, 0xbd, 0x9d, 0xc9, 0xc0, 0xc2, 0xbf, 0x0e, 0xb0, 0xeb, 0x46, 0xd2,
+ 0xe3, 0x6e, 0xc2, 0x6a, 0x14, 0xfb, 0xc4, 0x09, 0x7c, 0x12, 0x65, 0xc1, 0xab, 0x80, 0x24, 0xc2,
+ 0xe7, 0x8a, 0x60, 0xdc, 0x83, 0x0e, 0xfb, 0x4e, 0x78, 0xd2, 0x67, 0xd0, 0xdc, 0x3b, 0x76, 0x83,
+ 0x88, 0x6e, 0xcf, 0xa3, 0x3f, 0xc4, 0x77, 0x7c, 0x40, 0xb7, 0x17, 0x91, 0xec, 0x34, 0x4e, 0x5e,
+ 0x4b, 0x8f, 0x11, 0x43, 0x3c, 0x83, 0xf6, 0x1e, 0xd7, 0x77, 0x8a, 0xb6, 0x60, 0x99, 0x9b, 0x00,
+ 0xfb, 0xb8, 0x67, 0x8b, 0x11, 0xdd, 0x9e, 0x34, 0x0e, 0xf6, 0x79, 0xcf, 0xce, 0xc7, 0x5c, 0x70,
+ 0xcc, 0xe6, 0x84, 0x40, 0xe5, 0x90, 0x52, 0xf3, 0xc2, 0x38, 0x25, 0xbe, 0x90, 0xa8, 0x18, 0x61,
+ 0x07, 0x36, 0x29, 0xc7, 0x23, 0xf2, 0xd4, 0x4d, 0xd3, 0xd3, 0x38, 0xf1, 0xe5, 0xe6, 0x31, 0x74,
+ 0x23, 0x72, 0xea, 0xcc, 0x04, 0x58, 0xec, 0xc0, 0x80, 0x51, 0x9c, 0x38, 0xf4, 0x15, 0x0e, 0xdf,
+ 0x8d, 0x01, 0xc3, 0x43, 0xd8, 0x2a, 0x32, 0x10, 0x52, 0xfa, 0x3b, 0x0b, 0xd6, 0xf7, 0xe8, 0x2a,
+ 0xc4, 0x96, 0xdf, 0x5b, 0xec, 0x86, 0xa6, 0x6b, 0xa6, 0xa6, 0xa9, 0xe8, 0x5f, 0xc5, 0x89, 0xf0,
+ 0xc5, 0xb6, 0xcd, 0x07, 0xe8, 0x1a, 0x74, 0x7c, 0x92, 0x66, 0x41, 0xc4, 0x62, 0x30, 0x93, 0xc5,
+ 0x8a, 0xad, 0x83, 0x98, 0xd8, 0x4f, 0xe2, 0x79, 0x94, 0x09, 0xdb, 0x12, 0x23, 0x34, 0x80, 0xfa,
+ 0x2b, 0x22, 0x1d, 0x87, 0xfe, 0xc4, 0x5f, 0xc2, 0x86, 0xb9, 0x7c, 0xbe, 0x2f, 0xba, 0xfe, 0x2c,
+ 0x71, 0xa3, 0x94, 0xea, 0x24, 0x8e, 0x9c, 0xc0, 0x4f, 0x87, 0xd6, 0xb5, 0x3a, 0x5d, 0x7f, 0x01,
+ 0x8c, 0x3f, 0x86, 0xfe, 0x5e, 0x1c, 0x45, 0xc4, 0xcb, 0xe4, 0xde, 0x47, 0xd0, 0x66, 0x9b, 0x9c,
+ 0x27, 0x81, 0xd8, 0x74, 0x3e, 0xa6, 0x21, 0x3b, 0xc7, 0x16, 0x22, 0xbc, 0x0b, 0x6b, 0x7b, 0x09,
+ 0x71, 0x33, 0xb2, 0x1f, 0xfb, 0x44, 0xa3, 0x51, 0xd0, 0x5a, 0x3e, 0xc6, 0x7f, 0x6a, 0x01, 0xd2,
+ 0xbf, 0x10, 0x4b, 0xfe, 0x7f, 0xd0, 0x4b, 0x09, 0xf1, 0x9d, 0x93, 0x88, 0x9c, 0xc4, 0x51, 0xe0,
+ 0x89, 0x05, 0x77, 0x29, 0xf0, 0x1b, 0x01, 0x43, 0x1f, 0xc1, 0x20, 0x88, 0x82, 0x2c, 0x70, 0xc3,
+ 0xe0, 0x77, 0x88, 0xef, 0x84, 0x91, 0x9f, 0x0e, 0x6b, 0x7c, 0x63, 0x1a, 0x7c, 0x12, 0xf9, 0x29,
+ 0xba, 0x0b, 0xeb, 0x3a, 0xaa, 0x47, 0x97, 0xfd, 0x36, 0x13, 0xaa, 0x40, 0xda, 0xd4, 0x1e, 0x9f,
+ 0xc1, 0xff, 0x6c, 0x41, 0x5b, 0x9e, 0x81, 0x86, 0x5a, 0xad, 0x82, 0x5a, 0x1f, 0x40, 0x27, 0x3d,
+ 0x75, 0x67, 0x8e, 0x17, 0x06, 0x34, 0x3c, 0xf0, 0x30, 0x73, 0x49, 0x86, 0x19, 0x49, 0xe2, 0xce,
+ 0xe1, 0xa9, 0x3b, 0xdb, 0x63, 0x28, 0xb6, 0x8e, 0xcf, 0x83, 0xd8, 0x6b, 0x12, 0x39, 0xae, 0xef,
+ 0x27, 0x24, 0x4d, 0xd9, 0x92, 0x56, 0x6c, 0x13, 0x48, 0x63, 0xac, 0x4f, 0xbc, 0xe0, 0xc4, 0x0d,
+ 0x9d, 0x59, 0xe8, 0x7a, 0x24, 0x15, 0x4e, 0x53, 0x80, 0x62, 0x0c, 0xa0, 0x18, 0xa1, 0x16, 0xd4,
+ 0x27, 0xfb, 0x0f, 0x07, 0x4b, 0xa8, 0x03, 0xad, 0xbd, 0x83, 0xfd, 0xfd, 0xf1, 0xcb, 0x67, 0x83,
+ 0x1a, 0xd5, 0xf1, 0x43, 0x32, 0x8b, 0xd3, 0x40, 0xd7, 0xf1, 0xa2, 0xed, 0xe1, 0xdb, 0xb0, 0x9a,
+ 0x63, 0x0b, 0xdd, 0x0c, 0xa1, 0x25, 0x17, 0xcb, 0xb1, 0xe5, 0x90, 0x1a, 0xe0, 0xc3, 0x20, 0xf5,
+ 0xe2, 0x37, 0x24, 0xa1, 0xda, 0x4c, 0xdf, 0x3f, 0x6e, 0xfd, 0x10, 0x36, 0x0b, 0x14, 0x04, 0xd3,
+ 0xcb, 0xb0, 0x12, 0xcd, 0x4f, 0x1c, 0x8a, 0x9f, 0x8a, 0xf8, 0xa3, 0x00, 0xf8, 0x0f, 0x2c, 0x40,
+ 0xe3, 0xb7, 0xc4, 0x9b, 0x67, 0x84, 0xee, 0x5f, 0xdb, 0x58, 0x9c, 0xf8, 0x24, 0x71, 0x82, 0xdc,
+ 0xf0, 0xe4, 0x98, 0x45, 0x26, 0x37, 0x60, 0x53, 0x22, 0xe6, 0x89, 0x21, 0x0d, 0x22, 0x33, 0x42,
+ 0x12, 0x67, 0x36, 0x9f, 0x3a, 0xaf, 0xc9, 0x99, 0xd0, 0x88, 0x01, 0xa3, 0x94, 0xbf, 0x9b, 0xbb,
+ 0x51, 0x16, 0x64, 0x67, 0xe2, 0x80, 0xcc, 0xc7, 0xd4, 0x07, 0x1e, 0x91, 0x4c, 0x1c, 0x30, 0xef,
+ 0x22, 0xe3, 0xbf, 0xb4, 0x00, 0xe9, 0x5f, 0x88, 0x2d, 0x3f, 0x84, 0xb6, 0x38, 0x41, 0xb8, 0xbf,
+ 0x76, 0xb6, 0x6f, 0x4a, 0xb3, 0x2a, 0x63, 0xcb, 0x03, 0x2d, 0x1d, 0x47, 0x59, 0x72, 0x66, 0xe7,
+ 0x5f, 0x8e, 0x26, 0xd0, 0x33, 0xa6, 0x68, 0xdc, 0xa0, 0xbb, 0xe2, 0x8b, 0xa0, 0x3f, 0xd1, 0x0d,
+ 0x68, 0xbe, 0x71, 0xc3, 0x39, 0x8f, 0xde, 0x9d, 0xed, 0xd5, 0xc2, 0x19, 0x69, 0xf3, 0xd9, 0xfb,
+ 0xb5, 0x1f, 0x59, 0x78, 0x00, 0xfd, 0x47, 0x24, 0x7b, 0x12, 0xbd, 0x8a, 0xc5, 0xc6, 0xf0, 0xbf,
+ 0xd4, 0x61, 0x35, 0x07, 0x29, 0x0b, 0x79, 0x43, 0x92, 0x94, 0x06, 0x34, 0x61, 0x21, 0x62, 0xc8,
+ 0x82, 0x38, 0x55, 0xb9, 0x94, 0xad, 0x08, 0xd0, 0x3a, 0x8c, 0x66, 0x69, 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, 0x6d, 0x58, 0x66, 0x5a, 0x4f, 0x59, 0xac, 0xec, 0x6c,
+ 0xaf, 0xcb, 0xfd, 0x1d, 0x30, 0xe8, 0x1e, 0x8d, 0xa6, 0xb6, 0x40, 0x41, 0xdb, 0x50, 0x0f, 0x23,
+ 0x7f, 0xd8, 0x62, 0xf2, 0xbe, 0xa6, 0xc9, 0x5b, 0xdf, 0xe0, 0x9d, 0x49, 0xe4, 0x73, 0x39, 0x53,
+ 0x64, 0x1a, 0xd9, 0xdd, 0x30, 0x70, 0xd3, 0xe1, 0x0a, 0x3f, 0x54, 0xd9, 0x40, 0x3f, 0x54, 0xc1,
+ 0x38, 0x54, 0xd1, 0x3d, 0x58, 0x97, 0x89, 0x18, 0x0b, 0x05, 0xc7, 0x6e, 0x7a, 0x4c, 0xd2, 0x61,
+ 0x87, 0xed, 0xb7, 0x6a, 0x0a, 0x7d, 0x02, 0x2d, 0x19, 0xb2, 0xba, 0xe6, 0x1e, 0x44, 0xbc, 0x62,
+ 0xab, 0x93, 0x38, 0xa3, 0x47, 0xd0, 0x96, 0x2b, 0x7c, 0x0f, 0x75, 0x4f, 0x22, 0x9f, 0x91, 0xd1,
+ 0xd4, 0xbd, 0xc1, 0x0c, 0x53, 0x06, 0x5c, 0xa9, 0xf2, 0x1f, 0xc3, 0xba, 0x01, 0x15, 0x5a, 0xbf,
+ 0x5e, 0x1d, 0xb3, 0x4d, 0x20, 0xfe, 0x82, 0x91, 0xa4, 0xce, 0xad, 0x59, 0xd1, 0x7b, 0x44, 0x08,
+ 0x9b, 0x31, 0x57, 0xdf, 0xe7, 0x07, 0xc6, 0x6a, 0x42, 0x66, 0x73, 0x5e, 0xca, 0x1c, 0x7a, 0x71,
+ 0xc2, 0xb3, 0x94, 0x35, 0x1b, 0x14, 0x98, 0x1e, 0xa5, 0x53, 0x7a, 0x34, 0x72, 0x97, 0x6f, 0xdb,
+ 0x62, 0x84, 0x2f, 0xc0, 0xe6, 0x24, 0x48, 0x33, 0x11, 0xac, 0x83, 0x3c, 0x70, 0xe1, 0xaf, 0x60,
+ 0xab, 0x38, 0x21, 0xf8, 0xdd, 0x03, 0xf0, 0x72, 0xa8, 0x70, 0xcf, 0x41, 0x31, 0xea, 0xdb, 0x1a,
+ 0x0e, 0xfe, 0x07, 0x0b, 0xd6, 0x28, 0x31, 0x6e, 0x75, 0x72, 0xe3, 0x5a, 0x18, 0xb2, 0xcc, 0x30,
+ 0xf4, 0x43, 0x68, 0xc6, 0xa7, 0x11, 0x49, 0xc4, 0x91, 0xf2, 0x41, 0xae, 0xa6, 0x22, 0x8d, 0x3b,
+ 0x07, 0x14, 0xcd, 0xe6, 0xd8, 0xd4, 0x18, 0xc3, 0xe0, 0x24, 0xc8, 0x64, 0x02, 0xcb, 0x06, 0x54,
+ 0xbe, 0x41, 0xe4, 0x85, 0x73, 0x9f, 0x16, 0x2e, 0x81, 0x9b, 0x8a, 0x13, 0xa4, 0x6d, 0x17, 0xc1,
+ 0xf8, 0x3a, 0x34, 0x19, 0x3d, 0xd4, 0x86, 0xc6, 0xee, 0xc1, 0xb3, 0xc7, 0x83, 0x25, 0x7a, 0x8e,
+ 0x1c, 0xbc, 0xd8, 0x1f, 0x58, 0x14, 0xf4, 0x74, 0x3c, 0xb6, 0x07, 0x35, 0xfc, 0x67, 0x16, 0x20,
+ 0x7d, 0x21, 0x42, 0x2a, 0x5f, 0xe4, 0xae, 0xc6, 0x25, 0xf2, 0x61, 0xd5, 0xa2, 0x85, 0x0f, 0xf1,
+ 0x21, 0x77, 0x23, 0xf1, 0xd5, 0xe8, 0x09, 0x74, 0x34, 0x70, 0x85, 0xed, 0x5e, 0x37, 0x6d, 0xb7,
+ 0x6f, 0xba, 0xb2, 0x6e, 0xba, 0x08, 0x06, 0x94, 0x29, 0x2d, 0x28, 0x73, 0x75, 0x7e, 0xc4, 0x35,
+ 0x20, 0x60, 0x62, 0xcd, 0x1b, 0xd0, 0xe4, 0x81, 0x83, 0x9b, 0x2b, 0x1f, 0xe4, 0x9f, 0x13, 0x25,
+ 0x67, 0xfc, 0x99, 0xf8, 0x9c, 0xe8, 0x5b, 0xc6, 0xd0, 0xe4, 0x51, 0x89, 0xef, 0xb8, 0x2b, 0x57,
+ 0x44, 0xb1, 0x6c, 0x3e, 0x85, 0xff, 0xd5, 0x82, 0x96, 0xf0, 0x2e, 0x6a, 0x83, 0x69, 0xe6, 0x66,
+ 0x73, 0x79, 0x78, 0x8a, 0x11, 0xfa, 0x18, 0xda, 0xa2, 0xb2, 0x4a, 0xc5, 0xe6, 0x94, 0x39, 0x09,
+ 0xb8, 0x9d, 0x63, 0xa0, 0x1b, 0xb0, 0xcc, 0x52, 0x77, 0x1e, 0x25, 0x3b, 0xdb, 0x3d, 0x0d, 0x37,
+ 0x88, 0x6c, 0x31, 0x49, 0xb3, 0xcb, 0x69, 0x18, 0x7b, 0xaf, 0x8f, 0x49, 0x70, 0x74, 0x2c, 0x6b,
+ 0x17, 0x1d, 0x94, 0x07, 0xdb, 0xa6, 0x16, 0x6c, 0xb5, 0xf0, 0xbd, 0x6c, 0x86, 0xef, 0x3c, 0xd2,
+ 0xb5, 0xb4, 0x48, 0x87, 0xbf, 0x82, 0x3e, 0xf3, 0x47, 0x95, 0x07, 0x17, 0xc3, 0xbc, 0x55, 0x11,
+ 0xe6, 0x73, 0x5a, 0x35, 0x9d, 0xd6, 0x5f, 0x58, 0x80, 0x0e, 0x66, 0x24, 0xfa, 0x5f, 0x49, 0xc1,
+ 0x55, 0x2a, 0x5d, 0x37, 0x52, 0xe9, 0x6b, 0xd0, 0x99, 0xcd, 0xd3, 0x63, 0x47, 0x4c, 0xf2, 0x03,
+ 0x5d, 0x07, 0xc9, 0x64, 0xbb, 0xa9, 0x92, 0xed, 0x07, 0xb0, 0x6e, 0xac, 0x53, 0x98, 0xc3, 0x87,
+ 0xd0, 0x37, 0x93, 0x6a, 0xb1, 0xce, 0x02, 0x14, 0xff, 0x7d, 0x0d, 0x9a, 0xcc, 0x68, 0x99, 0xfd,
+ 0x25, 0x81, 0x28, 0x5f, 0x2d, 0x9b, 0x0f, 0x8c, 0x04, 0xa3, 0x66, 0x26, 0x18, 0x7a, 0xcc, 0xa8,
+ 0x9b, 0x31, 0xa3, 0x0f, 0xb5, 0xc0, 0x17, 0x45, 0x44, 0x2d, 0xf0, 0xd1, 0x97, 0x65, 0xb1, 0x35,
+ 0x99, 0x6d, 0x6d, 0x49, 0x7b, 0x31, 0x15, 0x57, 0x29, 0xce, 0x30, 0xf6, 0xdc, 0x90, 0x32, 0x13,
+ 0xb5, 0xab, 0x1c, 0xa3, 0xab, 0x00, 0x1e, 0x4b, 0xdd, 0x7d, 0xc7, 0xcd, 0x98, 0x49, 0x34, 0x6c,
+ 0x0d, 0x82, 0x6e, 0x88, 0xd2, 0xbb, 0xcd, 0x02, 0xd8, 0x9a, 0xe1, 0xab, 0x5a, 0xc9, 0x8d, 0xa1,
+ 0x1b, 0xa4, 0x4e, 0x7c, 0x1a, 0x39, 0x2c, 0x0a, 0xb0, 0x53, 0xb4, 0x6d, 0x1b, 0x30, 0x6a, 0xa6,
+ 0xc7, 0x71, 0xe8, 0xb3, 0x93, 0xb4, 0x61, 0xb3, 0xdf, 0xf8, 0xcf, 0x2d, 0xe8, 0x32, 0x5a, 0x36,
+ 0x39, 0x89, 0xdf, 0xb8, 0xa1, 0x21, 0x33, 0x6b, 0xb1, 0xcc, 0x0a, 0xe9, 0x9e, 0x9e, 0x24, 0xd6,
+ 0x0b, 0x49, 0xa2, 0xbe, 0xfb, 0x46, 0x61, 0xf7, 0xc5, 0x65, 0x37, 0xcb, 0xcb, 0xc6, 0xc7, 0xb0,
+ 0xcc, 0x23, 0x13, 0xfa, 0x04, 0x60, 0x3a, 0x3f, 0x73, 0x8c, 0xe8, 0xd8, 0x33, 0x24, 0x62, 0x6b,
+ 0x08, 0xe8, 0x2e, 0x74, 0x52, 0x12, 0x86, 0x12, 0xbf, 0x56, 0x85, 0xaf, 0x63, 0xe0, 0x4f, 0x65,
+ 0xe4, 0x64, 0xe9, 0x0c, 0x95, 0x17, 0x0d, 0x3d, 0x22, 0x53, 0x66, 0xbf, 0xa9, 0x0d, 0xc7, 0xa7,
+ 0x91, 0x28, 0xd1, 0xe9, 0x4f, 0xfc, 0x0b, 0x4b, 0x7c, 0xf5, 0x7c, 0xc6, 0x7a, 0x61, 0x37, 0xa0,
+ 0xc9, 0xf7, 0x62, 0x31, 0x23, 0x31, 0xf9, 0x3d, 0x5e, 0xb2, 0xf9, 0x2c, 0xfa, 0x09, 0xf4, 0xb8,
+ 0x84, 0x12, 0x2e, 0x78, 0x11, 0xaf, 0x36, 0xcc, 0xe5, 0xf1, 0xb9, 0xc7, 0x4b, 0xb6, 0x89, 0xbc,
+ 0xdb, 0x87, 0x2e, 0x07, 0xcc, 0x19, 0x53, 0xfc, 0x9f, 0x75, 0x68, 0xd0, 0x60, 0xb9, 0xb8, 0xae,
+ 0x78, 0xa7, 0xac, 0xf1, 0x4b, 0xe8, 0x86, 0x91, 0x2f, 0x87, 0x32, 0x2e, 0x5e, 0xd6, 0xc3, 0x31,
+ 0xcd, 0x70, 0x9e, 0xce, 0xa7, 0x5f, 0x93, 0x33, 0x71, 0xec, 0x18, 0x5f, 0x50, 0xfe, 0x41, 0xc4,
+ 0x9b, 0x3f, 0xfc, 0x6c, 0x94, 0x43, 0x75, 0x44, 0x34, 0xb5, 0x23, 0x82, 0x46, 0x8d, 0xb7, 0x73,
+ 0xdf, 0x31, 0x43, 0xa5, 0x0e, 0x42, 0x1f, 0xc3, 0x5a, 0x4a, 0xbc, 0x38, 0xf2, 0x53, 0x5e, 0x71,
+ 0x7a, 0x19, 0xf1, 0x99, 0x9f, 0xf4, 0xec, 0xf2, 0xc4, 0x82, 0x34, 0xf2, 0x1e, 0xb4, 0xe9, 0x2a,
+ 0x59, 0x90, 0x06, 0xb6, 0xa7, 0x8d, 0xe2, 0x9e, 0x9e, 0x27, 0x41, 0x6a, 0xe7, 0x58, 0xe8, 0x0e,
+ 0x20, 0x91, 0x08, 0xea, 0x7e, 0xdf, 0x61, 0x44, 0x2b, 0x66, 0x46, 0x0f, 0x60, 0xb5, 0x20, 0x98,
+ 0x8a, 0x83, 0x77, 0x43, 0x3f, 0x78, 0x57, 0xb4, 0x83, 0x76, 0xf4, 0x19, 0x3b, 0xdb, 0xe8, 0x1a,
+ 0xce, 0xad, 0x93, 0x07, 0x50, 0x9f, 0x27, 0x81, 0xa8, 0xcf, 0xe9, 0x4f, 0xfc, 0x7b, 0x35, 0x58,
+ 0x7b, 0x4a, 0xeb, 0x56, 0x61, 0x2f, 0x3c, 0xd2, 0xff, 0x4f, 0x86, 0x43, 0xdd, 0xb5, 0x1b, 0x05,
+ 0xd7, 0x96, 0xc1, 0xa9, 0x79, 0x7e, 0x70, 0xba, 0x05, 0x83, 0x84, 0xb0, 0xea, 0xda, 0xc9, 0x49,
+ 0x71, 0x4d, 0x97, 0xe0, 0x34, 0xaf, 0x0f, 0x4e, 0x4e, 0x88, 0x1f, 0xb8, 0x19, 0x85, 0x3a, 0x1e,
+ 0xad, 0x9e, 0x42, 0xa6, 0xf0, 0xb6, 0x5d, 0x35, 0x45, 0x45, 0x80, 0x74, 0x11, 0x88, 0x43, 0xe4,
+ 0x73, 0x18, 0x04, 0x51, 0x46, 0x92, 0xc8, 0x0d, 0x9d, 0x13, 0x37, 0xf3, 0x8e, 0xc9, 0x82, 0x90,
+ 0x51, 0x42, 0x43, 0x3f, 0x86, 0x3e, 0x2b, 0x1c, 0xd2, 0xb9, 0xe7, 0x91, 0x94, 0xe6, 0x79, 0x3c,
+ 0x76, 0xe4, 0x05, 0x03, 0xad, 0x8f, 0x0f, 0xf9, 0xa4, 0x5d, 0x40, 0x45, 0x9f, 0xd1, 0x24, 0xfa,
+ 0xc4, 0x0d, 0x22, 0x5a, 0x7f, 0xf0, 0x48, 0x50, 0xaf, 0x88, 0x04, 0x76, 0x11, 0x0b, 0x7d, 0x0e,
+ 0x3d, 0x46, 0xea, 0x95, 0x1b, 0x84, 0xf3, 0x84, 0x25, 0x97, 0x25, 0xa6, 0x3f, 0xe5, 0x73, 0xb6,
+ 0x89, 0x89, 0x7f, 0x69, 0xc1, 0xaa, 0x12, 0xc1, 0xf8, 0x0d, 0x89, 0xe8, 0xc1, 0xd1, 0x64, 0xfb,
+ 0x59, 0x18, 0x87, 0xd8, 0x2c, 0xfa, 0x1c, 0xba, 0xfa, 0x06, 0x44, 0x18, 0xaa, 0xda, 0xe9, 0xe3,
+ 0x25, 0xdb, 0x40, 0x45, 0x9f, 0xbf, 0xdb, 0x4e, 0x1f, 0x2f, 0x55, 0xed, 0xb5, 0xab, 0xef, 0x40,
+ 0xdc, 0x17, 0x54, 0x6d, 0x35, 0xe7, 0x2a, 0x50, 0x77, 0x5b, 0xd0, 0x24, 0x74, 0x83, 0x38, 0x86,
+ 0x8e, 0x56, 0xb8, 0x2d, 0xcc, 0x09, 0xb5, 0x88, 0x58, 0x33, 0x23, 0xa2, 0x96, 0xa2, 0x35, 0x4a,
+ 0x29, 0x1a, 0xef, 0xf0, 0x36, 0xb5, 0x0e, 0x2f, 0xfe, 0x14, 0x36, 0x59, 0x40, 0x26, 0xea, 0x5e,
+ 0xe7, 0x57, 0xf7, 0x25, 0x86, 0xb0, 0x55, 0xfc, 0x48, 0xb4, 0xf9, 0x26, 0x80, 0xf8, 0x8c, 0xe1,
+ 0xba, 0xe7, 0xb5, 0x5b, 0xce, 0x71, 0x60, 0xfc, 0x57, 0x16, 0xac, 0x1b, 0xe4, 0x84, 0x1b, 0x5c,
+ 0x85, 0x81, 0xc4, 0x71, 0xe2, 0xc8, 0x61, 0x09, 0x80, 0xa5, 0x12, 0x00, 0x1a, 0xe8, 0x94, 0x72,
+ 0x0a, 0xd4, 0x2b, 0x66, 0xb8, 0x2f, 0x53, 0x36, 0xbe, 0xc2, 0xe6, 0x89, 0x60, 0x09, 0xae, 0x07,
+ 0x95, 0x86, 0x11, 0x54, 0x94, 0x54, 0x76, 0xc2, 0xd0, 0xa8, 0xc3, 0xf0, 0x1c, 0x2e, 0x94, 0x66,
+ 0xc4, 0x56, 0x3e, 0x86, 0x35, 0xc9, 0x42, 0x8a, 0x44, 0x16, 0x1c, 0xe5, 0x09, 0x8a, 0x2d, 0xf6,
+ 0xab, 0x61, 0xf3, 0xc8, 0x59, 0x9e, 0xc0, 0x9f, 0xc0, 0x1a, 0x67, 0xab, 0x5f, 0xce, 0x2d, 0xac,
+ 0x2b, 0x69, 0x4d, 0xaf, 0xa3, 0x0b, 0x8d, 0xfe, 0x7e, 0x8d, 0x82, 0xd3, 0x2c, 0x4e, 0x8c, 0xd6,
+ 0xed, 0x3b, 0xf5, 0x61, 0xf5, 0xfe, 0x6e, 0xcd, 0xec, 0xef, 0xa2, 0xaf, 0xa1, 0x43, 0x0f, 0xa6,
+ 0xa9, 0xeb, 0xbd, 0x9e, 0xcf, 0xe4, 0xa9, 0x7c, 0x4b, 0x3a, 0x4b, 0x99, 0x23, 0x3d, 0xcf, 0x76,
+ 0x39, 0x32, 0x3f, 0xa3, 0x21, 0xcc, 0x01, 0xe8, 0x07, 0xec, 0x16, 0xd3, 0xf1, 0xdd, 0xcc, 0x9d,
+ 0xba, 0x29, 0xef, 0x7d, 0x77, 0xd9, 0x91, 0xfb, 0x50, 0x80, 0xc4, 0x61, 0xa6, 0x53, 0xf8, 0x55,
+ 0x87, 0x59, 0x57, 0xaf, 0x1a, 0x09, 0xb5, 0x44, 0x6d, 0x4d, 0xaa, 0x1d, 0x9d, 0x70, 0xb0, 0x68,
+ 0x33, 0x0b, 0x31, 0x48, 0x20, 0xeb, 0x31, 0x7f, 0x44, 0xcd, 0x4b, 0x20, 0xc9, 0x6e, 0x0d, 0xef,
+ 0x33, 0xac, 0x4a, 0xb8, 0xec, 0x2e, 0x3f, 0x04, 0x74, 0x48, 0xb2, 0x49, 0x7c, 0x34, 0x21, 0x6f,
+ 0x54, 0x91, 0x73, 0x07, 0x56, 0xc2, 0xf8, 0xc8, 0x09, 0x29, 0x4c, 0x5c, 0x75, 0xe6, 0x35, 0x60,
+ 0x8e, 0xab, 0x50, 0xf0, 0x26, 0xac, 0x1b, 0x54, 0x84, 0x2a, 0xd7, 0x60, 0xf5, 0xf0, 0x78, 0x9e,
+ 0xf9, 0xf1, 0xa9, 0xbc, 0x38, 0xa2, 0xd5, 0xac, 0x02, 0x09, 0xb4, 0x5f, 0x83, 0xad, 0xc3, 0xf9,
+ 0x34, 0xf5, 0x92, 0x60, 0x4a, 0xcc, 0x9e, 0xc4, 0x08, 0xda, 0xe4, 0x6d, 0x90, 0x66, 0x41, 0x74,
+ 0xc4, 0x96, 0xd1, 0xb6, 0xf3, 0x31, 0xb5, 0xfe, 0xfc, 0x2b, 0x76, 0x79, 0x96, 0x5b, 0xff, 0x07,
+ 0x70, 0x25, 0x9f, 0xa1, 0x41, 0x30, 0xdd, 0xf1, 0x3c, 0x32, 0xcb, 0x88, 0xbc, 0xc0, 0xc1, 0x0f,
+ 0x60, 0xd3, 0x44, 0xd0, 0x2e, 0x92, 0x65, 0x17, 0x22, 0x73, 0x5f, 0x8b, 0xf4, 0xb3, 0x6d, 0x9b,
+ 0x40, 0xfc, 0x5f, 0x35, 0xe8, 0xd2, 0xcf, 0x24, 0x59, 0x74, 0xb1, 0x14, 0x6e, 0x5a, 0x6c, 0xfc,
+ 0xc4, 0xcc, 0xdb, 0x6b, 0x85, 0xbc, 0xfd, 0xdc, 0x74, 0x61, 0x51, 0x53, 0x57, 0xa5, 0x25, 0x4d,
+ 0x3d, 0x2d, 0x29, 0xb6, 0x8a, 0x97, 0x2b, 0x5a, 0xc5, 0x5b, 0xb0, 0x9c, 0xb0, 0x3e, 0x9e, 0x28,
+ 0x9a, 0xc5, 0x88, 0x46, 0x23, 0x5e, 0x5c, 0x3a, 0x09, 0xf1, 0x48, 0xf0, 0x86, 0x4a, 0xbb, 0xcd,
+ 0xa3, 0x51, 0x11, 0x4e, 0xab, 0x4a, 0x01, 0x4b, 0xc5, 0x6d, 0xda, 0x0a, 0xbf, 0x63, 0x35, 0xa1,
+ 0x2c, 0xf5, 0x13, 0xb1, 0x5a, 0xa3, 0x0a, 0x22, 0xf5, 0x2b, 0xcd, 0xd0, 0x35, 0xe4, 0x50, 0x49,
+ 0x99, 0x27, 0x8a, 0x25, 0x38, 0x8d, 0xd2, 0x1d, 0xed, 0x70, 0xfb, 0x9e, 0xcd, 0x75, 0x5d, 0xc6,
+ 0xf5, 0x82, 0x8c, 0x8b, 0xd2, 0x6c, 0x54, 0x48, 0xf3, 0x43, 0xe8, 0x8b, 0xd3, 0xd4, 0x49, 0x88,
+ 0x9b, 0xc6, 0xf2, 0x9c, 0x2b, 0x40, 0xf1, 0xdf, 0xd4, 0xf9, 0x6a, 0x45, 0x02, 0xf0, 0x7f, 0x6b,
+ 0x2c, 0x4a, 0xe5, 0x4d, 0x43, 0xe5, 0x37, 0x61, 0xd5, 0x50, 0x2d, 0xf1, 0x85, 0xc6, 0x8b, 0x60,
+ 0x5a, 0x5b, 0x28, 0xd5, 0x66, 0x42, 0xdb, 0x3a, 0xa8, 0x24, 0x2c, 0xa8, 0x10, 0xd6, 0x35, 0x68,
+ 0x24, 0x71, 0x48, 0x98, 0x4a, 0xfb, 0xaa, 0x35, 0x65, 0xc7, 0x21, 0xb1, 0xd9, 0x0c, 0x3d, 0x69,
+ 0x0a, 0x66, 0x41, 0x7c, 0xd6, 0x62, 0x5e, 0xb1, 0xcb, 0x13, 0xd4, 0x51, 0x75, 0xb3, 0xc8, 0x86,
+ 0x3d, 0x7e, 0x59, 0x65, 0x00, 0xd1, 0x55, 0x80, 0xc4, 0x99, 0x25, 0x24, 0x38, 0x71, 0x8f, 0xc8,
+ 0xb0, 0xcf, 0x50, 0x34, 0x88, 0x72, 0xa5, 0x55, 0xcd, 0x95, 0xf0, 0x7f, 0xd4, 0xa0, 0xf9, 0x2c,
+ 0x71, 0x7d, 0x42, 0x6b, 0xdf, 0x13, 0xea, 0xf1, 0xce, 0xe2, 0x5a, 0xd4, 0xd6, 0x31, 0xe8, 0x07,
+ 0x99, 0xf6, 0x41, 0xad, 0xf2, 0x03, 0x0d, 0x43, 0xd3, 0x4f, 0xdd, 0xd0, 0xcf, 0x79, 0x3a, 0xd5,
+ 0x2c, 0xa1, 0x69, 0x5a, 0x42, 0xbe, 0x9f, 0x65, 0x3d, 0x34, 0x48, 0xd9, 0xb7, 0x16, 0xca, 0xfe,
+ 0x1a, 0x74, 0x08, 0xbf, 0xb3, 0x62, 0xfd, 0x13, 0x6e, 0x09, 0x3a, 0x28, 0xaf, 0x51, 0x56, 0xce,
+ 0xaf, 0x51, 0xee, 0x43, 0xd7, 0xa3, 0x86, 0x41, 0x92, 0x99, 0x9b, 0x64, 0xdc, 0x14, 0x16, 0xb7,
+ 0x78, 0x0c, 0x5c, 0x7c, 0x1b, 0xd6, 0x99, 0xd4, 0x1f, 0x07, 0xf4, 0x84, 0x3a, 0xd3, 0xaa, 0x30,
+ 0xde, 0x45, 0xb6, 0xb4, 0x2e, 0x32, 0x7e, 0x00, 0x1b, 0x26, 0xb2, 0x38, 0x1e, 0x6f, 0xc0, 0x72,
+ 0x46, 0xe1, 0xa5, 0x2a, 0x85, 0x61, 0xdb, 0x62, 0x12, 0xff, 0xb1, 0x05, 0x3d, 0x0a, 0x09, 0xa2,
+ 0xa3, 0x09, 0xa5, 0xc7, 0x0a, 0xc6, 0x13, 0xf7, 0xad, 0x93, 0x92, 0x30, 0x94, 0x1d, 0x1b, 0x39,
+ 0x66, 0xcf, 0x78, 0xdc, 0xb7, 0xce, 0x74, 0x2e, 0x53, 0x3a, 0x39, 0xa4, 0x66, 0x98, 0x90, 0x94,
+ 0x24, 0x34, 0x69, 0x62, 0x9f, 0xf2, 0x40, 0x62, 0x02, 0xa9, 0x83, 0xe4, 0x00, 0x4a, 0x84, 0x2b,
+ 0xd4, 0x80, 0xe1, 0x6d, 0xbe, 0xa1, 0x7c, 0x41, 0xef, 0x92, 0x15, 0xff, 0xb5, 0x05, 0x9b, 0x85,
+ 0x8f, 0x84, 0x18, 0x76, 0x60, 0x99, 0xc9, 0x49, 0x8a, 0xe1, 0x23, 0x5d, 0x0c, 0x25, 0xf4, 0x3b,
+ 0x7c, 0x28, 0x1a, 0xe0, 0xfc, 0xc3, 0xd1, 0x53, 0xe8, 0x68, 0xe0, 0x8a, 0xd4, 0xe5, 0xb6, 0xd9,
+ 0x00, 0xdf, 0xac, 0x66, 0xa1, 0x65, 0x34, 0xdf, 0x42, 0xf7, 0x79, 0x34, 0xfd, 0x1e, 0x6f, 0x48,
+ 0xd0, 0x65, 0x58, 0x49, 0x88, 0x68, 0x4f, 0x88, 0x44, 0x46, 0x01, 0xf0, 0x2a, 0xf4, 0x04, 0x5d,
+ 0x75, 0xf5, 0xff, 0x3c, 0x0a, 0x63, 0xef, 0xf5, 0xbb, 0x5e, 0xfd, 0xff, 0x0c, 0x90, 0xfe, 0x81,
+ 0x4a, 0xb5, 0xe6, 0x0c, 0x5a, 0x48, 0xb5, 0x24, 0x90, 0xa5, 0x5a, 0x1f, 0x40, 0x47, 0x47, 0xe1,
+ 0x37, 0x85, 0xa0, 0x10, 0xf0, 0x1f, 0x5a, 0xb0, 0xfa, 0x22, 0xc8, 0x8e, 0xfd, 0xc4, 0x3d, 0x7d,
+ 0x07, 0xa5, 0x16, 0x9f, 0x61, 0xd4, 0xce, 0x7b, 0x86, 0x51, 0x2f, 0x3e, 0xc3, 0x70, 0xc3, 0x50,
+ 0x74, 0x8c, 0xe8, 0x4f, 0xbd, 0x57, 0xdc, 0xe3, 0xbd, 0xe2, 0xfb, 0x30, 0x50, 0x8b, 0x79, 0xbf,
+ 0x46, 0xf1, 0xad, 0x9b, 0xb0, 0x92, 0xfb, 0x3b, 0x6a, 0x41, 0x7d, 0xf7, 0xf9, 0x6f, 0x0c, 0x96,
+ 0x50, 0x1b, 0x1a, 0x87, 0xe3, 0xc9, 0x84, 0xdf, 0xc9, 0xb0, 0x6b, 0x9a, 0xda, 0xad, 0x5b, 0xd0,
+ 0xa0, 0xd1, 0x05, 0xad, 0x40, 0xf3, 0xd9, 0xce, 0xd7, 0x63, 0x9b, 0xbf, 0x24, 0xfa, 0x86, 0xfd,
+ 0xb4, 0x50, 0x17, 0xda, 0x4f, 0xf6, 0x9f, 0x8d, 0xed, 0xfd, 0x9d, 0xc9, 0xa0, 0x76, 0xeb, 0x05,
+ 0xb4, 0x65, 0xde, 0x48, 0x91, 0x76, 0x26, 0x63, 0xfb, 0x19, 0xc7, 0x1f, 0xdb, 0xf6, 0x81, 0xcd,
+ 0xe9, 0xbe, 0xd8, 0xb1, 0xf7, 0x07, 0x35, 0xfa, 0xeb, 0xc9, 0xfe, 0x4f, 0x0f, 0x06, 0x75, 0xd4,
+ 0x81, 0xd6, 0xb7, 0x63, 0x7b, 0xf7, 0xe0, 0x70, 0x3c, 0x68, 0x50, 0xdc, 0x87, 0xe3, 0xdd, 0xe7,
+ 0x8f, 0x06, 0x4d, 0xc6, 0xd1, 0xde, 0xd9, 0x1b, 0x0f, 0x96, 0xb7, 0xff, 0xcd, 0x82, 0xd6, 0xcb,
+ 0xb9, 0xff, 0x24, 0x0a, 0x32, 0x34, 0x06, 0x50, 0x4f, 0x3b, 0x50, 0xfe, 0xf4, 0xaa, 0xf4, 0x40,
+ 0x64, 0x34, 0xaa, 0x9a, 0x12, 0x66, 0xb5, 0x84, 0x1e, 0x43, 0x47, 0xcb, 0xc9, 0xd1, 0x68, 0x71,
+ 0xf1, 0x30, 0xba, 0x54, 0x39, 0x97, 0x53, 0x1a, 0x03, 0x28, 0x8b, 0x53, 0x0b, 0x2a, 0x99, 0xad,
+ 0x5a, 0x50, 0xd9, 0x40, 0xf1, 0xd2, 0xf6, 0x1f, 0x5d, 0x82, 0xfa, 0xcb, 0xb9, 0x8f, 0x5e, 0x42,
+ 0x47, 0x7b, 0x29, 0x89, 0x4a, 0xd7, 0x7f, 0x6a, 0x39, 0x55, 0x0f, 0x2a, 0x47, 0xbf, 0xf8, 0xa7,
+ 0x7f, 0xff, 0x93, 0xda, 0x06, 0x5e, 0xbd, 0xfb, 0xe6, 0xff, 0xdf, 0x75, 0x7d, 0x5f, 0xda, 0xe2,
+ 0x7d, 0xeb, 0x16, 0xb2, 0xa1, 0x25, 0x1e, 0x43, 0xa2, 0x2d, 0x8d, 0x86, 0x56, 0xe0, 0x8d, 0x2e,
+ 0x94, 0xe0, 0x82, 0xee, 0x16, 0xa3, 0x3b, 0xc0, 0x1d, 0x41, 0x97, 0x1e, 0x53, 0x94, 0xe6, 0x2e,
+ 0xd4, 0x77, 0xdd, 0x08, 0x21, 0x75, 0xbb, 0x2f, 0x63, 0xc2, 0x68, 0xdd, 0x80, 0x09, 0x3a, 0x88,
+ 0xd1, 0xe9, 0xe2, 0x16, 0xa5, 0x33, 0x75, 0x23, 0x4a, 0xe3, 0x08, 0xfa, 0xe6, 0xdb, 0x29, 0x74,
+ 0x45, 0xbf, 0xa4, 0x2a, 0x3d, 0xda, 0x1a, 0x5d, 0x5d, 0x34, 0x5d, 0x58, 0x6c, 0x9f, 0x32, 0xf1,
+ 0x18, 0x0e, 0x8d, 0x0f, 0xc8, 0x83, 0xae, 0xfe, 0x94, 0x09, 0xa9, 0x07, 0x35, 0xe5, 0xf7, 0x59,
+ 0xa3, 0xcb, 0xd5, 0x93, 0x82, 0xc5, 0x90, 0xb1, 0x40, 0x78, 0xc0, 0x58, 0x50, 0x0c, 0x71, 0x8b,
+ 0x46, 0xa5, 0x2c, 0xde, 0x2f, 0x29, 0x29, 0x9b, 0xcf, 0x9f, 0x94, 0x94, 0x8b, 0x0f, 0x9d, 0x0c,
+ 0x29, 0x8b, 0x98, 0x48, 0x25, 0xf4, 0x73, 0xe8, 0xbd, 0x60, 0xef, 0x16, 0xc5, 0xab, 0x19, 0x45,
+ 0xd9, 0x7c, 0x74, 0xa3, 0x28, 0x17, 0x9e, 0xd7, 0xe0, 0xcb, 0x8c, 0xf2, 0x16, 0x5e, 0xa3, 0x94,
+ 0xf9, 0x1b, 0x48, 0x9f, 0xa3, 0x08, 0xcb, 0xf8, 0xde, 0x94, 0x8d, 0x35, 0x6b, 0x34, 0x7f, 0x1b,
+ 0x7a, 0xc6, 0xa3, 0x1b, 0x94, 0x0b, 0xb4, 0xea, 0x35, 0xcf, 0xe8, 0xca, 0x82, 0xd9, 0xaa, 0xf5,
+ 0xfb, 0x02, 0x85, 0x3d, 0xd3, 0xa1, 0xbc, 0x5e, 0x02, 0xa8, 0xc7, 0x2b, 0xca, 0x05, 0x4b, 0x0f,
+ 0x66, 0x94, 0x0b, 0x96, 0xdf, 0xba, 0xe0, 0x75, 0xc6, 0xa2, 0x87, 0x3a, 0xdc, 0x34, 0x39, 0xad,
+ 0x09, 0xb4, 0xc4, 0x33, 0x0d, 0x25, 0x19, 0xf3, 0xad, 0x8a, 0x92, 0x4c, 0xe1, 0x3d, 0x07, 0x1e,
+ 0x30, 0x82, 0x80, 0xda, 0x94, 0x60, 0x40, 0x49, 0xfc, 0x26, 0x74, 0xb4, 0x37, 0x0e, 0x48, 0x5f,
+ 0x4d, 0xe1, 0x39, 0x84, 0xf2, 0xf2, 0x8a, 0x47, 0x11, 0x78, 0x83, 0x51, 0xee, 0xa3, 0x2e, 0xa5,
+ 0x2c, 0xbb, 0x28, 0x82, 0xba, 0x7c, 0xc4, 0x60, 0x50, 0x2f, 0xbc, 0x8c, 0x30, 0xa8, 0x17, 0x5f,
+ 0x3d, 0x98, 0xd4, 0xa9, 0x8c, 0xd9, 0xda, 0x5f, 0x00, 0xa8, 0xfb, 0x76, 0x25, 0xe3, 0xd2, 0xc3,
+ 0x01, 0x25, 0xe3, 0xf2, 0xf5, 0xbc, 0x74, 0x7f, 0x04, 0x94, 0xb4, 0xb8, 0x95, 0x3a, 0x82, 0xbe,
+ 0xf9, 0x1c, 0x42, 0xb9, 0x7f, 0xe5, 0xfb, 0x09, 0xe5, 0xfe, 0xd5, 0xaf, 0x28, 0xa4, 0x45, 0x22,
+ 0xee, 0xfe, 0x8a, 0xec, 0x21, 0xac, 0xe4, 0x17, 0xf5, 0x68, 0xa8, 0x13, 0xd1, 0xef, 0xf3, 0x47,
+ 0x17, 0x2b, 0x66, 0x64, 0x13, 0x84, 0x51, 0xee, 0xa0, 0x15, 0x4a, 0x99, 0xdf, 0xd7, 0x48, 0xa2,
+ 0xec, 0xc9, 0x90, 0x49, 0x54, 0xbb, 0xe5, 0x2f, 0x10, 0xd5, 0xef, 0xfa, 0x0b, 0x44, 0x19, 0x1d,
+ 0x07, 0x3a, 0xda, 0x35, 0xb0, 0xd2, 0x64, 0xf9, 0x0e, 0x5b, 0x69, 0xb2, 0xe2, 0xde, 0x18, 0x5f,
+ 0x60, 0xa4, 0xd7, 0xf8, 0x69, 0x10, 0xcf, 0x48, 0x24, 0x83, 0xd4, 0x6f, 0x01, 0xa8, 0xf6, 0xb8,
+ 0x52, 0x66, 0xe9, 0xe2, 0x44, 0x19, 0x77, 0xa1, 0x9b, 0x8e, 0x2f, 0x32, 0xd2, 0xeb, 0x3c, 0xc6,
+ 0xb2, 0x2b, 0x0b, 0xa6, 0xce, 0xfb, 0xd6, 0xad, 0x7b, 0x16, 0x7a, 0x05, 0x7d, 0x85, 0x7f, 0x78,
+ 0x16, 0x79, 0xe7, 0xb1, 0x18, 0x55, 0x4d, 0x89, 0x0d, 0x5c, 0x61, 0x5c, 0x2e, 0x60, 0x64, 0x72,
+ 0x49, 0xcf, 0x22, 0x8f, 0xfa, 0xfd, 0xcf, 0xa0, 0xa3, 0x3d, 0xd0, 0x53, 0x72, 0x2a, 0xbf, 0xda,
+ 0x1b, 0x55, 0x35, 0xf0, 0xcd, 0xd3, 0x52, 0xd4, 0x48, 0xe9, 0xa9, 0x3b, 0xa3, 0xb4, 0x23, 0xe8,
+ 0x9b, 0x7d, 0x6a, 0x65, 0x96, 0x95, 0x4d, 0x6f, 0x65, 0x96, 0x0b, 0xda, 0xdb, 0xc6, 0x5e, 0x78,
+ 0x7b, 0x56, 0x3f, 0x9d, 0xa7, 0x34, 0x21, 0xc9, 0xdb, 0xd5, 0x7a, 0x42, 0x52, 0x6c, 0x89, 0xeb,
+ 0x09, 0x49, 0xa9, 0xbf, 0x6d, 0xee, 0x89, 0xb3, 0x91, 0x9a, 0x41, 0x09, 0xac, 0x16, 0x7a, 0xc9,
+ 0xa8, 0xb0, 0xea, 0x62, 0xfb, 0x79, 0xf4, 0xc1, 0xc2, 0x79, 0xc1, 0xef, 0x2a, 0xe3, 0x37, 0xc4,
+ 0xeb, 0x8a, 0x9f, 0x1b, 0x86, 0x5c, 0x4d, 0xfc, 0xec, 0x02, 0xd5, 0x19, 0x56, 0x76, 0x50, 0x6a,
+ 0x2e, 0x8f, 0x46, 0x55, 0x53, 0x82, 0x89, 0x61, 0x6d, 0x9c, 0x89, 0xcc, 0x40, 0xa6, 0xd0, 0xd1,
+ 0xfa, 0x95, 0x4a, 0x6e, 0xe5, 0x56, 0xa8, 0x92, 0x5b, 0x55, 0x83, 0xd3, 0x90, 0x5b, 0x4a, 0xb2,
+ 0x30, 0x3e, 0x62, 0x0d, 0x51, 0xca, 0xe3, 0x5b, 0x68, 0xcb, 0x4e, 0x27, 0xca, 0x3d, 0xa2, 0xd0,
+ 0x0e, 0x1d, 0x0d, 0xcb, 0x13, 0x05, 0x37, 0x64, 0x01, 0x35, 0x15, 0xb3, 0x94, 0xae, 0x03, 0xab,
+ 0x85, 0xbe, 0xa7, 0xd2, 0x47, 0x75, 0x43, 0x74, 0xd4, 0x33, 0xfe, 0x4d, 0x05, 0x5f, 0x62, 0xa4,
+ 0x37, 0x11, 0x93, 0x7e, 0x2a, 0x3f, 0x61, 0xff, 0x46, 0x92, 0xde, 0xb3, 0x10, 0xd1, 0x18, 0x14,
+ 0x15, 0x5e, 0xdd, 0xa7, 0x1d, 0x99, 0x0f, 0x19, 0xf9, 0x1d, 0xfe, 0x02, 0x36, 0x5c, 0xc9, 0xf7,
+ 0x2c, 0x34, 0x2b, 0x34, 0x61, 0x45, 0x37, 0x4f, 0x8b, 0xe4, 0x95, 0x3d, 0xda, 0x51, 0xd5, 0xfd,
+ 0x16, 0xfe, 0x01, 0xe3, 0x75, 0x09, 0x5d, 0x34, 0x78, 0x51, 0xb7, 0x94, 0xd7, 0x7b, 0xf7, 0x2c,
+ 0x34, 0x85, 0xbe, 0x49, 0xf2, 0xbd, 0x58, 0x15, 0xfc, 0x1f, 0xa1, 0x12, 0x2b, 0xca, 0xe3, 0x77,
+ 0xb5, 0xae, 0xb4, 0xd1, 0x7b, 0x46, 0x37, 0xaa, 0x79, 0x15, 0x7a, 0xd3, 0xa3, 0x0d, 0x9d, 0xa7,
+ 0x9c, 0xc4, 0x98, 0x31, 0xbd, 0x8c, 0x46, 0x65, 0xa6, 0xae, 0xc0, 0x61, 0x21, 0xb4, 0xab, 0x77,
+ 0x45, 0x54, 0xae, 0x5a, 0xd1, 0x58, 0x51, 0xb9, 0x6a, 0x55, 0x23, 0x45, 0x2a, 0x8f, 0xe7, 0xaa,
+ 0xac, 0x6b, 0x72, 0xcc, 0x31, 0x78, 0xf2, 0x5d, 0xe8, 0x9e, 0x5c, 0x5e, 0xd0, 0x5f, 0x28, 0xa4,
+ 0x69, 0x95, 0xdd, 0x07, 0xe9, 0xa7, 0x68, 0x4d, 0xb2, 0x0a, 0xa2, 0x23, 0xde, 0x84, 0x40, 0x5f,
+ 0x41, 0x93, 0x95, 0xf6, 0x68, 0x43, 0x95, 0x41, 0xaa, 0x83, 0x30, 0xda, 0x2c, 0x40, 0xcd, 0x5c,
+ 0x04, 0xb3, 0xc3, 0x71, 0x1e, 0x89, 0x8a, 0x61, 0x0a, 0x7d, 0x9e, 0x0f, 0xcb, 0x02, 0x58, 0x79,
+ 0x65, 0xa1, 0x3e, 0x57, 0x5e, 0x59, 0xac, 0x95, 0xcd, 0x78, 0xcc, 0x53, 0xe2, 0x53, 0x81, 0x73,
+ 0xdf, 0xba, 0x35, 0x5d, 0x66, 0xff, 0xb8, 0xf6, 0xe9, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xb0,
+ 0x2f, 0x50, 0xfc, 0xe3, 0x36, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -5395,6 +5672,8 @@ type XudClient interface {
// Begin gracefully shutting down xud.
// shell: xucli shutdown
Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error)
+ // Subscribes to alerts such as low balance.
+ SubscribeAlerts(ctx context.Context, in *SubscribeAlertsRequest, opts ...grpc.CallOption) (Xud_SubscribeAlertsClient, error)
// Subscribes to orders being added to and removed from the order book. This call allows the client
// to maintain an up-to-date view of the order book. For example, an exchange that wants to show
// its users a real time view of the orders available to them would subscribe to this streaming
@@ -5702,8 +5981,40 @@ func (c *xudClient) Shutdown(ctx context.Context, in *ShutdownRequest, opts ...g
return out, nil
}
+func (c *xudClient) SubscribeAlerts(ctx context.Context, in *SubscribeAlertsRequest, opts ...grpc.CallOption) (Xud_SubscribeAlertsClient, error) {
+ stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[1], "/xudrpc.Xud/SubscribeAlerts", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &xudSubscribeAlertsClient{stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+type Xud_SubscribeAlertsClient interface {
+ Recv() (*Alert, error)
+ grpc.ClientStream
+}
+
+type xudSubscribeAlertsClient struct {
+ grpc.ClientStream
+}
+
+func (x *xudSubscribeAlertsClient) Recv() (*Alert, error) {
+ m := new(Alert)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
func (c *xudClient) SubscribeOrders(ctx context.Context, in *SubscribeOrdersRequest, opts ...grpc.CallOption) (Xud_SubscribeOrdersClient, error) {
- stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[1], "/xudrpc.Xud/SubscribeOrders", opts...)
+ stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[2], "/xudrpc.Xud/SubscribeOrders", opts...)
if err != nil {
return nil, err
}
@@ -5735,7 +6046,7 @@ func (x *xudSubscribeOrdersClient) Recv() (*OrderUpdate, error) {
}
func (c *xudClient) SubscribeSwapFailures(ctx context.Context, in *SubscribeSwapsRequest, opts ...grpc.CallOption) (Xud_SubscribeSwapFailuresClient, error) {
- stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[2], "/xudrpc.Xud/SubscribeSwapFailures", opts...)
+ stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[3], "/xudrpc.Xud/SubscribeSwapFailures", opts...)
if err != nil {
return nil, err
}
@@ -5767,7 +6078,7 @@ func (x *xudSubscribeSwapFailuresClient) Recv() (*SwapFailure, error) {
}
func (c *xudClient) SubscribeSwaps(ctx context.Context, in *SubscribeSwapsRequest, opts ...grpc.CallOption) (Xud_SubscribeSwapsClient, error) {
- stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[3], "/xudrpc.Xud/SubscribeSwaps", opts...)
+ stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[4], "/xudrpc.Xud/SubscribeSwaps", opts...)
if err != nil {
return nil, err
}
@@ -5799,7 +6110,7 @@ func (x *xudSubscribeSwapsClient) Recv() (*SwapSuccess, error) {
}
func (c *xudClient) SubscribeSwapsAccepted(ctx context.Context, in *SubscribeSwapsAcceptedRequest, opts ...grpc.CallOption) (Xud_SubscribeSwapsAcceptedClient, error) {
- stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[4], "/xudrpc.Xud/SubscribeSwapsAccepted", opts...)
+ stream, err := c.cc.NewStream(ctx, &_Xud_serviceDesc.Streams[5], "/xudrpc.Xud/SubscribeSwapsAccepted", opts...)
if err != nil {
return nil, err
}
@@ -5967,6 +6278,8 @@ type XudServer interface {
// Begin gracefully shutting down xud.
// shell: xucli shutdown
Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error)
+ // Subscribes to alerts such as low balance.
+ SubscribeAlerts(*SubscribeAlertsRequest, Xud_SubscribeAlertsServer) error
// Subscribes to orders being added to and removed from the order book. This call allows the client
// to maintain an up-to-date view of the order book. For example, an exchange that wants to show
// its users a real time view of the orders available to them would subscribe to this streaming
@@ -6493,6 +6806,27 @@ func _Xud_Shutdown_Handler(srv interface{}, ctx context.Context, dec func(interf
return interceptor(ctx, in, info, handler)
}
+func _Xud_SubscribeAlerts_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(SubscribeAlertsRequest)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(XudServer).SubscribeAlerts(m, &xudSubscribeAlertsServer{stream})
+}
+
+type Xud_SubscribeAlertsServer interface {
+ Send(*Alert) error
+ grpc.ServerStream
+}
+
+type xudSubscribeAlertsServer struct {
+ grpc.ServerStream
+}
+
+func (x *xudSubscribeAlertsServer) Send(m *Alert) error {
+ return x.ServerStream.SendMsg(m)
+}
+
func _Xud_SubscribeOrders_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeOrdersRequest)
if err := stream.RecvMsg(m); err != nil {
@@ -6780,6 +7114,11 @@ var _Xud_serviceDesc = grpc.ServiceDesc{
Handler: _Xud_PlaceOrder_Handler,
ServerStreams: true,
},
+ {
+ StreamName: "SubscribeAlerts",
+ Handler: _Xud_SubscribeAlerts_Handler,
+ ServerStreams: true,
+ },
{
StreamName: "SubscribeOrders",
Handler: _Xud_SubscribeOrders_Handler,