diff --git a/docs/api.md b/docs/api.md index 03a2082cf..702178c0f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -231,6 +231,8 @@ | node_identifier | [string](#string) | | The node pub key or alias of the peer with which to close any channels with. | | currency | [string](#string) | | The ticker symbol of the currency of the channel to close. | | force | [bool](#bool) | | Whether to force close the channel in case the peer is offline or unresponsive. | +| destination | [string](#string) | | The on-chain address to send funds extracted from the channel. If unspecified, the funds return to the default wallet for the client closing the channel. | +| amount | [uint64](#uint64) | | For Connext only - the amount to extract from the channel. If 0 or unspecified, the entire off-chain balance for the specified currency will be extracted. | @@ -1441,7 +1443,7 @@ The primary service for interacting with a running xud node. | Ban | [BanRequest](#xudrpc.BanRequest) | [BanResponse](#xudrpc.BanResponse) | Bans a node and immediately disconnects from it. This can be used to prevent any connections to a specific node. shell: xucli ban <node_identifier> | | CloseChannel | [CloseChannelRequest](#xudrpc.CloseChannelRequest) | [CloseChannelResponse](#xudrpc.CloseChannelResponse) | Closes any existing payment channels with a peer for the specified currency. shell: xucli closechannel <node_identifier> <currency> [--force] | | Connect | [ConnectRequest](#xudrpc.ConnectRequest) | [ConnectResponse](#xudrpc.ConnectResponse) | Attempts to connect to a node. Once connected, the node is added to the list of peers and becomes available for swaps and trading. A handshake exchanges information about the peer's supported trading and swap clients. Orders will be shared with the peer upon connection and upon new order placements. shell: xucli connect <node_uri> | -| Deposit | [DepositRequest](#xudrpc.DepositRequest) | [DepositResponse](#xudrpc.DepositResponse) | Gets an address to deposit a given currency into the xud wallets. shell: xucli deposit <currency> | +| WalletDeposit | [DepositRequest](#xudrpc.DepositRequest) | [DepositResponse](#xudrpc.DepositResponse) | Gets an address to deposit a given currency into the xud wallets. shell: xucli deposit <currency> | | DiscoverNodes | [DiscoverNodesRequest](#xudrpc.DiscoverNodesRequest) | [DiscoverNodesResponse](#xudrpc.DiscoverNodesResponse) | Discover nodes from a specific peer and apply new connections | | GetBalance | [GetBalanceRequest](#xudrpc.GetBalanceRequest) | [GetBalanceResponse](#xudrpc.GetBalanceResponse) | Gets the total balance available across all payment channels and wallets for one or all currencies. shell: xucli getbalance [currency] | | GetInfo | [GetInfoRequest](#xudrpc.GetInfoRequest) | [GetInfoResponse](#xudrpc.GetInfoResponse) | Gets general information about this node. shell: xucli getinfo | @@ -1464,7 +1466,7 @@ The primary service for interacting with a running xud node. | 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. | | TradingLimits | [TradingLimitsRequest](#xudrpc.TradingLimitsRequest) | [TradingLimitsResponse](#xudrpc.TradingLimitsResponse) | Gets the trading limits for one or all currencies. shell: xucli tradinglimits [currency] | | Unban | [UnbanRequest](#xudrpc.UnbanRequest) | [UnbanResponse](#xudrpc.UnbanResponse) | Removes a ban from a node manually and, optionally, attempts to connect to it. shell: xucli unban <node_identifier> [reconnect] | -| Withdraw | [WithdrawRequest](#xudrpc.WithdrawRequest) | [WithdrawResponse](#xudrpc.WithdrawResponse) | Withdraws a given currency from the xud wallets to a specified address. shell: xucli withdraw <amount> <currency> <destination> [fee] | +| WalletWithdraw | [WithdrawRequest](#xudrpc.WithdrawRequest) | [WithdrawResponse](#xudrpc.WithdrawResponse) | Withdraws a given currency from the xud wallets to a specified address. shell: xucli withdraw <amount> <currency> <destination> [fee] | diff --git a/lib/cli/commands/closechannel.ts b/lib/cli/commands/closechannel.ts index b1a281176..3d6714cbd 100644 --- a/lib/cli/commands/closechannel.ts +++ b/lib/cli/commands/closechannel.ts @@ -2,31 +2,48 @@ import { Arguments, Argv } from 'yargs'; import { CloseChannelRequest } from '../../proto/xudrpc_pb'; import { callback, loadXudClient } from '../command'; -export const command = 'closechannel [--force]'; +export const command = 'closechannel [node_identifier ] [--force]'; export const describe = 'close any payment channels with a peer'; export const builder = (argv: Argv) => argv - .positional('node_identifier', { - description: 'the node key or alias of the connected peer to close the channel with', - type: 'string', - }) .positional('currency', { description: 'the ticker symbol for the currency', type: 'string', }) + .option('node_identifier', { + description: 'the node key or alias of the connected peer to close the channel with', + type: 'string', + }) .option('force', { type: 'boolean', description: 'whether to force close if the peer is offline', }) - .example('$0 closechannel 028599d05b18c0c3f8028915a17d603416f7276c822b6b2d20e71a3502bd0f9e0b BTC', 'close BTC channels by node key') - .example('$0 closechannel CheeseMonkey BTC', 'close BTC channels by alias') - .example('$0 closechannel CheeseMonkey BTC --force', 'force close BTC channels by alias'); + .option('destination', { + type: 'string', + description: 'the on-chain address to send funds extracted from the channel', + }) + .option('amount', { + type: 'number', + description: 'for Connext only - the amount to extract from the channel', + }) + .example('$0 closechannel BTC 028599d05b18c0c3f8028915a17d603416f7276c822b6b2d20e71a3502bd0f9e0b', 'close BTC channels by node key') + .example('$0 closechannel BTC CheeseMonkey', 'close BTC channels by alias') + .example('$0 closechannel BTC CheeseMonkey --force', 'force close BTC channels by alias') + .example('$0 closechannel ETH --amount 0.1', '[UNIMPLEMENTED] remove 0.1 ETH from a Connext channel'); export const handler = async (argv: Arguments) => { const request = new CloseChannelRequest(); - request.setNodeIdentifier(argv.node_identifier); + if (argv.node_identifier) { + request.setNodeIdentifier(argv.node_identifier); + } request.setCurrency(argv.currency.toUpperCase()); + if (argv.destination) { + request.setDestination(argv.destination); + } + if (argv.amount) { + request.setAmount(argv.amount); + } if (argv.force) { request.setForce(argv.force); } diff --git a/lib/cli/commands/openchannel.ts b/lib/cli/commands/openchannel.ts index 7de405300..9f934a8b0 100644 --- a/lib/cli/commands/openchannel.ts +++ b/lib/cli/commands/openchannel.ts @@ -27,7 +27,8 @@ export const builder = (argv: Argv) => argv }) .example('$0 openchannel BTC 0.1 028599d05b18c0c3f8028915a17d603416f7276c822b6b2d20e71a3502bd0f9e0b', 'open an 0.1 BTC channel by node key') .example('$0 openchannel BTC 0.1 CheeseMonkey', 'open an 0.1 BTC channel by alias') - .example('$0 openchannel BTC 0.1 CheeseMonkey 0.05', 'open an 0.1 BTC channel by alias and push 0.05 to remote side'); + .example('$0 openchannel BTC 0.1 CheeseMonkey 0.05', 'open an 0.1 BTC channel by alias and push 0.05 to remote side') + .example('$0 openchannel ETH 0.5', 'deposit 0.5 into an ETH Connext channel without specifying a remote node'); export const handler = async (argv: Arguments) => { const request = new OpenChannelRequest(); diff --git a/lib/cli/commands/deposit.ts b/lib/cli/commands/walletdeposit.ts similarity index 82% rename from lib/cli/commands/deposit.ts rename to lib/cli/commands/walletdeposit.ts index 65a6ea80c..87a628c95 100644 --- a/lib/cli/commands/deposit.ts +++ b/lib/cli/commands/walletdeposit.ts @@ -2,7 +2,7 @@ import { Arguments, Argv } from 'yargs'; import { DepositRequest } from '../../proto/xudrpc_pb'; import { callback, loadXudClient } from '../command'; -export const command = 'deposit '; +export const command = 'walletdeposit '; export const describe = 'gets an address to deposit funds to xud'; @@ -16,5 +16,5 @@ export const builder = (argv: Argv) => argv export const handler = async (argv: Arguments) => { const request = new DepositRequest(); request.setCurrency(argv.currency); - (await loadXudClient(argv)).deposit(request, callback(argv)); + (await loadXudClient(argv)).walletDeposit(request, callback(argv)); }; diff --git a/lib/cli/commands/withdraw.ts b/lib/cli/commands/walletwithdraw.ts similarity index 90% rename from lib/cli/commands/withdraw.ts rename to lib/cli/commands/walletwithdraw.ts index 59f7ae10e..b56cf764e 100644 --- a/lib/cli/commands/withdraw.ts +++ b/lib/cli/commands/walletwithdraw.ts @@ -2,7 +2,7 @@ import { Arguments, Argv } from 'yargs'; import { WithdrawRequest } from '../../proto/xudrpc_pb'; import { callback, loadXudClient } from '../command'; -export const command = 'withdraw [amount] [currency] [destination] [fee]'; +export const command = 'walletwithdraw [amount] [currency] [destination] [fee]'; export const describe = 'withdraws on-chain funds from xud'; @@ -42,5 +42,5 @@ export const handler = async (argv: Arguments) => { request.setDestination(argv.destination); request.setFee(argv.fee); - (await loadXudClient(argv)).withdraw(request, callback(argv)); + (await loadXudClient(argv)).walletWithdraw(request, callback(argv)); }; diff --git a/lib/connextclient/ConnextClient.ts b/lib/connextclient/ConnextClient.ts index 242069c97..543ac5de7 100644 --- a/lib/connextclient/ConnextClient.ts +++ b/lib/connextclient/ConnextClient.ts @@ -13,7 +13,7 @@ import SwapClient, { SwapClientInfo, PaymentStatus, } from '../swaps/SwapClient'; -import { SwapDeal } from '../swaps/types'; +import { SwapDeal, CloseChannelParams, OpenChannelParams } from '../swaps/types'; import { UnitConverter } from '../utils/UnitConverter'; import errors, { errorCodes } from './errors'; import { @@ -548,13 +548,15 @@ class ConnextClient extends SwapClient { }; } - /** - * Deposits funds to a node - */ - public deposit = async ( - { currency, units }: - { currency: string, units: number }, - ) => { + public deposit = async () => { + const clientConfig = await this.getClientConfig(); + return clientConfig.signerAddress; + } + + public openChannel = async ({ currency, units }: OpenChannelParams) => { + if (!currency) { + throw errors.CURRENCY_MISSING; + } const assetId = this.getTokenAddress(currency); await this.sendRequest('/deposit', 'POST', { assetId, @@ -562,14 +564,17 @@ class ConnextClient extends SwapClient { }); } - public async openChannel() {} - - /** - * Closes a payment client. - * @param multisigAddress the address of the client to close - */ - public closeChannel = async (): Promise => { - // not relevant for connext + public closeChannel = async ({ units, currency, destination }: CloseChannelParams): Promise => { + if (!currency) { + throw errors.CURRENCY_MISSING; + } + const amount = units || (await this.channelBalance(currency)).balance; + // TODO: connext-api-client withdraw endpoint not currently implemented + await this.sendRequest('/withdraw', 'POST', { + recipient: destination, + amount: BigInt(amount).toString(), + assetId: this.tokenAddresses.get(currency), + }); } /** diff --git a/lib/grpc/GrpcService.ts b/lib/grpc/GrpcService.ts index 5fe806865..3ca814d1e 100644 --- a/lib/grpc/GrpcService.ts +++ b/lib/grpc/GrpcService.ts @@ -360,15 +360,16 @@ class GrpcService { } /** - * See [[Service.deposit]] + * See [[Service.walletDeposit]] */ - public deposit: grpc.handleUnaryCall = async (call, callback) => { + public walletDeposit: grpc.handleUnaryCall = async (call, callback) => { if (!this.isReady(this.service, callback)) { return; } try { - await this.service.deposit(call.request.toObject()); + const address = await this.service.walletDeposit(call.request.toObject()); const response = new xudrpc.DepositResponse(); + response.setAddress(address); callback(null, response); } catch (err) { callback(getGrpcError(err), null); @@ -376,9 +377,9 @@ class GrpcService { } /** - * See [[Service.withdraw]] + * See [[Service.walletWithdraw]] */ - public withdraw: grpc.handleUnaryCall = async (call, callback) => { + public walletWithdraw: grpc.handleUnaryCall = async (call, callback) => { if (!this.isReady(this.service, callback)) { return; } diff --git a/lib/lndclient/LndClient.ts b/lib/lndclient/LndClient.ts index 93ef44753..928dddc5c 100644 --- a/lib/lndclient/LndClient.ts +++ b/lib/lndclient/LndClient.ts @@ -10,7 +10,7 @@ import { LightningClient, WalletUnlockerClient } from '../proto/lndrpc_grpc_pb'; import * as lndrpc from '../proto/lndrpc_pb'; import swapErrors from '../swaps/errors'; import SwapClient, { ChannelBalance, ClientStatus, PaymentState, SwapClientInfo, TradingLimits } from '../swaps/SwapClient'; -import { SwapDeal } from '../swaps/types'; +import { SwapDeal, CloseChannelParams, OpenChannelParams } from '../swaps/types'; import { base64ToHex, hexToUint8Array } from '../utils/utils'; import errors from './errors'; import { Chain, ChannelCount, ClientMethods, LndClientConfig, LndInfo } from './types'; @@ -519,6 +519,11 @@ class LndClient extends SwapClient { return this.unaryCall('closedChannels', new lndrpc.ClosedChannelsRequest()); } + public deposit = async () => { + const depositAddress = await this.newAddress(); + return depositAddress; + } + public withdraw = async ({ amount, destination, all = false, fee }: { amount: number, destination: string, @@ -653,7 +658,7 @@ class LndClient extends SwapClient { /** * Gets a new address for the internal lnd wallet. */ - public newAddress = async (addressType = lndrpc.AddressType.WITNESS_PUBKEY_HASH) => { + private newAddress = async (addressType = lndrpc.AddressType.WITNESS_PUBKEY_HASH) => { const request = new lndrpc.NewAddressRequest(); request.setType(addressType); const newAddressResponse = await this.unaryCall('newAddress', request); @@ -739,14 +744,17 @@ class LndClient extends SwapClient { * Opens a channel given peerPubKey and amount. */ public openChannel = async ( - { peerIdentifier: peerPubKey, units, uris, pushUnits = 0 }: - { peerIdentifier: string, units: number, uris?: string[], pushUnits?: number }, + { remoteIdentifier, units, uris, pushUnits = 0 }: OpenChannelParams, ): Promise => { + if (!remoteIdentifier) { + // TODO: better handling for for unrecognized peers & force closing channels + throw new Error('peer not connected to swap client'); + } if (uris) { await this.connectPeerAddresses(uris); } - await this.openChannelSync(peerPubKey, units, pushUnits); + await this.openChannelSync(remoteIdentifier, units, pushUnits); } /** @@ -1025,13 +1033,29 @@ class LndClient extends SwapClient { } /** - * Attempts to close an open channel. + * Closes any payment channels with a specified node. */ - public closeChannel = (fundingTxId: string, outputIndex: number, force: boolean): Promise => { + public closeChannel = async ({ remoteIdentifier, force = false }: CloseChannelParams) => { + const channels = (await this.listChannels()).getChannelsList(); + const closePromises: Promise[] = []; + channels.forEach((channel) => { + if (channel.getRemotePubkey() === remoteIdentifier) { + const [fundingTxId, outputIndex] = channel.getChannelPoint().split(':'); + const closePromise = this.closeChannelSync(fundingTxId, Number(outputIndex), force); + closePromises.push(closePromise); + } + }); + await Promise.all(closePromises); + } + + /** A synchronous helper method for the closeChannel call */ + public closeChannelSync = (fundingTxId: string, outputIndex: number, force: boolean): Promise => { return new Promise((resolve, reject) => { if (!this.lightning) { throw(errors.UNAVAILABLE(this.currency, this.status)); } + + // TODO: set delivery_address parameter after upgrading to 0.10+ lnd API proto definition const request = new lndrpc.CloseChannelRequest(); const channelPoint = new lndrpc.ChannelPoint(); channelPoint.setFundingTxidStr(fundingTxId); diff --git a/lib/proto/xudrpc.swagger.json b/lib/proto/xudrpc.swagger.json index 752b863a0..5c6858354 100644 --- a/lib/proto/xudrpc.swagger.json +++ b/lib/proto/xudrpc.swagger.json @@ -183,33 +183,6 @@ ] } }, - "/v1/deposit": { - "post": { - "summary": "Gets an address to deposit a given currency into the xud wallets.\nshell: xucli deposit \u003ccurrency\u003e", - "operationId": "Deposit", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/xudrpcDepositResponse" - } - } - }, - "parameters": [ - { - "name": "body", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/xudrpcDepositRequest" - } - } - ], - "tags": [ - "Xud" - ] - } - }, "/v1/discovernodes": { "post": { "summary": "Discover nodes from a specific peer and apply new connections", @@ -736,10 +709,37 @@ ] } }, - "/v1/withdraw": { + "/v1/walletdeposit": { + "post": { + "summary": "Gets an address to deposit a given currency into the xud wallets.\nshell: xucli deposit \u003ccurrency\u003e", + "operationId": "WalletDeposit", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/xudrpcDepositResponse" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/xudrpcDepositRequest" + } + } + ], + "tags": [ + "Xud" + ] + } + }, + "/v1/walletwithdraw": { "post": { "summary": "Withdraws a given currency from the xud wallets to a specified address.\nshell: xucli withdraw \u003camount\u003e \u003ccurrency\u003e \u003cdestination\u003e [fee]", - "operationId": "Withdraw", + "operationId": "WalletWithdraw", "responses": { "200": { "description": "A successful response.", diff --git a/lib/proto/xudrpc_grpc_pb.d.ts b/lib/proto/xudrpc_grpc_pb.d.ts index ede6d57a8..56e9fede0 100644 --- a/lib/proto/xudrpc_grpc_pb.d.ts +++ b/lib/proto/xudrpc_grpc_pb.d.ts @@ -80,7 +80,7 @@ interface IXudService extends grpc.ServiceDefinition { @@ -151,8 +151,8 @@ interface IXudService_IConnect extends grpc.MethodDefinition; responseDeserialize: grpc.deserialize; } -interface IXudService_IDeposit extends grpc.MethodDefinition { - path: string; // "/xudrpc.Xud/Deposit" +interface IXudService_IWalletDeposit extends grpc.MethodDefinition { + path: string; // "/xudrpc.Xud/WalletDeposit" requestStream: boolean; // false responseStream: boolean; // false requestSerialize: grpc.serialize; @@ -358,8 +358,8 @@ interface IXudService_IUnban extends grpc.MethodDefinition; responseDeserialize: grpc.deserialize; } -interface IXudService_IWithdraw extends grpc.MethodDefinition { - path: string; // "/xudrpc.Xud/Withdraw" +interface IXudService_IWalletWithdraw extends grpc.MethodDefinition { + path: string; // "/xudrpc.Xud/WalletWithdraw" requestStream: boolean; // false responseStream: boolean; // false requestSerialize: grpc.serialize; @@ -376,7 +376,7 @@ export interface IXudServer { ban: grpc.handleUnaryCall; closeChannel: grpc.handleUnaryCall; connect: grpc.handleUnaryCall; - deposit: grpc.handleUnaryCall; + walletDeposit: grpc.handleUnaryCall; discoverNodes: grpc.handleUnaryCall; getBalance: grpc.handleUnaryCall; getInfo: grpc.handleUnaryCall; @@ -399,7 +399,7 @@ export interface IXudServer { subscribeSwapFailures: grpc.handleServerStreamingCall; tradingLimits: grpc.handleUnaryCall; unban: grpc.handleUnaryCall; - withdraw: grpc.handleUnaryCall; + walletWithdraw: grpc.handleUnaryCall; } export interface IXudClient { @@ -418,9 +418,9 @@ export interface IXudClient { connect(request: xudrpc_pb.ConnectRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ConnectResponse) => void): grpc.ClientUnaryCall; connect(request: xudrpc_pb.ConnectRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ConnectResponse) => void): grpc.ClientUnaryCall; connect(request: xudrpc_pb.ConnectRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ConnectResponse) => void): grpc.ClientUnaryCall; - deposit(request: xudrpc_pb.DepositRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; - deposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; - deposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; + walletDeposit(request: xudrpc_pb.DepositRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; + walletDeposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; + walletDeposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; discoverNodes(request: xudrpc_pb.DiscoverNodesRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DiscoverNodesResponse) => void): grpc.ClientUnaryCall; discoverNodes(request: xudrpc_pb.DiscoverNodesRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DiscoverNodesResponse) => void): grpc.ClientUnaryCall; discoverNodes(request: xudrpc_pb.DiscoverNodesRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DiscoverNodesResponse) => void): grpc.ClientUnaryCall; @@ -483,9 +483,9 @@ export interface IXudClient { unban(request: xudrpc_pb.UnbanRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.UnbanResponse) => void): grpc.ClientUnaryCall; unban(request: xudrpc_pb.UnbanRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.UnbanResponse) => void): grpc.ClientUnaryCall; unban(request: xudrpc_pb.UnbanRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.UnbanResponse) => void): grpc.ClientUnaryCall; - withdraw(request: xudrpc_pb.WithdrawRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; - withdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; - withdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; + walletWithdraw(request: xudrpc_pb.WithdrawRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; + walletWithdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; + walletWithdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; } export class XudClient extends grpc.Client implements IXudClient { @@ -505,9 +505,9 @@ export class XudClient extends grpc.Client implements IXudClient { public connect(request: xudrpc_pb.ConnectRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ConnectResponse) => void): grpc.ClientUnaryCall; public connect(request: xudrpc_pb.ConnectRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ConnectResponse) => void): grpc.ClientUnaryCall; public connect(request: xudrpc_pb.ConnectRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.ConnectResponse) => void): grpc.ClientUnaryCall; - public deposit(request: xudrpc_pb.DepositRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; - public deposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; - public deposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; + public walletDeposit(request: xudrpc_pb.DepositRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; + public walletDeposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; + public walletDeposit(request: xudrpc_pb.DepositRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DepositResponse) => void): grpc.ClientUnaryCall; public discoverNodes(request: xudrpc_pb.DiscoverNodesRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DiscoverNodesResponse) => void): grpc.ClientUnaryCall; public discoverNodes(request: xudrpc_pb.DiscoverNodesRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DiscoverNodesResponse) => void): grpc.ClientUnaryCall; public discoverNodes(request: xudrpc_pb.DiscoverNodesRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.DiscoverNodesResponse) => void): grpc.ClientUnaryCall; @@ -570,7 +570,7 @@ export class XudClient extends grpc.Client implements IXudClient { public unban(request: xudrpc_pb.UnbanRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.UnbanResponse) => void): grpc.ClientUnaryCall; public unban(request: xudrpc_pb.UnbanRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.UnbanResponse) => void): grpc.ClientUnaryCall; public unban(request: xudrpc_pb.UnbanRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.UnbanResponse) => void): grpc.ClientUnaryCall; - public withdraw(request: xudrpc_pb.WithdrawRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; - public withdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; - public withdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; + public walletWithdraw(request: xudrpc_pb.WithdrawRequest, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; + public walletWithdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; + public walletWithdraw(request: xudrpc_pb.WithdrawRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: xudrpc_pb.WithdrawResponse) => void): grpc.ClientUnaryCall; } diff --git a/lib/proto/xudrpc_grpc_pb.js b/lib/proto/xudrpc_grpc_pb.js index a05fff963..00264f3be 100644 --- a/lib/proto/xudrpc_grpc_pb.js +++ b/lib/proto/xudrpc_grpc_pb.js @@ -819,8 +819,8 @@ var XudService = exports.XudService = { }, // Gets an address to deposit a given currency into the xud wallets. // shell: xucli deposit - deposit: { - path: '/xudrpc.Xud/Deposit', + walletDeposit: { + path: '/xudrpc.Xud/WalletDeposit', requestStream: false, responseStream: false, requestType: xudrpc_pb.DepositRequest, @@ -1135,8 +1135,8 @@ var XudService = exports.XudService = { }, // Withdraws a given currency from the xud wallets to a specified address. // shell: xucli withdraw [fee] - withdraw: { - path: '/xudrpc.Xud/Withdraw', + walletWithdraw: { + path: '/xudrpc.Xud/WalletWithdraw', requestStream: false, responseStream: false, requestType: xudrpc_pb.WithdrawRequest, diff --git a/lib/proto/xudrpc_pb.d.ts b/lib/proto/xudrpc_pb.d.ts index 044d7c2cb..3dadd8335 100644 --- a/lib/proto/xudrpc_pb.d.ts +++ b/lib/proto/xudrpc_pb.d.ts @@ -212,6 +212,12 @@ export class CloseChannelRequest extends jspb.Message { getForce(): boolean; setForce(value: boolean): void; + getDestination(): string; + setDestination(value: string): void; + + getAmount(): number; + setAmount(value: number): void; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): CloseChannelRequest.AsObject; @@ -228,6 +234,8 @@ export namespace CloseChannelRequest { nodeIdentifier: string, currency: string, force: boolean, + destination: string, + amount: number, } } diff --git a/lib/proto/xudrpc_pb.js b/lib/proto/xudrpc_pb.js index 74bae1dd0..87a0129a6 100644 --- a/lib/proto/xudrpc_pb.js +++ b/lib/proto/xudrpc_pb.js @@ -1469,7 +1469,9 @@ proto.xudrpc.CloseChannelRequest.toObject = function(includeInstance, msg) { var f, obj = { nodeIdentifier: jspb.Message.getFieldWithDefault(msg, 1, ""), currency: jspb.Message.getFieldWithDefault(msg, 2, ""), - force: jspb.Message.getFieldWithDefault(msg, 3, false) + force: jspb.Message.getFieldWithDefault(msg, 3, false), + destination: jspb.Message.getFieldWithDefault(msg, 4, ""), + amount: jspb.Message.getFieldWithDefault(msg, 5, 0) }; if (includeInstance) { @@ -1518,6 +1520,14 @@ proto.xudrpc.CloseChannelRequest.deserializeBinaryFromReader = function(msg, rea var value = /** @type {boolean} */ (reader.readBool()); msg.setForce(value); break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setDestination(value); + break; + case 5: + var value = /** @type {number} */ (reader.readUint64()); + msg.setAmount(value); + break; default: reader.skipField(); break; @@ -1568,6 +1578,20 @@ proto.xudrpc.CloseChannelRequest.serializeBinaryToWriter = function(message, wri f ); } + f = message.getDestination(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getAmount(); + if (f !== 0) { + writer.writeUint64( + 5, + f + ); + } }; @@ -1618,6 +1642,36 @@ proto.xudrpc.CloseChannelRequest.prototype.setForce = function(value) { }; +/** + * optional string destination = 4; + * @return {string} + */ +proto.xudrpc.CloseChannelRequest.prototype.getDestination = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** @param {string} value */ +proto.xudrpc.CloseChannelRequest.prototype.setDestination = function(value) { + jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional uint64 amount = 5; + * @return {number} + */ +proto.xudrpc.CloseChannelRequest.prototype.getAmount = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** @param {number} value */ +proto.xudrpc.CloseChannelRequest.prototype.setAmount = function(value) { + jspb.Message.setProto3IntField(this, 5, value); +}; + + /** * Generated by JsPbCodeGenerator. diff --git a/lib/raidenclient/RaidenClient.ts b/lib/raidenclient/RaidenClient.ts index e076ba986..8b8da3bb9 100644 --- a/lib/raidenclient/RaidenClient.ts +++ b/lib/raidenclient/RaidenClient.ts @@ -526,7 +526,7 @@ class RaidenClient extends SwapClient { * Creates a payment channel. */ public openChannel = async ( - { peerIdentifier: peerAddress, units, currency }: + { peerIdentifier, units, currency }: { peerIdentifier: string, units: number, currency: string }, ): Promise => { const tokenAddress = this.tokenAddresses.get(currency); @@ -534,7 +534,7 @@ class RaidenClient extends SwapClient { throw(errors.TOKEN_ADDRESS_NOT_FOUND); } await this.openChannelRequest({ - partner_address: peerAddress, + partner_address: peerIdentifier, token_address: tokenAddress, total_deposit: units, settle_timeout: 20660, @@ -557,11 +557,15 @@ class RaidenClient extends SwapClient { * Closes a payment channel. * @param channel_address the address of the channel to close */ - public closeChannel = async (channel_address: string): Promise => { + public closeChannelRequest = async (channel_address: string): Promise => { const endpoint = `channels/${channel_address}`; await this.sendRequest(endpoint, 'PATCH', { state: 'settled' }); } + public closeChannel = async () => { + // unimplemented + } + /** * Sends a token payment through the Raiden network. * @param target_address recipient of the payment @@ -601,6 +605,11 @@ class RaidenClient extends SwapClient { return body.our_address; } + public deposit = async () => { + const depositAddress = await this.getAddress(); + return depositAddress; + } + /** Raiden client specific cleanup. */ protected disconnect = () => { this.setStatus(ClientStatus.Disconnected); diff --git a/lib/service/Service.ts b/lib/service/Service.ts index a506e5f11..35c6d79bb 100644 --- a/lib/service/Service.ts +++ b/lib/service/Service.ts @@ -207,7 +207,7 @@ class Service { await this.pool.addOutbound({ host, port }, nodePubKey, retryConnecting, true); } - public deposit = async (args: { currency: string }) => { + public walletDeposit = async (args: { currency: string }) => { const { currency } = args; const address = await this.swapClientManager.deposit(currency); return address; @@ -222,18 +222,28 @@ class Service { * Closes any payment channels for a specified node and currency. */ public closeChannel = async ( - args: { nodeIdentifier: string, currency: string, force: boolean }, + args: { nodeIdentifier: string, currency: string, force: boolean, destination: string, amount: number }, ) => { - const { nodeIdentifier, currency, force } = args; - argChecks.HAS_NODE_IDENTIFIER({ nodeIdentifier }); + const { nodeIdentifier, currency, force, destination, amount } = args; argChecks.VALID_CURRENCY({ currency }); - const nodePubKey = isNodePubKey(args.nodeIdentifier) ? args.nodeIdentifier : this.pool.resolveAlias(args.nodeIdentifier); - const peer = this.pool.getPeer(nodePubKey); + let remoteIdentifier: string | undefined; + if (nodeIdentifier) { + const nodePubKey = isNodePubKey(nodeIdentifier) ? nodeIdentifier : this.pool.resolveAlias(nodeIdentifier); + const swapClientType = this.swapClientManager.getType(currency); + if (swapClientType === undefined) { + throw swapsErrors.SWAP_CLIENT_NOT_FOUND(currency); + } + const peer = this.pool.getPeer(nodePubKey); + remoteIdentifier = peer.getIdentifier(swapClientType, currency); + } + await this.swapClientManager.closeChannel({ - peer, currency, force, + destination, + amount, + remoteIdentifier, }); } @@ -246,14 +256,27 @@ class Service { const { nodeIdentifier, amount, currency, pushAmount } = args; argChecks.POSITIVE_AMOUNT({ amount }); argChecks.VALID_CURRENCY({ currency }); + + let remoteIdentifier: string | undefined; + let uris: string[] | undefined; + try { - let peer; - if (args.nodeIdentifier) { - const nodePubKey = isNodePubKey(args.nodeIdentifier) ? args.nodeIdentifier : this.pool.resolveAlias(args.nodeIdentifier); - peer = this.pool.getPeer(nodePubKey); + if (nodeIdentifier) { + const nodePubKey = isNodePubKey(nodeIdentifier) ? nodeIdentifier : this.pool.resolveAlias(nodeIdentifier); + const swapClientType = this.swapClientManager.getType(currency); + if (swapClientType === undefined) { + throw swapsErrors.SWAP_CLIENT_NOT_FOUND(currency); + } + const peer = this.pool.getPeer(nodePubKey); + remoteIdentifier = peer.getIdentifier(swapClientType, currency); + if (swapClientType === SwapClientType.Lnd) { + uris = peer.getLndUris(currency); + } } + await this.swapClientManager.openChannel({ - peer, + remoteIdentifier, + uris, amount, currency, pushAmount, diff --git a/lib/swaps/SwapClient.ts b/lib/swaps/SwapClient.ts index 8bb832290..514dcae57 100644 --- a/lib/swaps/SwapClient.ts +++ b/lib/swaps/SwapClient.ts @@ -1,6 +1,6 @@ import Logger from '../Logger'; import { EventEmitter } from 'events'; -import { SwapDeal, Route } from './types'; +import { SwapDeal, Route, CloseChannelParams, OpenChannelParams } from './types'; import { SwapClientType } from '../constants/enums'; import { setTimeoutPromise } from '../utils/utils'; @@ -315,20 +315,22 @@ abstract class SwapClient extends EventEmitter { public abstract async getHeight(): Promise; /** - * Opens a payment channel given peerIdentifier, amount - * optional currency and optional lndUris. + * Opens a payment channel. */ public abstract async openChannel( - { peerIdentifier, units, currency, uris, pushUnits }: - { - peerIdentifier: string, - units: number, - currency?: string, - uris?: string[], - pushUnits?: number, - }, + { remoteIdentifier, units, currency, uris, pushUnits }: OpenChannelParams, ): Promise; + /** + * Closes a payment channel. + */ + public abstract async closeChannel( + { remoteIdentifier, units, currency, destination, force }: CloseChannelParams, + ): Promise; + + /** Gets a deposit address. */ + public abstract async deposit(): Promise; + public isConnected(): boolean { return this.status === ClientStatus.ConnectionVerified; } diff --git a/lib/swaps/SwapClientManager.ts b/lib/swaps/SwapClientManager.ts index 7829894c6..67a009116 100644 --- a/lib/swaps/SwapClientManager.ts +++ b/lib/swaps/SwapClientManager.ts @@ -1,6 +1,7 @@ import { EventEmitter } from 'events'; import { promises as fs } from 'fs'; import Config from '../Config'; +import ConnextClient from '../connextclient/ConnextClient'; import { SwapClientType } from '../constants/enums'; import { Models } from '../db/DB'; import lndErrors from '../lndclient/errors'; @@ -10,7 +11,6 @@ import { Loggers } from '../Logger'; import { Currency } from '../orderbook/types'; import Peer from '../p2p/Peer'; import RaidenClient from '../raidenclient/RaidenClient'; -import ConnextClient from '../connextclient/ConnextClient'; import { keystore } from '../utils/seedutil'; import { UnitConverter } from '../utils/UnitConverter'; import errors from './errors'; @@ -312,6 +312,10 @@ class SwapClientManager extends EventEmitter { return this.swapClients.get(currency); } + /** Gets the type of swap client for a given currency. */ + public getType = (currency: string) => { + return this.swapClients.get(currency)?.type; + } /** * Returns whether the swap client for a specified currency is connected. * @returns `true` if a swap client exists and is connected, otherwise `false` @@ -440,13 +444,9 @@ class SwapClientManager extends EventEmitter { if (!swapClient) { throw errors.SWAP_CLIENT_NOT_FOUND(currency); } - if (isLndClient(swapClient)) { - const address = await swapClient.newAddress(); - return address; - } else { - // TODO: generic deposit logic - throw new Error('currency currently not supported for fetching deposit addresses'); - } + + const address = await swapClient.deposit(); + return address; } public withdraw = async ({ currency, amount, destination, all, fee }: { @@ -470,49 +470,44 @@ class SwapClientManager extends EventEmitter { } /** - * Closes any payment channels with a peer for a given currency. - * @param peer a peer to open the payment channel with. + * Closes a payment channel. + * @param remoteIdentifier the identifier for the remote side of the channel. * @param currency a currency for the payment channel. - * @param amount the size of the payment channel local balance + * @param amount the amount to extract from the channel. If 0 or unspecified, + * the entire off-chain balance for the specified currency will be extracted. * @returns Nothing upon success, throws otherwise. */ public closeChannel = async ( - { peer, currency, force }: - { peer: Peer, currency: string, force: boolean }, + { remoteIdentifier, currency, force, destination, amount }: + { remoteIdentifier?: string, currency: string, force: boolean, destination?: string, amount?: number }, ): Promise => { const swapClient = this.get(currency); if (!swapClient) { throw errors.SWAP_CLIENT_NOT_FOUND(currency); } - const peerIdentifier = peer.getIdentifier(swapClient.type, currency); - if (!peerIdentifier) { - throw new Error('peer not connected to swap client'); - } - // TODO: temporarily we only support closing lnd channels, make this logic generic - if (isLndClient(swapClient)) { - const lndChannels = (await swapClient.listChannels()).getChannelsList(); - const closePromises: Promise[] = []; - lndChannels.forEach((channel) => { - if (channel.getRemotePubkey() === peerIdentifier) { - const [fundingTxId, outputIndex] = channel.getChannelPoint().split(':'); - const closePromise = swapClient.closeChannel(fundingTxId, Number(outputIndex), force); - closePromises.push(closePromise); - } - }); - await Promise.all(closePromises); - } + const units = amount ? this.unitConverter.amountToUnits({ + amount, + currency, + }) : undefined; + await swapClient.closeChannel({ + remoteIdentifier, + currency, + force, + destination, + units, + }); } /** * Opens a payment channel. - * @param peer a peer to open the payment channel with. + * @param remoteIdentifier the identifier for the remote side of the channel. * @param currency a currency for the payment channel. * @param amount the size of the payment channel local balance * @returns Nothing upon success, throws otherwise. */ public openChannel = async ( - { peer, amount, currency, pushAmount = 0 }: - { peer?: Peer, amount: number, currency: string, pushAmount?: number }, + { remoteIdentifier, amount, currency, pushAmount = 0, uris }: + { remoteIdentifier?: string, amount: number, currency: string, pushAmount?: number, uris?: string[] }, ): Promise => { const swapClient = this.get(currency); if (!swapClient) { @@ -527,23 +522,13 @@ class SwapClientManager extends EventEmitter { amount: pushAmount, }); - if (!peer) { - if (isConnextClient(swapClient)) { - await swapClient.deposit({ currency, units }); - return; - } else { - throw new Error('peerPubKey or alias must be specified'); - } - } - const peerIdentifier = peer.getIdentifier(swapClient.type, currency); - if (!peerIdentifier) { - throw new Error('peer not connected to swap client'); - } - let uris: string[] | undefined; - if (isLndClient(swapClient)) { - uris = peer.getLndUris(currency); - } - await swapClient.openChannel({ peerIdentifier, currency, units, uris, pushUnits }); + await swapClient.openChannel({ + remoteIdentifier, + currency, + units, + uris, + pushUnits, + }); } /** diff --git a/lib/swaps/types.ts b/lib/swaps/types.ts index 937c6246c..97828c1cd 100644 --- a/lib/swaps/types.ts +++ b/lib/swaps/types.ts @@ -107,3 +107,32 @@ export type ResolveRequest = { expiration: number, chain_height: number, }; + +export type CloseChannelParams = { + /** The remote node with which to close channels.. */ + remoteIdentifier?: string, + /** + * The amount to extract from the channel, if applicable. If 0 or unspecified, + * the entire off-chain balance for the specified currency will be extracted. + */ + units?: number, + currency?: string, + /** + * The on-chain address to send funds extracted from the channel. If unspecified + * the funds return to the default wallet for the client closing the channel. + */ + destination?: string, + force?: boolean, +}; + +export type OpenChannelParams = { + /** The remote node with which to open the channel. */ + remoteIdentifier?: string, + /** The size of the channel. */ + units: number, + currency?: string, + /** Uris with which to connect to the remote node. */ + uris?: string[], + /** The balance to assign to the remote node. */ + pushUnits?: number, +}; diff --git a/proto/xudrpc.proto b/proto/xudrpc.proto index 51e96e417..39acd314b 100644 --- a/proto/xudrpc.proto +++ b/proto/xudrpc.proto @@ -95,9 +95,9 @@ service Xud { /* Gets an address to deposit a given currency into the xud wallets. * shell: xucli deposit */ - rpc Deposit(DepositRequest) returns (DepositResponse) { + rpc WalletDeposit(DepositRequest) returns (DepositResponse) { option (google.api.http) = { - post: "/v1/deposit" + post: "/v1/walletdeposit" body: "*" }; } @@ -307,9 +307,9 @@ service Xud { /* Withdraws a given currency from the xud wallets to a specified address. * shell: xucli withdraw [fee] */ - rpc Withdraw(WithdrawRequest) returns (WithdrawResponse) { + rpc WalletWithdraw(WithdrawRequest) returns (WithdrawResponse) { option (google.api.http) = { - post: "/v1/withdraw" + post: "/v1/walletwithdraw" body: "*" }; } @@ -376,6 +376,12 @@ message CloseChannelRequest { string currency = 2 [json_name = "currency"]; // Whether to force close the channel in case the peer is offline or unresponsive. bool force = 3 [json_name = "force"]; + // The on-chain address to send funds extracted from the channel. If unspecified, + // the funds return to the default wallet for the client closing the channel. + string destination = 4 [json_name = "destination"]; + // For Connext only - the amount to extract from the channel. If 0 or unspecified, + // the entire off-chain balance for the specified currency will be extracted. + uint64 amount = 5 [json_name = "amount"]; } message CloseChannelResponse {} diff --git a/test/jest/LndClient.spec.ts b/test/jest/LndClient.spec.ts index e41db518d..085cd828c 100644 --- a/test/jest/LndClient.spec.ts +++ b/test/jest/LndClient.spec.ts @@ -76,7 +76,7 @@ describe('LndClient', () => { }); await lnd.openChannel({ units, - peerIdentifier: peerPubKey, + remoteIdentifier: peerPubKey, uris: lndListeningUris, }); expect(lnd['connectPeer']).toHaveBeenCalledTimes(2); @@ -96,7 +96,7 @@ describe('LndClient', () => { .mockImplementation(alreadyConnected); await lnd.openChannel({ units, - peerIdentifier: peerPubKey, + remoteIdentifier: peerPubKey, uris: lndListeningUris, }); expect(lnd['connectPeer']).toHaveBeenCalledTimes(1); @@ -118,7 +118,7 @@ describe('LndClient', () => { await lnd.openChannel({ units, pushUnits, - peerIdentifier: peerPubKey, + remoteIdentifier: peerPubKey, uris: lndListeningUris, }); expect(lnd['connectPeer']).toHaveBeenCalledTimes(1); @@ -138,7 +138,7 @@ describe('LndClient', () => { }); await lnd.openChannel({ units, - peerIdentifier: peerPubKey, + remoteIdentifier: peerPubKey, uris: lndListeningUris, }); expect(lnd['connectPeer']).toHaveBeenCalledTimes(1); @@ -157,7 +157,7 @@ describe('LndClient', () => { try { await lnd.openChannel({ units, - peerIdentifier: peerPubKey, + remoteIdentifier: peerPubKey, uris: lndListeningUris, }); } catch (e) { diff --git a/test/jest/Service.spec.ts b/test/jest/Service.spec.ts index a6264978f..149a2399e 100644 --- a/test/jest/Service.spec.ts +++ b/test/jest/Service.spec.ts @@ -1,4 +1,4 @@ -import { Owner } from '../../lib/constants/enums'; +import { Owner, SwapClientType } from '../../lib/constants/enums'; import Orderbook from '../../lib/orderbook/OrderBook'; import Peer from '../../lib/p2p/Peer'; import Pool from '../../lib/p2p/Pool'; @@ -12,15 +12,32 @@ jest.mock('../../lib/orderbook/OrderBook'); const mockedOrderbook = >Orderbook; jest.mock('../../lib/swaps/Swaps'); const mockedSwaps = >Swaps; -jest.mock('../../lib/swaps/SwapClientManager'); +jest.mock('../../lib/swaps/SwapClientManager', () => { + return jest.fn().mockImplementation(() => { + return { + getType: () => SwapClientType.Lnd, + }; + }); +}); const mockedSwapClientManager = >SwapClientManager; jest.mock('../../lib/swaps/SwapClient'); const mockedSwapClient = >SwapClient; jest.mock('../../lib/p2p/Pool'); const mockedPool = >Pool; jest.mock('../../lib/p2p/Peer'); +jest.mock('../../lib/p2p/Peer', () => { + return jest.fn().mockImplementation(() => { + return { + getLndPubKey: () => lndPubKey, + getIdentifier: () => lndPubKey, + getLndUris: jest.fn(), + }; + }); +}); const mockedPeer = >Peer; +const lndPubKey = 'lndpubkey'; + const getArgs = () => { return { nodeIdentifier: '02f8895eb03c37b2665415be4d83b20228acc0abc55ebf6728565141c66cfc164a', @@ -52,7 +69,7 @@ describe('Service', () => { }); describe('openChannel', () => { - test('gets peer from pool for swapClientManager', async () => { + test('gets peer identifier from pool for swapClientManager', async () => { service = new Service(components); const args = getArgs(); await service.openChannel(args); @@ -60,7 +77,7 @@ describe('Service', () => { .toHaveBeenCalledWith(args.nodeIdentifier); expect(components.swapClientManager.openChannel) .toHaveBeenCalledWith({ - peer, + remoteIdentifier: lndPubKey, amount: args.amount, currency: args.currency, }); diff --git a/test/jest/SwapClientManager.spec.ts b/test/jest/SwapClientManager.spec.ts index 4e5f0f158..d5aef989a 100644 --- a/test/jest/SwapClientManager.spec.ts +++ b/test/jest/SwapClientManager.spec.ts @@ -2,7 +2,6 @@ import Config from '../../lib/Config'; import { SwapClientType } from '../../lib/constants/enums'; import DB from '../../lib/db/DB'; import Logger from '../../lib/Logger'; -import Peer from '../../lib/p2p/Peer'; import SwapClientManager from '../../lib/swaps/SwapClientManager'; import { UnitConverter } from '../../lib/utils/UnitConverter'; @@ -82,8 +81,6 @@ const loggers = { swaps: logger, http: logger, }; -jest.mock('../../lib/p2p/Peer'); -const mockedPeer = >Peer; describe('Swaps.SwapClientManager', () => { let config: Config; @@ -209,13 +206,10 @@ describe('Swaps.SwapClientManager', () => { }); describe('openChannel', () => { - let peer: Peer; - let peerLndPubKey: string; + let remoteIdentifier: string; beforeEach(() => { - peer = new mockedPeer(); - peerLndPubKey = '02afaef2634e5c7ca8d682b828a62bd040929b1e4b5030b21e2a0a891cf545b2e1'; - peer.getIdentifier = jest.fn().mockReturnValue(peerLndPubKey); + remoteIdentifier = '02afaef2634e5c7ca8d682b828a62bd040929b1e4b5030b21e2a0a891cf545b2e1'; }); test('it fails without swap client', async () => { @@ -226,21 +220,19 @@ describe('Swaps.SwapClientManager', () => { swapClientManager.get = jest.fn().mockReturnValue(undefined); await swapClientManager.init(db.models); try { - await swapClientManager.openChannel({ peer, currency, amount }); + await swapClientManager.openChannel({ remoteIdentifier, currency, amount }); } catch (e) { expect(e).toMatchSnapshot(); } }); test('it fails without peerSwapClientPubKey', async () => { - expect.assertions(1); const currency = 'BTC'; const amount = 16000000; swapClientManager = new SwapClientManager(config, loggers, unitConverter); - peer.getIdentifier = jest.fn().mockReturnValue(undefined); await swapClientManager.init(db.models); try { - await swapClientManager.openChannel({ peer, currency, amount }); + await swapClientManager.openChannel({ remoteIdentifier, currency, amount }); } catch (e) { expect(e).toMatchSnapshot(); } @@ -255,17 +247,15 @@ describe('Swaps.SwapClientManager', () => { '123.456.789.321:9735', '192.168.63.155:9777', ]; - peer.getLndUris = jest.fn().mockReturnValue(lndListeningUris); await swapClientManager.init(db.models); - await swapClientManager.openChannel({ peer, currency, amount }); + await swapClientManager.openChannel({ remoteIdentifier, currency, amount, uris: lndListeningUris }); expect(getClientSpy).toHaveBeenCalledWith(currency); - expect(peer.getIdentifier).toHaveBeenCalledWith(SwapClientType.Lnd, currency); expect(mockLndOpenChannel).toHaveBeenCalledTimes(1); expect(mockLndOpenChannel).toHaveBeenCalledWith( expect.objectContaining({ + remoteIdentifier, units: amount, uris: lndListeningUris, - peerIdentifier: peerLndPubKey, }), ); }); @@ -276,21 +266,17 @@ describe('Swaps.SwapClientManager', () => { const amount = 5000000; const expectedUnits = 50000000000000000; const peerRaidenAddress = '0x10D8CCAD85C7dc123090B43aA1f98C00a303BFC5'; - peer.getIdentifier = jest.fn().mockReturnValue(peerRaidenAddress); swapClientManager = new SwapClientManager(config, loggers, unitConverter); const getClientSpy = jest.spyOn(swapClientManager, 'get'); - peer.getLndUris = jest.fn(); await swapClientManager.init(db.models); - await swapClientManager.openChannel({ peer, currency, amount }); + await swapClientManager.openChannel({ currency, amount, remoteIdentifier: peerRaidenAddress }); expect(getClientSpy).toHaveBeenCalledWith(currency); - expect(peer.getIdentifier).toHaveBeenCalledWith(SwapClientType.Raiden, currency); - expect(peer.getLndUris).toHaveBeenCalledTimes(0); expect(mockRaidenOpenChannel).toHaveBeenCalledTimes(1); expect(mockRaidenOpenChannel).toHaveBeenCalledWith( expect.objectContaining({ currency, units: expectedUnits, - peerIdentifier: peerRaidenAddress, + remoteIdentifier: peerRaidenAddress, // uris: undefined, pushUnits: 0, }), diff --git a/test/jest/__snapshots__/SwapClientManager.spec.ts.snap b/test/jest/__snapshots__/SwapClientManager.spec.ts.snap index 65c59b7cf..4ec2a09a6 100644 --- a/test/jest/__snapshots__/SwapClientManager.spec.ts.snap +++ b/test/jest/__snapshots__/SwapClientManager.spec.ts.snap @@ -1,7 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Swaps.SwapClientManager openChannel it fails without peerSwapClientPubKey 1`] = `[Error: peer not connected to swap client]`; - exports[`Swaps.SwapClientManager openChannel it fails without swap client 1`] = ` Object { "code": "7.1", diff --git a/test/simulation/xudrpc/xudrpc.pb.go b/test/simulation/xudrpc/xudrpc.pb.go index bd9c5132d..e1c860273 100644 --- a/test/simulation/xudrpc/xudrpc.pb.go +++ b/test/simulation/xudrpc/xudrpc.pb.go @@ -515,7 +515,13 @@ type CloseChannelRequest struct { // The ticker symbol of the currency of the channel to close. Currency string `protobuf:"bytes,2,opt,name=currency,proto3" json:"currency,omitempty"` // Whether to force close the channel in case the peer is offline or unresponsive. - Force bool `protobuf:"varint,3,opt,name=force,proto3" json:"force,omitempty"` + Force bool `protobuf:"varint,3,opt,name=force,proto3" json:"force,omitempty"` + // The on-chain address to send funds extracted from the channel. If unspecified, + // the funds return to the default wallet for the client closing the channel. + Destination string `protobuf:"bytes,4,opt,name=destination,proto3" json:"destination,omitempty"` + // For Connext only - the amount to extract from the channel. If 0 or unspecified, + // the entire off-chain balance for the specified currency will be extracted. + Amount uint64 `protobuf:"varint,5,opt,name=amount,proto3" json:"amount,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -567,6 +573,20 @@ func (m *CloseChannelRequest) GetForce() bool { return false } +func (m *CloseChannelRequest) GetDestination() string { + if m != nil { + return m.Destination + } + return "" +} + +func (m *CloseChannelRequest) GetAmount() uint64 { + if m != nil { + return m.Amount + } + return 0 +} + type CloseChannelResponse struct { XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -4256,237 +4276,239 @@ func init() { func init() { proto.RegisterFile("xudrpc.proto", fileDescriptor_6960a02cc0a63cf6) } var fileDescriptor_6960a02cc0a63cf6 = []byte{ - // 3675 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x3a, 0x4d, 0x8f, 0xdc, 0xc6, - 0xb1, 0xcb, 0xf9, 0xd8, 0x99, 0xad, 0xf9, 0xdc, 0xde, 0x0f, 0x8d, 0x46, 0xb2, 0x2c, 0xf3, 0xd9, - 0x7a, 0xb2, 0x2c, 0xad, 0xf4, 0xd6, 0xcf, 0xcf, 0x96, 0xfc, 0x6c, 0x58, 0xbb, 0xda, 0x67, 0xc9, - 0x5e, 0x7d, 0x80, 0x2b, 0xd9, 0x7a, 0x41, 0x62, 0x82, 0x43, 0xb6, 0xb4, 0x8c, 0x38, 0xcd, 0x11, - 0x3f, 0xf6, 0x23, 0xa7, 0xc0, 0x06, 0x72, 0x48, 0x8e, 0xce, 0xd1, 0x40, 0x72, 0xca, 0x25, 0xb9, - 0x07, 0xc8, 0x29, 0xe7, 0x5c, 0x03, 0x04, 0x39, 0x04, 0x08, 0x02, 0xe4, 0x17, 0xe4, 0x17, 0x04, - 0xfd, 0x45, 0x76, 0x93, 0x9c, 0xb5, 0x64, 0x24, 0x37, 0x76, 0x75, 0x75, 0x55, 0x57, 0x75, 0x75, - 0x55, 0x75, 0x15, 0xa1, 0x7b, 0x94, 0x7a, 0xd1, 0xcc, 0xdd, 0x98, 0x45, 0x61, 0x12, 0xa2, 0x45, - 0x3e, 0x1a, 0x2f, 0x3b, 0x84, 0x84, 0x89, 0x93, 0xf8, 0x21, 0x89, 0xf9, 0x94, 0xb9, 0x06, 0x2b, - 0x37, 0x3d, 0x6f, 0x3b, 0x8d, 0x22, 0x4c, 0xdc, 0x63, 0x0b, 0xc7, 0xb3, 0x90, 0xc4, 0xd8, 0xfc, - 0x02, 0xfa, 0x37, 0x3d, 0xef, 0x81, 0xe3, 0x47, 0x16, 0x7e, 0x9e, 0xe2, 0x38, 0x41, 0xaf, 0x43, - 0x6f, 0xe2, 0xc4, 0xd8, 0x76, 0x05, 0xea, 0xc8, 0x38, 0x6f, 0x5c, 0x5c, 0xb2, 0x74, 0x20, 0xba, - 0x00, 0xfd, 0xe7, 0x69, 0x98, 0x28, 0x68, 0x35, 0x86, 0x56, 0x80, 0x9a, 0xcb, 0x30, 0xc8, 0xe8, - 0x0b, 0x96, 0xbf, 0xad, 0x41, 0x6b, 0xcb, 0x09, 0x1c, 0xe2, 0x62, 0xca, 0x2c, 0x09, 0x13, 0x27, - 0xb0, 0x27, 0x1c, 0xc0, 0x98, 0x35, 0x2c, 0x1d, 0x88, 0x2e, 0xc2, 0xc0, 0xdd, 0x77, 0x08, 0xc1, - 0x39, 0x5e, 0x8d, 0xe1, 0x15, 0xc1, 0xe8, 0x3d, 0x38, 0x35, 0xc3, 0xc4, 0xf3, 0xc9, 0x53, 0xbb, - 0xb8, 0xa2, 0xce, 0x56, 0xcc, 0x9b, 0x46, 0x37, 0x60, 0xe4, 0x13, 0xc7, 0x4d, 0xfc, 0x03, 0x5c, - 0x5a, 0xda, 0x60, 0x4b, 0xe7, 0xce, 0x53, 0x65, 0x1c, 0x3a, 0x41, 0x80, 0x93, 0x6c, 0x45, 0x93, - 0xad, 0x28, 0x40, 0xd1, 0x87, 0x30, 0x4e, 0x89, 0x1b, 0x92, 0x27, 0x7e, 0x34, 0xc5, 0x9e, 0x5d, - 0x58, 0xb3, 0xc8, 0xd6, 0x9c, 0x80, 0x61, 0xfe, 0x0f, 0xc0, 0x96, 0x43, 0xe4, 0x41, 0x5d, 0x84, - 0x01, 0x09, 0x3d, 0x6c, 0xfb, 0x1e, 0x26, 0x89, 0xff, 0xc4, 0xc7, 0x91, 0x38, 0xaa, 0x22, 0xd8, - 0xec, 0x41, 0x87, 0xad, 0x13, 0x07, 0xf0, 0x2e, 0x34, 0xb7, 0xf7, 0x1d, 0x9f, 0xa0, 0x55, 0x68, - 0xba, 0xf4, 0x43, 0xac, 0xe3, 0x03, 0x34, 0x82, 0x16, 0xc1, 0xc9, 0x61, 0x18, 0x3d, 0x13, 0x67, - 0x2a, 0x87, 0xe6, 0x0c, 0xda, 0xdb, 0x5c, 0xf4, 0x18, 0xad, 0xc3, 0x22, 0xd7, 0x06, 0x5b, 0xdc, - 0xb3, 0xc4, 0x08, 0x8d, 0xa1, 0x2d, 0xf5, 0xc4, 0x96, 0xf7, 0xac, 0x6c, 0x4c, 0x29, 0x0b, 0xf5, - 0xb3, 0xd3, 0xe8, 0x59, 0x72, 0x48, 0xa9, 0xb9, 0x41, 0x18, 0x63, 0x8f, 0xe9, 0xba, 0x67, 0x89, - 0x91, 0xf9, 0x1c, 0x56, 0xb6, 0xe9, 0x97, 0x60, 0xfb, 0xd2, 0xa2, 0xd3, 0xed, 0x14, 0x2c, 0x34, - 0x1b, 0x53, 0xf1, 0x9f, 0x84, 0x91, 0x30, 0x8d, 0xb6, 0xc5, 0x07, 0xe6, 0x3a, 0xac, 0xea, 0x2c, - 0x85, 0xd6, 0x2e, 0x43, 0x7f, 0x3b, 0x24, 0x04, 0xbb, 0x89, 0xdc, 0xc5, 0x18, 0xda, 0x8c, 0x5d, - 0x1a, 0xf9, 0x82, 0x7d, 0x36, 0xa6, 0x76, 0x9f, 0x61, 0x0b, 0x02, 0x57, 0x61, 0x79, 0x3b, 0xc2, - 0x4e, 0x82, 0xef, 0x85, 0x1e, 0x56, 0x68, 0xcc, 0x9c, 0x38, 0x3e, 0x0c, 0x23, 0x4f, 0xd2, 0x90, - 0x63, 0xf3, 0x6b, 0x03, 0x90, 0xba, 0x82, 0xd3, 0x41, 0xff, 0x01, 0xbd, 0x18, 0x63, 0xcf, 0x9e, - 0x12, 0x3c, 0x0d, 0x89, 0xef, 0x8e, 0x8c, 0xf3, 0xf5, 0x8b, 0x4b, 0x56, 0x97, 0x02, 0xef, 0x0a, - 0x18, 0x7a, 0x13, 0x86, 0x3e, 0xf1, 0x13, 0xdf, 0x09, 0xfc, 0x1f, 0x61, 0xcf, 0x0e, 0x88, 0x17, - 0x8f, 0x6a, 0x0c, 0x6f, 0xa0, 0xc0, 0x77, 0x89, 0x17, 0xa3, 0x2b, 0x80, 0x54, 0xd4, 0xc8, 0xa1, - 0xea, 0x13, 0x3a, 0x59, 0x56, 0x66, 0x2c, 0x36, 0x61, 0xfe, 0xc9, 0x80, 0xb6, 0x74, 0x23, 0x9a, - 0x7a, 0x8d, 0x82, 0x7a, 0x3f, 0x80, 0x4e, 0x7c, 0xe8, 0xcc, 0x6c, 0x37, 0xf0, 0x31, 0x49, 0x98, - 0xf6, 0xfb, 0x9b, 0x67, 0x36, 0x84, 0xc3, 0x92, 0x24, 0x36, 0xf6, 0x0e, 0x9d, 0xd9, 0x36, 0x43, - 0xb1, 0x54, 0x7c, 0xee, 0x1a, 0x9e, 0x61, 0x62, 0x3b, 0x9e, 0x17, 0xe1, 0x38, 0x66, 0x3b, 0x5a, - 0xb2, 0x74, 0x20, 0xbd, 0x7a, 0x1e, 0x76, 0xfd, 0xa9, 0x13, 0xd8, 0xb3, 0xc0, 0x71, 0x71, 0x2c, - 0x0c, 0xa8, 0x00, 0x35, 0x5f, 0x03, 0xc8, 0x19, 0xa1, 0x16, 0xd4, 0x77, 0xef, 0xdd, 0x1a, 0x2e, - 0x20, 0x80, 0x45, 0xeb, 0xe6, 0x9d, 0x5b, 0x3b, 0xf7, 0x86, 0x06, 0x3d, 0xe0, 0x5b, 0x78, 0x16, - 0xc6, 0xbe, 0x7a, 0xc0, 0xf3, 0xa4, 0x33, 0xdf, 0x82, 0x41, 0x86, 0x2d, 0x0e, 0x66, 0x04, 0x2d, - 0xb9, 0x57, 0x8e, 0x2d, 0x87, 0xe6, 0x47, 0xb0, 0x7a, 0xcb, 0x8f, 0xdd, 0xf0, 0x00, 0x47, 0xf4, - 0x28, 0xe3, 0x97, 0xbf, 0xc2, 0xef, 0xc0, 0x5a, 0x81, 0x82, 0x60, 0x7a, 0x16, 0x96, 0x48, 0x3a, - 0xb5, 0x29, 0x7e, 0x2c, 0xae, 0x62, 0x0e, 0x30, 0x7f, 0x6a, 0x00, 0xda, 0x39, 0xc2, 0x6e, 0x9a, - 0x60, 0x2a, 0xbe, 0x22, 0x58, 0x18, 0x79, 0x38, 0xb2, 0xfd, 0xcc, 0xea, 0xe4, 0x98, 0x5d, 0x52, - 0xc7, 0x67, 0x53, 0xe2, 0xfa, 0x8b, 0x21, 0x32, 0xa1, 0x3b, 0xc3, 0x38, 0xb2, 0x67, 0xe9, 0xc4, - 0x7e, 0x86, 0x8f, 0xc5, 0x81, 0x68, 0x30, 0x4a, 0xf9, 0x79, 0xea, 0x90, 0xc4, 0x4f, 0x8e, 0x85, - 0xdb, 0xcc, 0xc6, 0xf4, 0x02, 0x7c, 0x8c, 0x13, 0xe1, 0xfa, 0x5f, 0x44, 0xc7, 0xbf, 0x32, 0x00, - 0xa9, 0x2b, 0x84, 0xc8, 0x5b, 0xd0, 0x16, 0x1e, 0x31, 0x66, 0xb6, 0xdf, 0xd9, 0xbc, 0x28, 0xad, - 0xaa, 0x8c, 0xbd, 0x21, 0xc6, 0xf1, 0x0e, 0x49, 0xa2, 0x63, 0x6b, 0x91, 0xc9, 0x19, 0x8f, 0x77, - 0xa1, 0xa7, 0x4d, 0xa0, 0x21, 0xd4, 0xa9, 0x4c, 0x7c, 0x0b, 0xf4, 0x13, 0xbd, 0x01, 0xcd, 0x03, - 0x27, 0x48, 0xb9, 0x1b, 0xeb, 0x6c, 0x0e, 0x24, 0x0f, 0xc9, 0x80, 0xcf, 0xde, 0xa8, 0xbd, 0x67, - 0x98, 0x43, 0xe8, 0x7f, 0x8c, 0x93, 0x3b, 0xe4, 0x49, 0x28, 0xc4, 0x32, 0x7f, 0xd2, 0x80, 0x41, - 0x06, 0xca, 0xed, 0xe3, 0x00, 0x47, 0xb1, 0x1f, 0x4a, 0x87, 0x2b, 0x87, 0x54, 0xb3, 0xec, 0xc0, - 0xa5, 0x66, 0xb9, 0xe2, 0x35, 0x18, 0x42, 0xd0, 0x48, 0x23, 0x9f, 0x5e, 0x03, 0x7a, 0x8b, 0xd9, - 0xb7, 0x3c, 0x7c, 0x7a, 0x02, 0xd2, 0xf0, 0x73, 0x40, 0x36, 0xeb, 0xf8, 0x51, 0xcc, 0x22, 0x92, - 0x9c, 0xa5, 0x00, 0xf4, 0x16, 0x08, 0x5d, 0xb0, 0xc0, 0xd3, 0xd9, 0x5c, 0x91, 0xf2, 0xdd, 0x67, - 0xd0, 0xed, 0x30, 0x25, 0x89, 0x54, 0x17, 0xda, 0x84, 0x7a, 0x40, 0xbc, 0x51, 0x8b, 0x69, 0xfb, - 0xbc, 0xa2, 0x6d, 0x55, 0xc0, 0x8d, 0x5d, 0xe2, 0x71, 0x2d, 0x53, 0x64, 0x74, 0x09, 0x16, 0x85, - 0x2f, 0x69, 0x33, 0x06, 0x48, 0x2e, 0xe3, 0x8e, 0x84, 0xad, 0x14, 0x18, 0xd4, 0x15, 0x3b, 0x81, - 0xef, 0xc4, 0xa3, 0x25, 0x1e, 0x89, 0xd8, 0x40, 0x8d, 0x44, 0xa0, 0x45, 0x22, 0x74, 0x0d, 0x56, - 0x64, 0x20, 0x67, 0x3e, 0x63, 0xdf, 0x89, 0xf7, 0x71, 0x3c, 0xea, 0x30, 0xdd, 0x54, 0x4d, 0xa1, - 0x2b, 0xd0, 0x72, 0xa9, 0x43, 0x3e, 0x4a, 0x46, 0x5d, 0x5d, 0xde, 0x6d, 0x0e, 0x66, 0xfb, 0x91, - 0x38, 0xe3, 0x8f, 0xa1, 0x2d, 0xa5, 0x79, 0x09, 0xd3, 0xd8, 0x25, 0x1e, 0x23, 0xa3, 0x98, 0xc6, - 0x87, 0xcc, 0x84, 0xe9, 0x9d, 0x55, 0xcc, 0xe3, 0x25, 0x2e, 0xbe, 0x05, 0x2b, 0xda, 0xfa, 0x2c, - 0x08, 0x0c, 0x22, 0x3c, 0x4b, 0x79, 0x8e, 0xb7, 0xe7, 0x86, 0x11, 0x8f, 0xc3, 0xcb, 0x16, 0xe4, - 0x60, 0x1a, 0x55, 0x27, 0x34, 0x88, 0xf1, 0x9b, 0xdc, 0xb6, 0xc4, 0xc8, 0x3c, 0x05, 0x6b, 0xbb, - 0x7e, 0x9c, 0x08, 0x17, 0xec, 0x67, 0xfe, 0xc8, 0xfc, 0x04, 0xd6, 0x8b, 0x13, 0x82, 0xdf, 0x35, - 0x00, 0x37, 0x83, 0x8a, 0x5b, 0x37, 0x2c, 0xfa, 0x72, 0x4b, 0xc1, 0x31, 0xff, 0x60, 0xc0, 0x32, - 0x25, 0xc6, 0xcd, 0x49, 0x0a, 0xae, 0x78, 0x17, 0x43, 0xf7, 0x2e, 0xef, 0x40, 0x33, 0x3c, 0x24, - 0x38, 0x12, 0x81, 0xe2, 0xd5, 0x4c, 0xa7, 0x45, 0x1a, 0x1b, 0xf7, 0x29, 0x9a, 0xc5, 0xb1, 0xa9, - 0xe5, 0x04, 0xfe, 0xd4, 0x4f, 0x44, 0x46, 0xc1, 0x07, 0x54, 0xbf, 0x3e, 0x71, 0x83, 0xd4, 0xc3, - 0x36, 0x33, 0x25, 0x11, 0x17, 0xda, 0x56, 0x11, 0x6c, 0xbe, 0x0e, 0x4d, 0x46, 0x0f, 0xb5, 0xa1, - 0xb1, 0x75, 0xff, 0xe1, 0xed, 0xe1, 0x02, 0x8d, 0x0e, 0xf7, 0x3f, 0xbf, 0x37, 0x34, 0x28, 0xe8, - 0xc1, 0xce, 0x8e, 0x35, 0xac, 0x99, 0xbf, 0x30, 0x00, 0xa9, 0x1b, 0x11, 0x5a, 0xf9, 0x30, 0xbb, - 0x43, 0x5c, 0x23, 0x17, 0xaa, 0x36, 0x2d, 0x2e, 0x07, 0x1f, 0xea, 0x5e, 0xe8, 0x0e, 0x74, 0x14, - 0x70, 0x85, 0xa1, 0xbd, 0xae, 0x1b, 0x5a, 0x5f, 0xbf, 0xa3, 0xaa, 0x9d, 0x21, 0x18, 0x52, 0xa6, - 0x34, 0xd3, 0xce, 0x8e, 0xf3, 0x4d, 0x7e, 0x02, 0x02, 0x26, 0xf6, 0xbc, 0x0a, 0x4d, 0xee, 0x11, - 0x78, 0xda, 0xc0, 0x07, 0xd9, 0x72, 0x9c, 0xeb, 0xd9, 0x7c, 0x57, 0x2c, 0xc7, 0xaa, 0xc8, 0x26, - 0x34, 0xb9, 0xbb, 0xe1, 0x12, 0x77, 0xe5, 0x8e, 0x28, 0x96, 0xc5, 0xa7, 0x24, 0xdf, 0x87, 0x91, - 0xa3, 0xc4, 0xba, 0xec, 0xa0, 0x0c, 0xe5, 0xa0, 0xcc, 0xf7, 0xb9, 0x5e, 0x25, 0xaa, 0x60, 0xf2, - 0x06, 0x2c, 0x26, 0x0c, 0x22, 0xb8, 0xf4, 0x24, 0x17, 0x86, 0x67, 0x89, 0x49, 0xf3, 0x2f, 0x06, - 0xb4, 0xc4, 0x95, 0xa3, 0xb6, 0x1e, 0x27, 0x4e, 0x92, 0xca, 0xd8, 0x2b, 0x46, 0xe8, 0x32, 0xb4, - 0x45, 0xba, 0x1e, 0x0b, 0x25, 0xe6, 0x66, 0x2b, 0xe0, 0x56, 0x86, 0x41, 0x19, 0xb3, 0x24, 0x98, - 0xbb, 0x59, 0x85, 0x31, 0x4b, 0x98, 0x2d, 0x31, 0x89, 0xce, 0x43, 0x67, 0x12, 0x84, 0xee, 0xb3, - 0x7d, 0xec, 0x3f, 0xdd, 0x4f, 0x84, 0xe7, 0x55, 0x41, 0x99, 0xb7, 0x6e, 0x2a, 0xde, 0x5a, 0xf1, - 0xff, 0x8b, 0xba, 0xff, 0xcf, 0xdc, 0x5f, 0x4b, 0x71, 0x7f, 0xe6, 0x27, 0xd0, 0x67, 0xf7, 0x3e, - 0xcf, 0x66, 0x8b, 0x71, 0xc2, 0xa8, 0x88, 0x13, 0x19, 0xad, 0x9a, 0x4a, 0xeb, 0xe7, 0x06, 0xa0, - 0xfb, 0x33, 0x4c, 0xfe, 0x2d, 0x89, 0x34, 0x7d, 0x0b, 0x4c, 0x69, 0xbc, 0x10, 0x8f, 0x2c, 0x31, - 0xa2, 0x6a, 0x9a, 0xa5, 0xf1, 0xbe, 0x2d, 0x26, 0x79, 0x3e, 0xa0, 0x82, 0xe8, 0xab, 0x54, 0xdb, - 0x95, 0x48, 0x95, 0x7f, 0x5f, 0x83, 0x26, 0x33, 0x71, 0x66, 0xad, 0x91, 0x2f, 0x1e, 0x86, 0x86, - 0xc5, 0x07, 0x5a, 0x96, 0x51, 0xd3, 0xb3, 0x0c, 0xd5, 0xc3, 0xd4, 0x75, 0x0f, 0xd3, 0x87, 0x9a, - 0xcf, 0x1f, 0x18, 0x4b, 0x56, 0xcd, 0xf7, 0xd0, 0x47, 0x65, 0xe1, 0x9b, 0xcc, 0x42, 0xd6, 0xe5, - 0xa9, 0xeb, 0xea, 0xaf, 0x54, 0x4a, 0x10, 0xba, 0x4e, 0x40, 0x99, 0xf1, 0x23, 0xcd, 0xc6, 0xe8, - 0x1c, 0x80, 0xcb, 0x92, 0x77, 0xcf, 0x76, 0x12, 0x76, 0xb0, 0x0d, 0x4b, 0x81, 0xa0, 0x37, 0xa0, - 0x11, 0xfb, 0x1e, 0x66, 0xc1, 0xb1, 0xbf, 0xb9, 0xac, 0xdd, 0xec, 0x3d, 0xdf, 0xc3, 0x16, 0x9b, - 0xa6, 0x47, 0xee, 0xc7, 0x76, 0x78, 0x48, 0x6c, 0xe6, 0x33, 0x58, 0x80, 0x6c, 0x5b, 0x1a, 0x8c, - 0x1a, 0xdb, 0x7e, 0x18, 0x78, 0x2c, 0x48, 0x36, 0x2c, 0xf6, 0x6d, 0xfe, 0xd2, 0x80, 0x2e, 0xa3, - 0x65, 0xe1, 0x69, 0x78, 0xe0, 0x04, 0x9a, 0xce, 0x8c, 0xf9, 0x3a, 0x2b, 0xe4, 0x7c, 0x6a, 0xa6, - 0x58, 0x2f, 0x64, 0x8a, 0xaa, 0xf4, 0x8d, 0x82, 0xf4, 0xc5, 0x6d, 0x37, 0xcb, 0xdb, 0x36, 0xf7, - 0x61, 0x91, 0xfb, 0x31, 0x74, 0x05, 0x60, 0x92, 0x1e, 0xdb, 0x9a, 0x2f, 0xed, 0x69, 0x1a, 0xb1, - 0x14, 0x04, 0x74, 0x15, 0x3a, 0x31, 0x0e, 0x02, 0x89, 0x5f, 0xab, 0xc2, 0x57, 0x31, 0xcc, 0xb7, - 0xa5, 0x9f, 0x65, 0x59, 0x0d, 0xd5, 0x17, 0x75, 0x54, 0xc2, 0x13, 0xb1, 0x6f, 0xea, 0x7b, 0xc3, - 0x43, 0x22, 0x9e, 0xac, 0xf4, 0xd3, 0xfc, 0xd2, 0x10, 0xab, 0x1e, 0xcd, 0x3c, 0x27, 0xa1, 0x4e, - 0xa9, 0xc9, 0x65, 0x31, 0x98, 0x91, 0xe8, 0xfc, 0x6e, 0x2f, 0x58, 0x7c, 0x16, 0xfd, 0x2f, 0xf4, - 0xb8, 0x86, 0x22, 0xae, 0x78, 0xe1, 0x75, 0x56, 0xf5, 0xed, 0xf1, 0xb9, 0xdb, 0x0b, 0x96, 0x8e, - 0xbc, 0xd5, 0x87, 0x2e, 0x07, 0xa4, 0x8c, 0xa9, 0xf9, 0x55, 0x1d, 0x1a, 0xd4, 0xb5, 0xce, 0x7f, - 0x5c, 0xbc, 0x50, 0xf2, 0xf8, 0x11, 0x74, 0x03, 0xe2, 0xc9, 0xa1, 0xf4, 0x6e, 0x67, 0x55, 0xe7, - 0x4d, 0x93, 0x97, 0x07, 0xe9, 0xe4, 0x53, 0x7c, 0x2c, 0x82, 0x94, 0xb6, 0x82, 0xf2, 0xf7, 0xc9, - 0x24, 0x4c, 0x89, 0x27, 0x22, 0xa9, 0x1c, 0xe6, 0x01, 0xa5, 0xa9, 0x04, 0x14, 0x7a, 0xf7, 0x8f, - 0x52, 0xcf, 0xd6, 0x1d, 0x9e, 0x0a, 0x42, 0x97, 0x61, 0x39, 0xc6, 0x6e, 0x48, 0xbc, 0xd8, 0x76, - 0xf9, 0x53, 0x19, 0x7b, 0xec, 0x9e, 0xf4, 0xac, 0xf2, 0x04, 0x7d, 0xe8, 0xf1, 0x5c, 0x31, 0x7b, - 0x0f, 0xb6, 0x79, 0xc1, 0x49, 0x87, 0x56, 0x67, 0x92, 0xe3, 0x0f, 0x60, 0x50, 0x10, 0xaf, 0x22, - 0xd8, 0xae, 0xaa, 0xc1, 0x76, 0x49, 0x0d, 0xae, 0x3f, 0xae, 0xc1, 0xf2, 0x03, 0xfa, 0x90, 0x14, - 0x87, 0x97, 0x45, 0xb4, 0x7f, 0x99, 0x6f, 0x52, 0xef, 0x59, 0xa3, 0x70, 0xcf, 0xa4, 0xa7, 0x68, - 0x9e, 0xec, 0x29, 0x2e, 0xc1, 0x30, 0xc2, 0xec, 0xb9, 0x6b, 0x67, 0xa4, 0xb8, 0xda, 0x4b, 0x70, - 0x9a, 0x3f, 0xfb, 0xd3, 0x29, 0xf6, 0x7c, 0x27, 0xa1, 0x50, 0xdb, 0xa5, 0x2f, 0x9a, 0x80, 0x69, - 0xbf, 0x6d, 0x55, 0x4d, 0x51, 0x15, 0x20, 0x55, 0x05, 0x22, 0x52, 0x5f, 0x87, 0xa1, 0x4f, 0x12, - 0x1c, 0x11, 0x27, 0xb0, 0xa7, 0x4e, 0xe2, 0xee, 0xe3, 0x39, 0xf7, 0xb7, 0x84, 0x86, 0xde, 0x87, - 0x3e, 0x4b, 0xd0, 0xe3, 0xd4, 0x75, 0x71, 0x4c, 0x53, 0x34, 0x7e, 0x91, 0xb3, 0xc4, 0x9c, 0xbe, - 0x58, 0xf7, 0xf8, 0xa4, 0x55, 0x40, 0x45, 0xef, 0xd2, 0xfc, 0x77, 0xea, 0xf8, 0x84, 0xe6, 0xf9, - 0xfc, 0x5a, 0xd6, 0x2b, 0xae, 0xa5, 0x55, 0xc4, 0x42, 0xd7, 0xa1, 0xc7, 0x48, 0x3d, 0x71, 0xfc, - 0x20, 0x8d, 0x58, 0x5e, 0x58, 0x62, 0xfa, 0x7f, 0x7c, 0xce, 0xd2, 0x31, 0xcd, 0x7f, 0x18, 0x30, - 0xc8, 0x55, 0xb0, 0x73, 0x80, 0x09, 0xf5, 0xe2, 0x4d, 0x26, 0xcf, 0x5c, 0xa7, 0xc0, 0x66, 0xd1, - 0x75, 0xe8, 0xaa, 0x02, 0x08, 0x9f, 0x50, 0x25, 0xe9, 0xed, 0x05, 0x4b, 0x43, 0x45, 0xd7, 0x5f, - 0x4c, 0xd2, 0xdb, 0x0b, 0x55, 0xb2, 0x76, 0x55, 0x09, 0x98, 0x61, 0x55, 0x8b, 0x9a, 0x71, 0x15, - 0xa8, 0x5b, 0x2d, 0x68, 0x62, 0x2a, 0xa0, 0xf9, 0x8d, 0x01, 0x90, 0x3f, 0xd8, 0xe6, 0xa6, 0x59, - 0x8a, 0x7b, 0xaa, 0xe9, 0xee, 0x49, 0x4d, 0xc0, 0xea, 0xdf, 0x9a, 0x80, 0x29, 0x39, 0x52, 0xa3, - 0x94, 0x23, 0xf1, 0x62, 0x65, 0x53, 0x29, 0x56, 0x9a, 0x21, 0x74, 0x94, 0xf7, 0xdb, 0x77, 0xd8, - 0xde, 0xcb, 0x32, 0x7c, 0x1b, 0xd6, 0x98, 0xf3, 0xc6, 0x79, 0x29, 0xfd, 0xdb, 0x0b, 0x19, 0x23, - 0x58, 0x2f, 0x2e, 0x12, 0x99, 0xce, 0x2e, 0x20, 0x3e, 0xa3, 0x79, 0x96, 0x93, 0xea, 0x33, 0x27, - 0xf8, 0x17, 0xf3, 0x1d, 0x58, 0xd1, 0xa8, 0x89, 0x4b, 0x7a, 0x0e, 0x86, 0x12, 0xc5, 0x0e, 0x89, - 0xcd, 0x72, 0x05, 0x43, 0xc9, 0x15, 0xae, 0xc0, 0x32, 0x5f, 0xa6, 0xf6, 0x01, 0xe6, 0xbe, 0xd4, - 0xcc, 0x55, 0xb9, 0x67, 0xad, 0xac, 0xff, 0xd7, 0x1a, 0x05, 0xc7, 0x49, 0x18, 0x69, 0x05, 0xce, - 0x17, 0xaa, 0x56, 0xaa, 0x55, 0xd0, 0x9a, 0x5e, 0x05, 0x45, 0x9f, 0x42, 0x87, 0x06, 0xa2, 0x89, - 0xe3, 0x3e, 0x4b, 0x67, 0x32, 0x72, 0x5d, 0xca, 0x6a, 0x09, 0x25, 0x8e, 0x34, 0x8e, 0x6d, 0x71, - 0x64, 0x1e, 0xc7, 0x20, 0xc8, 0x00, 0xe8, 0x3f, 0x61, 0x20, 0xe2, 0x85, 0xe7, 0x24, 0xce, 0xc4, - 0x89, 0xf9, 0xa5, 0xe8, 0xca, 0x30, 0x72, 0x4b, 0x40, 0xd1, 0x35, 0x58, 0x2d, 0x20, 0xda, 0x33, - 0x27, 0xd9, 0x17, 0xb6, 0x80, 0x74, 0xec, 0x07, 0x4e, 0xb2, 0x8f, 0x5e, 0x63, 0xbd, 0x98, 0x9c, - 0xee, 0x22, 0xa3, 0x4b, 0x23, 0x9e, 0x44, 0x13, 0x51, 0x48, 0xdd, 0xdc, 0xb7, 0x45, 0xa1, 0xae, - 0x1a, 0x85, 0x5c, 0x7a, 0xba, 0x8a, 0xb8, 0x79, 0x3d, 0x38, 0xe2, 0x60, 0x51, 0xe7, 0x15, 0x1a, - 0x96, 0x40, 0x56, 0xe4, 0xa5, 0x82, 0x4b, 0x24, 0x51, 0x95, 0xe1, 0x35, 0x81, 0xbe, 0x04, 0x8b, - 0xf2, 0xee, 0x32, 0x0c, 0xf6, 0xf6, 0xd3, 0xc4, 0x0b, 0x0f, 0x65, 0xa3, 0x81, 0xbe, 0x0d, 0x73, - 0x90, 0x38, 0xed, 0xff, 0x86, 0xf5, 0xbd, 0x74, 0x12, 0xbb, 0x91, 0x3f, 0xc1, 0xfa, 0x0b, 0x7f, - 0x0c, 0x6d, 0x7c, 0xe4, 0xc7, 0x89, 0x4f, 0x9e, 0x32, 0xb1, 0xda, 0x56, 0x36, 0x36, 0x3f, 0x80, - 0xb5, 0x6c, 0x15, 0xf5, 0x3e, 0xb1, 0xd2, 0x74, 0x92, 0x0f, 0xf3, 0xc4, 0x79, 0x26, 0x72, 0xac, - 0xb6, 0xa5, 0x03, 0xcd, 0x5f, 0x1b, 0xd0, 0x51, 0x9c, 0xd6, 0x77, 0x2c, 0x63, 0xaa, 0x17, 0xa8, - 0x5e, 0x08, 0xd0, 0xc5, 0x12, 0x67, 0xa3, 0xa2, 0xc4, 0x79, 0x01, 0xfa, 0xc2, 0x4b, 0xda, 0x11, - 0x76, 0xe2, 0x50, 0x3a, 0x88, 0x02, 0xd4, 0xfc, 0x73, 0x9d, 0xef, 0x56, 0x38, 0x76, 0x74, 0xba, - 0xb4, 0xdb, 0x16, 0x1b, 0xdf, 0xd1, 0x33, 0xe9, 0x5a, 0x21, 0x93, 0x3e, 0x31, 0x67, 0x98, 0x57, - 0x6b, 0xa5, 0x8e, 0x30, 0x62, 0xa5, 0x2f, 0xb1, 0x39, 0x31, 0xa2, 0x0f, 0x3e, 0xfe, 0xf4, 0xb2, - 0x23, 0xec, 0x62, 0xff, 0x00, 0x7b, 0x2c, 0x8f, 0x6a, 0x58, 0x45, 0x30, 0x4d, 0xe0, 0x04, 0x28, - 0xc6, 0x24, 0x61, 0xe9, 0x54, 0xc3, 0x52, 0x41, 0x25, 0x65, 0x41, 0x85, 0xb2, 0x2e, 0x43, 0x23, - 0x0a, 0x03, 0x3c, 0xea, 0xb0, 0xdc, 0x65, 0x54, 0x11, 0xf0, 0x36, 0xac, 0x30, 0xc0, 0x16, 0xc3, - 0xa2, 0x29, 0xa1, 0xf4, 0x99, 0xf9, 0xfe, 0xba, 0x8c, 0x6c, 0x79, 0x82, 0x1a, 0x4d, 0x06, 0x64, - 0x7b, 0xec, 0xf1, 0x0e, 0x81, 0x06, 0xa4, 0xef, 0xb0, 0xc8, 0x9e, 0x45, 0xd8, 0x9f, 0x3a, 0x4f, - 0xf1, 0xa8, 0xcf, 0x50, 0x14, 0x48, 0x9e, 0xc5, 0x0d, 0x94, 0x2c, 0xce, 0x3c, 0x0b, 0x0d, 0xba, - 0x2f, 0xb4, 0x04, 0xcd, 0x87, 0x37, 0x3f, 0xdd, 0xb1, 0x86, 0x0b, 0xf4, 0xf3, 0x2e, 0xfb, 0x34, - 0xcc, 0x6d, 0xe8, 0x3d, 0x8c, 0x1c, 0xcf, 0x27, 0x4f, 0x77, 0xfd, 0xa9, 0x9f, 0xd0, 0xb3, 0x6d, - 0xdd, 0x75, 0x8e, 0xf6, 0x70, 0x10, 0xc8, 0xb7, 0xd5, 0xd4, 0x39, 0xb2, 0xe9, 0x13, 0x04, 0x9d, - 0x82, 0xc5, 0xbb, 0xce, 0xd1, 0x56, 0x2a, 0xbd, 0x75, 0x8b, 0xce, 0x4c, 0xd2, 0x63, 0xf3, 0x77, - 0x06, 0x34, 0x59, 0x3d, 0x83, 0xbe, 0x67, 0xa6, 0xd4, 0xc0, 0xed, 0xf9, 0xef, 0x0b, 0x4b, 0xc5, - 0x40, 0x9b, 0xd0, 0x49, 0x94, 0x05, 0xb5, 0xaa, 0x05, 0x7d, 0x05, 0x83, 0x5a, 0x4b, 0x6e, 0x11, - 0x75, 0xcd, 0x22, 0x4e, 0xb2, 0x22, 0xc5, 0xf6, 0x9a, 0x7a, 0x0c, 0xd8, 0x84, 0x55, 0x4d, 0x03, - 0x2f, 0x12, 0x05, 0x7f, 0x63, 0xc0, 0x5a, 0x61, 0x91, 0x70, 0x61, 0x37, 0x61, 0x91, 0x95, 0x83, - 0x64, 0xee, 0xf8, 0xa6, 0x5a, 0xef, 0x29, 0xa1, 0x6f, 0xf0, 0xa1, 0x28, 0xa5, 0xf1, 0x85, 0xe3, - 0x07, 0xd0, 0x51, 0xc0, 0x15, 0x7e, 0xf5, 0x2d, 0xbd, 0x94, 0xb6, 0x56, 0xcd, 0x42, 0x71, 0xb7, - 0x9f, 0x41, 0xf7, 0x11, 0x99, 0x7c, 0x87, 0x7e, 0x2b, 0x3a, 0x0b, 0x4b, 0x11, 0x16, 0x4f, 0x17, - 0xe1, 0x66, 0x73, 0x80, 0x39, 0x80, 0x9e, 0xa0, 0x9b, 0x37, 0x06, 0x1f, 0x91, 0x20, 0x74, 0x9f, - 0xbd, 0x68, 0x63, 0xf0, 0x2b, 0x03, 0x90, 0xba, 0x22, 0x0f, 0x04, 0x29, 0x83, 0x16, 0x02, 0x81, - 0x04, 0xca, 0x40, 0x90, 0x21, 0xe9, 0x81, 0x40, 0x82, 0x79, 0x20, 0x40, 0xaf, 0x42, 0x47, 0xa5, - 0xc5, 0xdb, 0x0e, 0x90, 0x53, 0x32, 0x7f, 0x66, 0xc0, 0xe0, 0x73, 0x3f, 0xd9, 0xf7, 0x22, 0xe7, - 0xf0, 0x05, 0x8e, 0x9f, 0x3a, 0x14, 0x0f, 0xd3, 0x38, 0xc0, 0x8a, 0xd3, 0xc2, 0xcf, 0xa9, 0xa0, - 0xb9, 0x75, 0xa4, 0x21, 0xd4, 0x9d, 0x20, 0x10, 0xef, 0x4e, 0xfa, 0x49, 0x21, 0x4f, 0x30, 0x16, - 0x4d, 0x0d, 0xfa, 0x69, 0xde, 0x80, 0x61, 0xbe, 0x19, 0xa1, 0x90, 0x0b, 0xd0, 0x4f, 0x22, 0x87, - 0xc4, 0x8e, 0x4b, 0xc9, 0xe7, 0x7e, 0xb7, 0x00, 0xbd, 0x74, 0x0e, 0x96, 0xb2, 0xc7, 0x14, 0x6a, - 0x41, 0x7d, 0xeb, 0xd1, 0xff, 0x0f, 0x17, 0x50, 0x1b, 0x1a, 0x7b, 0x3b, 0xbb, 0xbb, 0x43, 0x63, - 0xf3, 0x6f, 0x06, 0xb4, 0x1e, 0xa7, 0xde, 0x1d, 0xe2, 0x27, 0x68, 0x07, 0x20, 0xef, 0xc9, 0xa2, - 0xd3, 0x59, 0x2a, 0x5b, 0xec, 0xec, 0x8e, 0xc7, 0x55, 0x53, 0xe2, 0xc4, 0x17, 0xd0, 0x6d, 0xe8, - 0x28, 0xb1, 0x1c, 0x8d, 0xe7, 0xe7, 0x33, 0xe3, 0x33, 0x95, 0x73, 0x19, 0xa5, 0x1d, 0x80, 0xdc, - 0x16, 0xf2, 0x0d, 0x95, 0x2c, 0x2a, 0xdf, 0x50, 0xd9, 0x74, 0xcc, 0x85, 0xcd, 0x6f, 0xd6, 0xa0, - 0xfe, 0x38, 0xf5, 0xd0, 0x63, 0xe8, 0x28, 0xff, 0x89, 0xa0, 0x52, 0x8d, 0x3f, 0xdf, 0x4e, 0xd5, - 0xef, 0x24, 0xe3, 0x2f, 0xff, 0xf8, 0xf7, 0xaf, 0x6b, 0xab, 0xe6, 0xe0, 0xea, 0xc1, 0x7f, 0x5d, - 0x75, 0x3c, 0x4f, 0x1e, 0xfe, 0x0d, 0xe3, 0x12, 0xb2, 0xa0, 0x25, 0x7e, 0x05, 0x41, 0xeb, 0x0a, - 0x0d, 0x25, 0xe7, 0x1c, 0x9f, 0x2a, 0xc1, 0x05, 0xdd, 0x75, 0x46, 0x77, 0x68, 0x76, 0x04, 0x5d, - 0xea, 0x86, 0x28, 0xcd, 0x2d, 0xa8, 0x6f, 0x39, 0x04, 0xa1, 0xbc, 0x37, 0x27, 0xaf, 0xeb, 0x78, - 0x45, 0x83, 0x09, 0x3a, 0x88, 0xd1, 0xe9, 0x9a, 0x2d, 0x4a, 0x67, 0xe2, 0x10, 0x4a, 0xc3, 0x85, - 0xae, 0xda, 0xf0, 0x47, 0x79, 0x8b, 0xba, 0xfc, 0xe7, 0xc1, 0xf8, 0x6c, 0xf5, 0xa4, 0x20, 0x3f, - 0x62, 0xe4, 0x91, 0x39, 0xa4, 0xe4, 0xd9, 0x2f, 0x0c, 0xe2, 0x61, 0x43, 0x85, 0x17, 0xff, 0x03, - 0xe4, 0xc2, 0xeb, 0xbf, 0x13, 0xe4, 0xc2, 0x17, 0x7f, 0x1c, 0xd0, 0x84, 0x17, 0x5e, 0x44, 0x28, - 0x54, 0xb4, 0xa0, 0x73, 0x9a, 0x7a, 0x07, 0x3b, 0xa7, 0x59, 0xe8, 0x55, 0xeb, 0x34, 0x3d, 0x3e, - 0x49, 0x69, 0xfe, 0x10, 0x7a, 0x5a, 0x9f, 0x19, 0x65, 0x02, 0x57, 0x35, 0xb0, 0xc7, 0xaf, 0xcc, - 0x99, 0x15, 0x5c, 0xce, 0x32, 0x2e, 0xeb, 0xe6, 0x32, 0xe3, 0x22, 0x50, 0x58, 0x67, 0x9a, 0xf2, - 0x7a, 0x0c, 0x90, 0xf7, 0x6b, 0x73, 0xcb, 0x2d, 0xf5, 0x88, 0x73, 0xcb, 0x2d, 0xb7, 0x77, 0xcd, - 0x15, 0xc6, 0xa2, 0x87, 0x3a, 0xfc, 0x44, 0x39, 0xad, 0x5d, 0x68, 0x89, 0xde, 0x64, 0xae, 0x19, - 0xbd, 0x41, 0x9b, 0x6b, 0xa6, 0xd0, 0xc4, 0x34, 0x87, 0x8c, 0x20, 0xa0, 0x36, 0x25, 0xe8, 0x53, - 0x12, 0xdf, 0x87, 0x8e, 0xd2, 0x82, 0x43, 0xea, 0x6e, 0x0a, 0x7d, 0xbd, 0xfc, 0x72, 0x54, 0xf4, - 0xec, 0xcc, 0x55, 0x46, 0xb9, 0x8f, 0xba, 0x94, 0x32, 0xd5, 0x02, 0xa3, 0xfe, 0x39, 0x40, 0xde, - 0x2d, 0xca, 0xb5, 0x50, 0x6a, 0x7b, 0xe5, 0x5a, 0x28, 0x37, 0x97, 0xa4, 0x5d, 0x23, 0xa0, 0xa4, - 0x45, 0x95, 0xf4, 0x29, 0xf4, 0xf5, 0x66, 0x1e, 0x7a, 0x45, 0xa5, 0x50, 0xea, 0xfe, 0x8d, 0xcf, - 0xcd, 0x9b, 0xd6, 0x6d, 0x06, 0xf5, 0x99, 0x1d, 0xe6, 0x64, 0xf7, 0x60, 0x29, 0x6b, 0x33, 0xa1, - 0x91, 0x4a, 0x44, 0xed, 0x46, 0x8d, 0x4f, 0x57, 0xcc, 0x08, 0xca, 0xcb, 0x8c, 0x72, 0x07, 0x2d, - 0x51, 0xca, 0xbc, 0x7e, 0x28, 0x89, 0xb2, 0x4e, 0xb6, 0x4e, 0x54, 0xe9, 0x51, 0x15, 0x88, 0xaa, - 0x9d, 0xaa, 0x02, 0x51, 0x46, 0xe7, 0x0b, 0xae, 0x6b, 0xde, 0x6d, 0xd2, 0x75, 0xad, 0x35, 0xab, - 0x74, 0x5d, 0xeb, 0xcd, 0x29, 0xf3, 0x34, 0xa3, 0xbb, 0x62, 0x32, 0x35, 0x04, 0x7e, 0x9c, 0xf0, - 0x6e, 0x14, 0xb5, 0x68, 0x1b, 0x3a, 0x4a, 0x3b, 0x23, 0xb7, 0x94, 0x72, 0xe7, 0x25, 0xb7, 0x94, - 0xaa, 0xfe, 0xc7, 0x29, 0xc6, 0x62, 0x99, 0xbb, 0xd1, 0x70, 0x86, 0x89, 0x74, 0x23, 0x3f, 0x00, - 0xc8, 0x2b, 0x50, 0xb9, 0x00, 0xa5, 0xda, 0x64, 0x6e, 0xde, 0x85, 0x82, 0x95, 0xbe, 0x7b, 0x56, - 0x15, 0x64, 0xe6, 0x72, 0xc3, 0xb8, 0x74, 0xcd, 0x40, 0x4f, 0xa0, 0x9f, 0xe3, 0xef, 0x1d, 0x13, - 0xf7, 0x24, 0x16, 0xe3, 0xaa, 0x29, 0x21, 0xc0, 0x2b, 0x8c, 0xcb, 0x29, 0x13, 0xe9, 0x5c, 0xe2, - 0x63, 0xe2, 0x52, 0x3d, 0x7d, 0x0f, 0x3a, 0xca, 0x5f, 0x29, 0xb9, 0x9e, 0xca, 0xbf, 0xaa, 0x8c, - 0xab, 0x6a, 0x64, 0x7a, 0x98, 0xc1, 0x7c, 0x51, 0x7c, 0xe8, 0xcc, 0x28, 0x6d, 0x02, 0x7d, 0xbd, - 0xd6, 0x92, 0x9b, 0x7d, 0x65, 0xe1, 0x26, 0x37, 0xfb, 0x39, 0x25, 0x1a, 0x4d, 0x16, 0x56, 0xa7, - 0xc7, 0x6a, 0x58, 0x9b, 0xd0, 0x48, 0x9e, 0xd5, 0x5c, 0xd4, 0x48, 0x5e, 0x2c, 0xeb, 0xa8, 0x91, - 0xbc, 0x54, 0xa4, 0xd1, 0x65, 0xe2, 0x6c, 0xe4, 0xc9, 0x50, 0xbb, 0xcd, 0x2b, 0x2e, 0xf9, 0x99, - 0x94, 0x8a, 0x36, 0xe3, 0x71, 0xd5, 0x54, 0x95, 0xdd, 0x72, 0x06, 0x32, 0x8c, 0x7e, 0x06, 0x6d, - 0xf9, 0xc2, 0x47, 0x99, 0xe5, 0x14, 0xca, 0x00, 0xe3, 0x51, 0x79, 0xa2, 0x60, 0xae, 0xcc, 0xb1, - 0xc5, 0x62, 0x96, 0xd2, 0xc5, 0x30, 0x28, 0x54, 0x09, 0x50, 0xa6, 0xed, 0xea, 0xf2, 0xc1, 0x58, - 0xff, 0x0d, 0x85, 0xb7, 0x5e, 0xcc, 0x33, 0x8c, 0xc1, 0x1a, 0x5a, 0x61, 0x0c, 0xe4, 0x42, 0x6e, - 0x52, 0xd7, 0x0c, 0x34, 0x81, 0xbe, 0x5e, 0x56, 0xc8, 0x8f, 0xbc, 0xb2, 0xdc, 0x70, 0xa2, 0x51, - 0x21, 0xa4, 0x31, 0xa1, 0x66, 0x45, 0x79, 0xcc, 0x0a, 0xa5, 0x0b, 0x51, 0x83, 0x78, 0x39, 0x56, - 0x62, 0x91, 0xf9, 0x1a, 0x63, 0x75, 0x06, 0x9d, 0x2e, 0xb1, 0x92, 0xc5, 0xe6, 0x6b, 0x06, 0x7a, - 0x5a, 0x7c, 0x64, 0x9e, 0x9d, 0xf3, 0x2a, 0x2a, 0x84, 0xe2, 0xca, 0x37, 0x93, 0x3c, 0x7d, 0xc4, - 0x42, 0x71, 0xc2, 0x51, 0xf8, 0xd3, 0x09, 0x7d, 0x02, 0x4d, 0xf6, 0x20, 0x41, 0xab, 0x79, 0x86, - 0x98, 0xbf, 0x7b, 0xc6, 0x6b, 0x05, 0xa8, 0x1e, 0xcd, 0x4c, 0xe6, 0x5e, 0x53, 0x22, 0x92, 0xa9, - 0xcf, 0xa0, 0x2d, 0xd3, 0xf0, 0xdc, 0x92, 0x0a, 0xaf, 0x84, 0xdc, 0x92, 0x8a, 0x19, 0xbb, 0x6e, - 0x49, 0x87, 0x62, 0xf6, 0x86, 0x71, 0x69, 0xb2, 0xc8, 0xfe, 0x62, 0x7e, 0xfb, 0x9f, 0x01, 0x00, - 0x00, 0xff, 0xff, 0x9d, 0xa6, 0x7e, 0x1c, 0xf0, 0x2c, 0x00, 0x00, + // 3704 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x3a, 0x4b, 0x8f, 0xdc, 0x46, + 0x73, 0xcb, 0x79, 0xec, 0xcc, 0xd6, 0x3c, 0xb7, 0xf7, 0xa1, 0xd1, 0x48, 0xd6, 0x27, 0x33, 0xb6, + 0x22, 0xcb, 0xd2, 0x4a, 0x59, 0xc7, 0xf1, 0x27, 0x39, 0x36, 0xac, 0x5d, 0x6d, 0x2c, 0xd9, 0xab, + 0x07, 0xb8, 0x92, 0xa5, 0x04, 0x89, 0x09, 0x0e, 0xd9, 0xd2, 0x32, 0xe2, 0x34, 0xc7, 0x7c, 0xec, + 0x23, 0xa7, 0xc0, 0x06, 0x72, 0x48, 0x8e, 0xce, 0x31, 0x40, 0x72, 0xca, 0xc5, 0x39, 0x06, 0x08, + 0x90, 0x53, 0xce, 0xb9, 0x06, 0x08, 0x72, 0x08, 0x10, 0x04, 0xc8, 0x2f, 0xc8, 0x2f, 0x08, 0xfa, + 0xc5, 0xee, 0xe6, 0x70, 0xd6, 0x92, 0x91, 0xef, 0xc6, 0xae, 0xae, 0xae, 0xea, 0xaa, 0xae, 0xae, + 0xaa, 0xae, 0x22, 0x74, 0x4f, 0xf2, 0x20, 0x99, 0xf9, 0x5b, 0xb3, 0x24, 0xce, 0x62, 0xb4, 0xcc, + 0x47, 0xe3, 0x55, 0x8f, 0x90, 0x38, 0xf3, 0xb2, 0x30, 0x26, 0x29, 0x9f, 0xb2, 0x37, 0x60, 0xed, + 0x6e, 0x10, 0xec, 0xe6, 0x49, 0x82, 0x89, 0x7f, 0xea, 0xe0, 0x74, 0x16, 0x93, 0x14, 0xdb, 0xdf, + 0x42, 0xff, 0x6e, 0x10, 0x3c, 0xf1, 0xc2, 0xc4, 0xc1, 0xdf, 0xe5, 0x38, 0xcd, 0xd0, 0x7b, 0xd0, + 0x9b, 0x78, 0x29, 0x76, 0x7d, 0x81, 0x3a, 0xb2, 0x2e, 0x5b, 0x57, 0x57, 0x1c, 0x13, 0x88, 0xae, + 0x40, 0xff, 0xbb, 0x3c, 0xce, 0x34, 0xb4, 0x1a, 0x43, 0x2b, 0x41, 0xed, 0x55, 0x18, 0x14, 0xf4, + 0x05, 0xcb, 0x7f, 0xaa, 0x41, 0x6b, 0xc7, 0x8b, 0x3c, 0xe2, 0x63, 0xca, 0x2c, 0x8b, 0x33, 0x2f, + 0x72, 0x27, 0x1c, 0xc0, 0x98, 0x35, 0x1c, 0x13, 0x88, 0xae, 0xc2, 0xc0, 0x3f, 0xf4, 0x08, 0xc1, + 0x0a, 0xaf, 0xc6, 0xf0, 0xca, 0x60, 0xf4, 0x6b, 0x38, 0x37, 0xc3, 0x24, 0x08, 0xc9, 0x2b, 0xb7, + 0xbc, 0xa2, 0xce, 0x56, 0x2c, 0x9a, 0x46, 0x77, 0x60, 0x14, 0x12, 0xcf, 0xcf, 0xc2, 0x23, 0x3c, + 0xb7, 0xb4, 0xc1, 0x96, 0x2e, 0x9c, 0xa7, 0xca, 0x38, 0xf6, 0xa2, 0x08, 0x67, 0xc5, 0x8a, 0x26, + 0x5b, 0x51, 0x82, 0xa2, 0xcf, 0x61, 0x9c, 0x13, 0x3f, 0x26, 0x2f, 0xc3, 0x64, 0x8a, 0x03, 0xb7, + 0xb4, 0x66, 0x99, 0xad, 0x39, 0x03, 0xc3, 0xfe, 0x3d, 0x80, 0x1d, 0x8f, 0xc8, 0x83, 0xba, 0x0a, + 0x03, 0x12, 0x07, 0xd8, 0x0d, 0x03, 0x4c, 0xb2, 0xf0, 0x65, 0x88, 0x13, 0x71, 0x54, 0x65, 0xb0, + 0xdd, 0x83, 0x0e, 0x5b, 0x27, 0x0e, 0xe0, 0x13, 0x68, 0xee, 0x1e, 0x7a, 0x21, 0x41, 0xeb, 0xd0, + 0xf4, 0xe9, 0x87, 0x58, 0xc7, 0x07, 0x68, 0x04, 0x2d, 0x82, 0xb3, 0xe3, 0x38, 0x79, 0x2d, 0xce, + 0x54, 0x0e, 0xed, 0x19, 0xb4, 0x77, 0xb9, 0xe8, 0x29, 0xda, 0x84, 0x65, 0xae, 0x0d, 0xb6, 0xb8, + 0xe7, 0x88, 0x11, 0x1a, 0x43, 0x5b, 0xea, 0x89, 0x2d, 0xef, 0x39, 0xc5, 0x98, 0x52, 0x16, 0xea, + 0x67, 0xa7, 0xd1, 0x73, 0xe4, 0x90, 0x52, 0xf3, 0xa3, 0x38, 0xc5, 0x01, 0xd3, 0x75, 0xcf, 0x11, + 0x23, 0xfb, 0x27, 0x0b, 0xd6, 0x76, 0xe9, 0xa7, 0xe0, 0xfb, 0xd6, 0xb2, 0xd3, 0xfd, 0x94, 0x4c, + 0xb4, 0x18, 0x53, 0xf9, 0x5f, 0xc6, 0x89, 0xb0, 0x8d, 0xb6, 0xc3, 0x07, 0xe8, 0x32, 0x74, 0x02, + 0x9c, 0x66, 0x21, 0x61, 0xf7, 0x87, 0x6d, 0x68, 0xc5, 0xd1, 0x41, 0x4c, 0xf6, 0x69, 0x9c, 0x93, + 0x4c, 0x9c, 0xb3, 0x18, 0xd9, 0x9b, 0xb0, 0x6e, 0x6e, 0x56, 0x28, 0xfc, 0x3a, 0xf4, 0x77, 0x63, + 0x42, 0xb0, 0x9f, 0xc9, 0xfd, 0x8f, 0xa1, 0xcd, 0x36, 0x9a, 0x27, 0xa1, 0xd8, 0x78, 0x31, 0xa6, + 0x57, 0xa6, 0xc0, 0x16, 0x04, 0x6e, 0xc2, 0xea, 0x6e, 0x82, 0xbd, 0x0c, 0x3f, 0x8a, 0x03, 0xac, + 0xd1, 0x98, 0x79, 0x69, 0x7a, 0x1c, 0x27, 0x81, 0xa4, 0x21, 0xc7, 0xf6, 0x8f, 0x16, 0x20, 0x7d, + 0x05, 0xa7, 0x83, 0x7e, 0x0b, 0x7a, 0x29, 0xc6, 0x81, 0x3b, 0x25, 0x78, 0x1a, 0x93, 0xd0, 0x1f, + 0x59, 0x97, 0xeb, 0x57, 0x57, 0x9c, 0x2e, 0x05, 0x3e, 0x14, 0x30, 0xf4, 0x01, 0x0c, 0x43, 0x12, + 0x66, 0xa1, 0x17, 0x85, 0x7f, 0x86, 0x03, 0x37, 0x22, 0x41, 0x3a, 0xaa, 0x31, 0xbc, 0x81, 0x06, + 0xdf, 0x27, 0x41, 0x8a, 0x6e, 0x00, 0xd2, 0x51, 0x13, 0x8f, 0x2a, 0x5e, 0x68, 0x73, 0x55, 0x9b, + 0x71, 0xd8, 0x84, 0xfd, 0xef, 0x16, 0xb4, 0xa5, 0x07, 0x32, 0x0e, 0xc6, 0x2a, 0x1d, 0xcc, 0x67, + 0xd0, 0x49, 0x8f, 0xbd, 0x99, 0xeb, 0x47, 0x21, 0x26, 0x19, 0x3b, 0xb7, 0xfe, 0xf6, 0x85, 0x2d, + 0xe1, 0xeb, 0x24, 0x89, 0xad, 0x83, 0x63, 0x6f, 0xb6, 0xcb, 0x50, 0x1c, 0x1d, 0x9f, 0x7b, 0x95, + 0xd7, 0x98, 0xb8, 0x5e, 0x10, 0x24, 0x38, 0x4d, 0xd9, 0x8e, 0x56, 0x1c, 0x13, 0x48, 0x6f, 0x6d, + 0x80, 0xfd, 0x70, 0xea, 0x45, 0xee, 0x2c, 0xf2, 0x7c, 0x9c, 0x0a, 0xdb, 0x2b, 0x41, 0xed, 0x77, + 0x01, 0x14, 0x23, 0xd4, 0x82, 0xfa, 0xfe, 0xa3, 0x7b, 0xc3, 0x25, 0x04, 0xb0, 0xec, 0xdc, 0x7d, + 0x70, 0x6f, 0xef, 0xd1, 0xd0, 0xa2, 0x07, 0x7c, 0x0f, 0xcf, 0xe2, 0x34, 0xd4, 0x0f, 0x78, 0x91, + 0x74, 0xf6, 0x87, 0x30, 0x28, 0xb0, 0xc5, 0xc1, 0x8c, 0xa0, 0x25, 0xf7, 0xca, 0xb1, 0xe5, 0xd0, + 0xfe, 0x02, 0xd6, 0xef, 0x85, 0xa9, 0x1f, 0x1f, 0xe1, 0x84, 0x1e, 0x65, 0xfa, 0xf6, 0xb7, 0xff, + 0x63, 0xd8, 0x28, 0x51, 0x10, 0x4c, 0x2f, 0xc2, 0x0a, 0xc9, 0xa7, 0x2e, 0xc5, 0x4f, 0xc5, 0x2d, + 0x56, 0x00, 0xfb, 0x2f, 0x2d, 0x40, 0x7b, 0x27, 0xd8, 0xcf, 0x33, 0x4c, 0xc5, 0xd7, 0x04, 0x8b, + 0x93, 0x00, 0x27, 0x6e, 0x58, 0x58, 0x9d, 0x1c, 0xb3, 0xfb, 0xed, 0x85, 0x6c, 0x4a, 0x78, 0x0e, + 0x31, 0x44, 0x36, 0x74, 0x67, 0x18, 0x27, 0xee, 0x2c, 0x9f, 0xb8, 0xaf, 0xf1, 0xa9, 0x38, 0x10, + 0x03, 0x46, 0x29, 0x7f, 0x97, 0x7b, 0x24, 0x0b, 0xb3, 0x53, 0xe1, 0x71, 0x8b, 0x31, 0xbd, 0x00, + 0x5f, 0xe2, 0x4c, 0x44, 0x8d, 0x37, 0xd1, 0xf1, 0xdf, 0x5b, 0x80, 0xf4, 0x15, 0x42, 0xe4, 0x1d, + 0x68, 0x0b, 0x67, 0x9a, 0x32, 0xdb, 0xef, 0x6c, 0x5f, 0x95, 0x56, 0x35, 0x8f, 0xbd, 0x25, 0xc6, + 0xe9, 0x1e, 0xc9, 0x92, 0x53, 0x67, 0x99, 0xc9, 0x99, 0x8e, 0xf7, 0xa1, 0x67, 0x4c, 0xa0, 0x21, + 0xd4, 0xa9, 0x4c, 0x7c, 0x0b, 0xf4, 0x13, 0xbd, 0x0f, 0xcd, 0x23, 0x2f, 0xca, 0xb9, 0x07, 0xec, + 0x6c, 0x0f, 0x24, 0x0f, 0xc9, 0x80, 0xcf, 0xde, 0xa9, 0xfd, 0xda, 0xb2, 0x87, 0xd0, 0xff, 0x12, + 0x67, 0x0f, 0xc8, 0xcb, 0x58, 0x88, 0x65, 0xff, 0x45, 0x03, 0x06, 0x05, 0x48, 0xd9, 0xc7, 0x11, + 0x4e, 0x52, 0xea, 0x8f, 0x84, 0x7d, 0x88, 0x21, 0xd5, 0x2c, 0x3b, 0x70, 0xa9, 0x59, 0xae, 0x78, + 0x03, 0x86, 0x10, 0x34, 0xf2, 0x24, 0xa4, 0xd7, 0x80, 0xde, 0x62, 0xf6, 0x2d, 0x0f, 0x9f, 0x9e, + 0x80, 0x34, 0x7c, 0x05, 0x28, 0x66, 0xbd, 0x30, 0x49, 0x99, 0x93, 0x93, 0xb3, 0x14, 0x80, 0x3e, + 0x04, 0xa1, 0x0b, 0x16, 0xb3, 0x3a, 0xdb, 0x6b, 0x52, 0xbe, 0xc7, 0x0c, 0xba, 0x4b, 0x9d, 0xa1, + 0x54, 0x17, 0xda, 0x86, 0x7a, 0x44, 0x82, 0x51, 0x8b, 0x69, 0xfb, 0xb2, 0xa6, 0x6d, 0x5d, 0xc0, + 0xad, 0x7d, 0x12, 0x70, 0x2d, 0x53, 0x64, 0x74, 0x0d, 0x96, 0x85, 0x2f, 0x69, 0x33, 0x06, 0x48, + 0x2e, 0xe3, 0x8e, 0x84, 0xad, 0x14, 0x18, 0xd4, 0x89, 0x7b, 0x51, 0xe8, 0xa5, 0xa3, 0x15, 0x1e, + 0xc4, 0xd8, 0x40, 0x0f, 0x62, 0x60, 0x04, 0x31, 0x74, 0x0b, 0xd6, 0x64, 0x0e, 0xc0, 0x7c, 0xc6, + 0xa1, 0x97, 0x1e, 0xe2, 0x74, 0xd4, 0x61, 0xba, 0xa9, 0x9a, 0x42, 0x37, 0xa0, 0xe5, 0x53, 0x87, + 0x7c, 0x92, 0x8d, 0xba, 0xa6, 0xbc, 0xbb, 0x1c, 0xcc, 0xf6, 0x23, 0x71, 0xc6, 0x5f, 0x42, 0x5b, + 0x4a, 0xf3, 0x16, 0xa6, 0xb1, 0x4f, 0x02, 0x46, 0x46, 0x33, 0x8d, 0xcf, 0x99, 0x09, 0xd3, 0x3b, + 0xab, 0x99, 0xc7, 0x5b, 0x5c, 0x7c, 0x07, 0xd6, 0x8c, 0xf5, 0x45, 0x10, 0x18, 0x24, 0x78, 0x96, + 0xf3, 0xf4, 0xf0, 0xc0, 0x8f, 0x13, 0x1e, 0xc2, 0x57, 0x1d, 0x50, 0x60, 0x1a, 0xe2, 0x26, 0x34, + 0x88, 0xf1, 0x9b, 0xdc, 0x76, 0xc4, 0xc8, 0x3e, 0x07, 0x1b, 0xfb, 0x61, 0x9a, 0x09, 0x17, 0x1c, + 0x16, 0xfe, 0xc8, 0xfe, 0x0a, 0x36, 0xcb, 0x13, 0x82, 0xdf, 0x2d, 0x00, 0xbf, 0x80, 0x8a, 0x5b, + 0x37, 0x2c, 0xfb, 0x72, 0x47, 0xc3, 0xb1, 0xff, 0xd5, 0x82, 0x55, 0x4a, 0x8c, 0x9b, 0x93, 0x14, + 0x5c, 0xf3, 0x2e, 0x96, 0xe9, 0x5d, 0x3e, 0x86, 0x66, 0x7c, 0x4c, 0x70, 0x22, 0x02, 0xc5, 0xaf, + 0x0a, 0x9d, 0x96, 0x69, 0x6c, 0x3d, 0xa6, 0x68, 0x0e, 0xc7, 0xa6, 0x96, 0x13, 0x85, 0xd3, 0x30, + 0x13, 0xc9, 0x08, 0x1f, 0x50, 0xfd, 0x86, 0xc4, 0x8f, 0xf2, 0x00, 0xbb, 0xcc, 0x94, 0x44, 0x5c, + 0x68, 0x3b, 0x65, 0xb0, 0xfd, 0x1e, 0x34, 0x19, 0x3d, 0xd4, 0x86, 0xc6, 0xce, 0xe3, 0xa7, 0xf7, + 0x87, 0x4b, 0x34, 0x3a, 0x3c, 0x7e, 0xfe, 0x68, 0x68, 0x51, 0xd0, 0x93, 0xbd, 0x3d, 0x67, 0x58, + 0xb3, 0xff, 0xd6, 0x02, 0xa4, 0x6f, 0x44, 0x68, 0xe5, 0xf3, 0xe2, 0x0e, 0x71, 0x8d, 0x5c, 0xa9, + 0xda, 0xb4, 0xb8, 0x1c, 0x7c, 0x68, 0x7a, 0xa1, 0x07, 0xd0, 0xd1, 0xc0, 0x15, 0x86, 0xf6, 0x9e, + 0x69, 0x68, 0x7d, 0xf3, 0x8e, 0xea, 0x76, 0x86, 0x60, 0x48, 0x99, 0xd2, 0x24, 0xbd, 0x38, 0xce, + 0x0f, 0xf8, 0x09, 0x08, 0x98, 0xd8, 0xf3, 0x3a, 0x34, 0xb9, 0x47, 0xe0, 0x69, 0x03, 0x1f, 0x14, + 0xcb, 0xb1, 0xd2, 0xb3, 0xfd, 0x89, 0x58, 0x8e, 0x75, 0x91, 0x6d, 0x68, 0x72, 0x77, 0xc3, 0x25, + 0xee, 0xca, 0x1d, 0x51, 0x2c, 0x87, 0x4f, 0x49, 0xbe, 0x4f, 0x13, 0x4f, 0x8b, 0x75, 0xc5, 0x41, + 0x59, 0xda, 0x41, 0xd9, 0x9f, 0x72, 0xbd, 0x4a, 0x54, 0xc1, 0xe4, 0x7d, 0x58, 0xce, 0x18, 0x44, + 0x70, 0xe9, 0x49, 0x2e, 0x0c, 0xcf, 0x11, 0x93, 0xf6, 0x7f, 0x5a, 0xd0, 0x12, 0x57, 0x8e, 0xda, + 0x7a, 0x9a, 0x79, 0x59, 0x2e, 0x63, 0xaf, 0x18, 0xa1, 0xeb, 0xd0, 0x16, 0x99, 0x7e, 0x2a, 0x94, + 0xa8, 0xcc, 0x56, 0xc0, 0x9d, 0x02, 0x83, 0x32, 0x66, 0xf9, 0x33, 0x77, 0xb3, 0x1a, 0x63, 0x96, + 0x6b, 0x3b, 0x62, 0x92, 0x66, 0x97, 0x93, 0x28, 0xf6, 0x5f, 0x1f, 0xe2, 0xf0, 0xd5, 0x61, 0x26, + 0x3c, 0xaf, 0x0e, 0x2a, 0xbc, 0x75, 0x53, 0xf3, 0xd6, 0x9a, 0xff, 0x5f, 0x36, 0xfd, 0x7f, 0xe1, + 0xfe, 0x5a, 0x9a, 0xfb, 0xb3, 0xbf, 0x82, 0x3e, 0xbb, 0xf7, 0x2a, 0x0f, 0x2e, 0xc7, 0x09, 0xab, + 0x22, 0x4e, 0x14, 0xb4, 0x6a, 0x3a, 0xad, 0xbf, 0xb6, 0x00, 0x3d, 0x9e, 0x61, 0xf2, 0x1b, 0x49, + 0xc1, 0x55, 0x2a, 0x5d, 0xd7, 0x53, 0x69, 0xaa, 0xa6, 0x59, 0x9e, 0x1e, 0xba, 0x62, 0x92, 0xe7, + 0x03, 0x3a, 0x88, 0x3e, 0x68, 0x8d, 0x5d, 0x89, 0x54, 0xf9, 0x5f, 0x6a, 0xd0, 0x64, 0x26, 0xce, + 0xac, 0x35, 0x09, 0xc5, 0x9b, 0xd2, 0x72, 0xf8, 0xc0, 0xc8, 0x32, 0x6a, 0x66, 0x96, 0xa1, 0x7b, + 0x98, 0xba, 0xe9, 0x61, 0xfa, 0x50, 0x0b, 0x03, 0xf1, 0x14, 0xa8, 0x85, 0x01, 0xfa, 0x62, 0x5e, + 0xf8, 0x26, 0xb3, 0x90, 0x4d, 0x79, 0xea, 0xa6, 0xfa, 0x2b, 0x95, 0x12, 0xc5, 0xbe, 0x17, 0x51, + 0x66, 0xfc, 0x48, 0x8b, 0x31, 0xba, 0x04, 0xe0, 0xb3, 0xe4, 0x3d, 0x70, 0xbd, 0x8c, 0x1d, 0x6c, + 0xc3, 0xd1, 0x20, 0xe8, 0x7d, 0x68, 0xa4, 0x61, 0x80, 0x59, 0x70, 0xec, 0x6f, 0xaf, 0x1a, 0x37, + 0xfb, 0x20, 0x0c, 0xb0, 0xc3, 0xa6, 0xe9, 0x91, 0x87, 0xa9, 0x1b, 0x1f, 0x13, 0x97, 0xf9, 0x0c, + 0x16, 0x20, 0xdb, 0x8e, 0x01, 0xa3, 0xc6, 0x76, 0x18, 0x47, 0x01, 0x0b, 0x92, 0x0d, 0x87, 0x7d, + 0xdb, 0x7f, 0x67, 0x41, 0x97, 0xd1, 0x72, 0xf0, 0x34, 0x3e, 0xf2, 0x22, 0x43, 0x67, 0xd6, 0x62, + 0x9d, 0x95, 0x72, 0x3e, 0x3d, 0x53, 0xac, 0x97, 0x32, 0x45, 0x5d, 0xfa, 0x46, 0x49, 0xfa, 0xf2, + 0xb6, 0x9b, 0xf3, 0xdb, 0xb6, 0x0f, 0x61, 0x99, 0xfb, 0x31, 0x74, 0x03, 0x60, 0x92, 0x9f, 0xba, + 0x86, 0x2f, 0xed, 0x19, 0x1a, 0x71, 0x34, 0x04, 0x74, 0x13, 0x3a, 0x29, 0x8e, 0x22, 0x89, 0x5f, + 0xab, 0xc2, 0xd7, 0x31, 0xec, 0x8f, 0xa4, 0x9f, 0x65, 0x59, 0x0d, 0xd5, 0x17, 0x75, 0x54, 0xc2, + 0x13, 0xb1, 0x6f, 0xea, 0x7b, 0xe3, 0x63, 0x22, 0x5e, 0xbb, 0xf4, 0xd3, 0xfe, 0xde, 0x12, 0xab, + 0x9e, 0xcd, 0x02, 0x2f, 0xa3, 0x4e, 0xa9, 0xc9, 0x65, 0xb1, 0x98, 0x91, 0x98, 0xfc, 0xee, 0x2f, + 0x39, 0x7c, 0x16, 0xfd, 0x3e, 0xf4, 0xb8, 0x86, 0x12, 0xae, 0x78, 0xe1, 0x75, 0xd6, 0xcd, 0xed, + 0xf1, 0xb9, 0xfb, 0x4b, 0x8e, 0x89, 0xbc, 0xd3, 0x87, 0x2e, 0x07, 0xe4, 0x8c, 0xa9, 0xfd, 0x43, + 0x1d, 0x1a, 0xd4, 0xb5, 0x2e, 0x7e, 0x5c, 0xbc, 0x51, 0xf2, 0xf8, 0x05, 0x74, 0x23, 0x12, 0xc8, + 0xa1, 0xf4, 0x6e, 0x17, 0x75, 0xe7, 0x4d, 0x93, 0x97, 0x27, 0xf9, 0xe4, 0x6b, 0x7c, 0x2a, 0x82, + 0x94, 0xb1, 0x82, 0xf2, 0x0f, 0xc9, 0x24, 0xce, 0x49, 0x20, 0x22, 0xa9, 0x1c, 0xaa, 0x80, 0xd2, + 0xd4, 0x02, 0x0a, 0xbd, 0xfb, 0x27, 0x79, 0xe0, 0x9a, 0x0e, 0x4f, 0x07, 0xa1, 0xeb, 0xb0, 0x9a, + 0x62, 0x3f, 0x26, 0x41, 0xea, 0xfa, 0xfc, 0xa9, 0x8c, 0x03, 0x76, 0x4f, 0x7a, 0xce, 0xfc, 0x04, + 0x7d, 0xe8, 0xf1, 0x5c, 0xb1, 0x78, 0x0f, 0xb6, 0x79, 0xad, 0xca, 0x84, 0x56, 0x67, 0x92, 0xe3, + 0xcf, 0x60, 0x50, 0x12, 0xaf, 0x22, 0xd8, 0xae, 0xeb, 0xc1, 0x76, 0x45, 0x0f, 0xae, 0x7f, 0x5e, + 0x83, 0xd5, 0x27, 0xf4, 0x21, 0x29, 0x0e, 0xaf, 0x88, 0x68, 0xff, 0x6f, 0xbe, 0x49, 0xbf, 0x67, + 0x8d, 0xd2, 0x3d, 0x93, 0x9e, 0xa2, 0x79, 0xb6, 0xa7, 0xb8, 0x06, 0xc3, 0x04, 0xb3, 0xe7, 0xae, + 0x5b, 0x90, 0xe2, 0x6a, 0x9f, 0x83, 0xd3, 0xfc, 0x39, 0x9c, 0x4e, 0x71, 0x10, 0x7a, 0x19, 0x85, + 0xba, 0x3e, 0x7d, 0xd1, 0x44, 0x4c, 0xfb, 0x6d, 0xa7, 0x6a, 0x8a, 0xaa, 0x00, 0xe9, 0x2a, 0x10, + 0x91, 0xfa, 0x36, 0x0c, 0x43, 0x92, 0xe1, 0x84, 0x78, 0x91, 0x3b, 0xf5, 0x32, 0xff, 0x10, 0x2f, + 0xb8, 0xbf, 0x73, 0x68, 0xe8, 0x53, 0xe8, 0xb3, 0x04, 0x3d, 0xcd, 0x7d, 0x1f, 0xa7, 0x34, 0x45, + 0xe3, 0x17, 0xb9, 0x48, 0xcc, 0xe9, 0x8b, 0xf5, 0x80, 0x4f, 0x3a, 0x25, 0x54, 0xf4, 0x09, 0xcd, + 0x7f, 0xa7, 0x5e, 0x48, 0x68, 0x9e, 0xcf, 0xaf, 0x65, 0xbd, 0xe2, 0x5a, 0x3a, 0x65, 0x2c, 0x74, + 0x1b, 0x7a, 0x8c, 0xd4, 0x4b, 0x2f, 0x8c, 0xf2, 0x84, 0xe5, 0x85, 0x73, 0x4c, 0xff, 0x80, 0xcf, + 0x39, 0x26, 0xa6, 0xfd, 0xbf, 0x16, 0x0c, 0x94, 0x0a, 0xf6, 0x8e, 0x30, 0xa1, 0x5e, 0xbc, 0xc9, + 0xe4, 0x59, 0xe8, 0x14, 0xd8, 0x2c, 0xba, 0x0d, 0x5d, 0x5d, 0x00, 0xe1, 0x13, 0xaa, 0x24, 0xbd, + 0xbf, 0xe4, 0x18, 0xa8, 0xe8, 0xf6, 0x9b, 0x49, 0x7a, 0x7f, 0xa9, 0x4a, 0xd6, 0xae, 0x2e, 0x01, + 0x33, 0xac, 0x6a, 0x51, 0x0b, 0xae, 0x02, 0x75, 0xa7, 0x05, 0x4d, 0x4c, 0x05, 0xb4, 0xff, 0xc6, + 0x02, 0x50, 0x0f, 0xb6, 0x85, 0x69, 0x96, 0xe6, 0x9e, 0x6a, 0xa6, 0x7b, 0xd2, 0x13, 0xb0, 0xfa, + 0xcf, 0x26, 0x60, 0x5a, 0x8e, 0xd4, 0x98, 0xcb, 0x91, 0x78, 0x9d, 0xb3, 0xa9, 0xd5, 0x39, 0xed, + 0x18, 0x3a, 0xda, 0xfb, 0xed, 0x17, 0x6c, 0xef, 0x6d, 0x19, 0x7e, 0x04, 0x1b, 0xcc, 0x79, 0x63, + 0x55, 0x85, 0xff, 0xf9, 0x42, 0xc6, 0x08, 0x36, 0xcb, 0x8b, 0x44, 0xa6, 0xb3, 0x0f, 0x88, 0xcf, + 0x18, 0x9e, 0xe5, 0xac, 0xfa, 0xcc, 0x19, 0xfe, 0xc5, 0xfe, 0x18, 0xd6, 0x0c, 0x6a, 0xe2, 0x92, + 0x5e, 0x82, 0xa1, 0x44, 0x71, 0x63, 0xe2, 0xb2, 0x5c, 0xc1, 0xd2, 0x72, 0x85, 0x1b, 0xb0, 0xca, + 0x97, 0xe9, 0x2d, 0x84, 0x85, 0x2f, 0x35, 0x7b, 0x5d, 0xee, 0xd9, 0xe8, 0x08, 0xfc, 0x57, 0x8d, + 0x82, 0xd3, 0x2c, 0x4e, 0x8c, 0x02, 0xe7, 0x1b, 0x55, 0x2b, 0xf5, 0x2a, 0x68, 0xcd, 0xac, 0x82, + 0xa2, 0xaf, 0xa1, 0x43, 0x03, 0xd1, 0xc4, 0xf3, 0x5f, 0xe7, 0x33, 0x19, 0xb9, 0xae, 0x15, 0xb5, + 0x84, 0x39, 0x8e, 0x34, 0x8e, 0xed, 0x70, 0x64, 0x1e, 0xc7, 0x20, 0x2a, 0x00, 0xe8, 0xb7, 0x61, + 0x20, 0xe2, 0x45, 0xe0, 0x65, 0xde, 0xc4, 0x4b, 0xf9, 0xa5, 0xe8, 0xca, 0x30, 0x72, 0x4f, 0x40, + 0xd1, 0x2d, 0x58, 0x2f, 0x21, 0xba, 0x33, 0x2f, 0x3b, 0x14, 0xb6, 0x80, 0x4c, 0xec, 0x27, 0x5e, + 0x76, 0x88, 0xde, 0x65, 0x6d, 0x1c, 0x45, 0x77, 0x99, 0xd1, 0xa5, 0x11, 0x4f, 0xa2, 0x89, 0x28, + 0xa4, 0x6f, 0xee, 0xe7, 0xa2, 0x50, 0x57, 0x8f, 0x42, 0x3e, 0x3d, 0x5d, 0x4d, 0x5c, 0x55, 0x0f, + 0x4e, 0x38, 0x58, 0xd4, 0x79, 0x85, 0x86, 0x25, 0x90, 0x15, 0x79, 0xa9, 0xe0, 0x12, 0x49, 0x54, + 0x65, 0x78, 0x4d, 0xa0, 0x2f, 0xc1, 0xa2, 0xbc, 0xbb, 0x0a, 0x83, 0x83, 0xc3, 0x3c, 0x0b, 0xe2, + 0x63, 0xd9, 0xa3, 0xa0, 0x6f, 0x43, 0x05, 0x12, 0xa7, 0xfd, 0xbb, 0xb0, 0x79, 0x90, 0x4f, 0x52, + 0x3f, 0x09, 0x27, 0xd8, 0x7c, 0xe1, 0x8f, 0xa1, 0x8d, 0x4f, 0xc2, 0x34, 0x0b, 0xc9, 0x2b, 0x26, + 0x56, 0xdb, 0x29, 0xc6, 0xf6, 0x67, 0xb0, 0x51, 0xac, 0xa2, 0xde, 0x27, 0xd5, 0xfa, 0x55, 0xf2, + 0x61, 0x9e, 0x79, 0xaf, 0x45, 0x8e, 0xd5, 0x76, 0x4c, 0xa0, 0xfd, 0x93, 0x05, 0x1d, 0xcd, 0x69, + 0xfd, 0xc2, 0x32, 0xa6, 0x7e, 0x81, 0xea, 0xa5, 0x00, 0x5d, 0x2e, 0x71, 0x36, 0x2a, 0x4a, 0x9c, + 0x57, 0xa0, 0x2f, 0xbc, 0xa4, 0x9b, 0x60, 0x2f, 0x8d, 0xa5, 0x83, 0x28, 0x41, 0xed, 0xff, 0xa8, + 0xf3, 0xdd, 0x0a, 0xc7, 0x8e, 0xce, 0xcf, 0xed, 0xb6, 0xc5, 0xc6, 0x0f, 0xcc, 0x4c, 0xba, 0x56, + 0xca, 0xa4, 0xcf, 0xcc, 0x19, 0x16, 0xd5, 0x5a, 0xa9, 0x23, 0x4c, 0x58, 0xe9, 0x4b, 0x6c, 0x4e, + 0x8c, 0xe8, 0x83, 0x8f, 0x3f, 0xbd, 0xdc, 0x04, 0xfb, 0x38, 0x3c, 0xc2, 0x01, 0xcb, 0xa3, 0x1a, + 0x4e, 0x19, 0x4c, 0x13, 0x38, 0x01, 0x4a, 0x31, 0xc9, 0x58, 0x3a, 0xd5, 0x70, 0x74, 0xd0, 0x9c, + 0xb2, 0xa0, 0x42, 0x59, 0xd7, 0xa1, 0x91, 0xc4, 0x11, 0x1e, 0x75, 0x58, 0xee, 0x32, 0xaa, 0x08, + 0x78, 0x5b, 0x4e, 0x1c, 0x61, 0x87, 0x61, 0xd1, 0x94, 0x50, 0xfa, 0x4c, 0xb5, 0xbf, 0x2e, 0x23, + 0x3b, 0x3f, 0x41, 0x8d, 0xa6, 0x00, 0xb2, 0x3d, 0xf6, 0x78, 0x87, 0xc0, 0x00, 0xd2, 0x77, 0x58, + 0xe2, 0xce, 0x12, 0x1c, 0x4e, 0xbd, 0x57, 0x78, 0xd4, 0x67, 0x28, 0x1a, 0x44, 0x65, 0x71, 0x03, + 0x2d, 0x8b, 0xb3, 0x2f, 0x42, 0x83, 0xee, 0x0b, 0xad, 0x40, 0xf3, 0xe9, 0xdd, 0xaf, 0xf7, 0x9c, + 0xe1, 0x12, 0xfd, 0x7c, 0xc8, 0x3e, 0x2d, 0x7b, 0x17, 0x7a, 0x4f, 0x13, 0x2f, 0x08, 0xc9, 0xab, + 0xfd, 0x70, 0x1a, 0x66, 0xf4, 0x6c, 0x5b, 0x0f, 0xbd, 0x93, 0x03, 0x1c, 0x45, 0xf2, 0x6d, 0x35, + 0xf5, 0x4e, 0x5c, 0xfa, 0x04, 0x41, 0xe7, 0x60, 0xf9, 0xa1, 0x77, 0xb2, 0x93, 0x4b, 0x6f, 0xdd, + 0xa2, 0x33, 0x93, 0xfc, 0xd4, 0xfe, 0x67, 0x0b, 0x9a, 0xac, 0x9e, 0x41, 0xdf, 0x33, 0x53, 0x6a, + 0xe0, 0xee, 0xe2, 0xf7, 0x85, 0xa3, 0x63, 0xa0, 0x6d, 0xe8, 0x64, 0xda, 0x82, 0x5a, 0xd5, 0x82, + 0xbe, 0x86, 0x41, 0xad, 0x45, 0x59, 0x44, 0xdd, 0xb0, 0x88, 0xb3, 0xac, 0x48, 0xb3, 0xbd, 0xa6, + 0x19, 0x03, 0xb6, 0x61, 0xdd, 0xd0, 0xc0, 0x9b, 0x44, 0xc1, 0x7f, 0xb0, 0x60, 0xa3, 0xb4, 0x48, + 0xb8, 0xb0, 0xbb, 0xb0, 0xcc, 0xca, 0x41, 0x32, 0x77, 0xfc, 0x40, 0xaf, 0xf7, 0xcc, 0xa1, 0x6f, + 0xf1, 0xa1, 0x28, 0xa5, 0xf1, 0x85, 0xe3, 0x27, 0xd0, 0xd1, 0xc0, 0x15, 0x7e, 0xf5, 0x43, 0xb3, + 0x94, 0xb6, 0x51, 0xcd, 0x42, 0x73, 0xb7, 0xdf, 0x40, 0xf7, 0x19, 0x99, 0xfc, 0x82, 0x56, 0x2d, + 0xba, 0x08, 0x2b, 0x09, 0x16, 0x4f, 0x17, 0xe1, 0x66, 0x15, 0xc0, 0x1e, 0x40, 0x4f, 0xd0, 0x55, + 0x8d, 0xc1, 0x67, 0x24, 0x8a, 0xfd, 0xd7, 0x6f, 0xda, 0x18, 0xfc, 0xc1, 0x02, 0xa4, 0xaf, 0x50, + 0x81, 0x20, 0x67, 0xd0, 0x52, 0x20, 0x90, 0x40, 0x19, 0x08, 0x0a, 0x24, 0x33, 0x10, 0x48, 0x30, + 0x0f, 0x04, 0xe8, 0x57, 0xd0, 0xd1, 0x69, 0xf1, 0xb6, 0x03, 0x28, 0x4a, 0xf6, 0x5f, 0x59, 0x30, + 0x78, 0x1e, 0x66, 0x87, 0x41, 0xe2, 0x1d, 0xbf, 0xc1, 0xf1, 0x97, 0x5b, 0xb2, 0xb5, 0xb3, 0x5a, + 0xb2, 0x66, 0x1d, 0x69, 0x08, 0x75, 0x2f, 0x8a, 0xc4, 0xbb, 0x93, 0x7e, 0x52, 0xc8, 0x4b, 0x8c, + 0x45, 0x53, 0x83, 0x7e, 0xda, 0x77, 0x60, 0xa8, 0x36, 0x23, 0x14, 0x72, 0x05, 0xfa, 0x59, 0xe2, + 0x91, 0xd4, 0xf3, 0x29, 0x79, 0xe5, 0x77, 0x4b, 0xd0, 0x6b, 0x97, 0x60, 0xa5, 0x78, 0x4c, 0xa1, + 0x16, 0xd4, 0x77, 0x9e, 0xfd, 0xe1, 0x70, 0x09, 0xb5, 0xa1, 0x71, 0xb0, 0xb7, 0xbf, 0x3f, 0xb4, + 0xb6, 0xff, 0xdb, 0x82, 0xd6, 0x8b, 0x3c, 0x78, 0x40, 0xc2, 0x0c, 0xed, 0x01, 0xa8, 0x9e, 0x2c, + 0x3a, 0x5f, 0xa4, 0xb2, 0xe5, 0xce, 0xee, 0x78, 0x5c, 0x35, 0x25, 0x4e, 0x7c, 0x09, 0xdd, 0x87, + 0x8e, 0x16, 0xcb, 0xd1, 0x78, 0x71, 0x3e, 0x33, 0xbe, 0x50, 0x39, 0x57, 0x50, 0xda, 0x03, 0x50, + 0xb6, 0xa0, 0x36, 0x34, 0x67, 0x51, 0x6a, 0x43, 0xf3, 0xa6, 0x63, 0x2f, 0x6d, 0xff, 0xe3, 0x06, + 0xd4, 0x5f, 0xe4, 0x01, 0x7a, 0x01, 0x1d, 0xed, 0x17, 0x13, 0x34, 0x57, 0xe3, 0x57, 0xdb, 0xa9, + 0xfa, 0x13, 0x65, 0xfc, 0xfd, 0xbf, 0xfd, 0xcf, 0x8f, 0xb5, 0x75, 0x7b, 0x70, 0xf3, 0xe8, 0x77, + 0x6e, 0x7a, 0x41, 0x20, 0x0f, 0xff, 0x8e, 0x75, 0x0d, 0x39, 0xd0, 0x12, 0x7f, 0x91, 0xa0, 0x4d, + 0x8d, 0x86, 0x96, 0x73, 0x8e, 0xcf, 0xcd, 0xc1, 0x05, 0xdd, 0x4d, 0x46, 0x77, 0x68, 0x77, 0x04, + 0x5d, 0xea, 0x86, 0x28, 0xcd, 0x1d, 0xa8, 0xef, 0x78, 0x04, 0x21, 0xd5, 0x9b, 0x93, 0xd7, 0x75, + 0xbc, 0x66, 0xc0, 0x04, 0x1d, 0xc4, 0xe8, 0x74, 0xed, 0x16, 0xa5, 0x33, 0xf1, 0x08, 0xa5, 0xe1, + 0x43, 0x57, 0x6f, 0xf8, 0x23, 0xd5, 0xa2, 0x9e, 0xff, 0x67, 0x61, 0x7c, 0xb1, 0x7a, 0x52, 0x90, + 0x1f, 0x31, 0xf2, 0xc8, 0x1e, 0x52, 0xf2, 0xec, 0xef, 0x07, 0xf1, 0xb0, 0xa1, 0xc2, 0x8b, 0xff, + 0x01, 0x94, 0xf0, 0xe6, 0xef, 0x04, 0x4a, 0xf8, 0xf2, 0x8f, 0x03, 0x86, 0xf0, 0xc2, 0x8b, 0xd0, + 0x8d, 0x7f, 0x0b, 0xbd, 0xe7, 0xec, 0xdf, 0x12, 0xd1, 0x88, 0x56, 0x94, 0xcd, 0x3e, 0xb6, 0xa2, + 0x5c, 0xea, 0x58, 0xdb, 0x17, 0x19, 0xe5, 0x4d, 0x7b, 0x95, 0x52, 0xe6, 0xff, 0xa9, 0x04, 0x1c, + 0x85, 0xd2, 0xff, 0x53, 0xe8, 0x19, 0x3d, 0x67, 0x54, 0x08, 0x5f, 0xd5, 0xcc, 0x1e, 0xbf, 0xb3, + 0x60, 0xb6, 0x8a, 0x57, 0x20, 0x50, 0x58, 0x97, 0x9a, 0xf2, 0x7a, 0x01, 0xa0, 0x7a, 0xb7, 0xca, + 0x8a, 0xe7, 0xfa, 0xc5, 0xca, 0x8a, 0xe7, 0x5b, 0xbd, 0xf6, 0x1a, 0x63, 0xd1, 0x43, 0x1d, 0x7e, + 0xba, 0x9c, 0xd6, 0x3e, 0xb4, 0x44, 0x9f, 0x52, 0xe9, 0xc7, 0x6c, 0xd6, 0x2a, 0xfd, 0x94, 0x1a, + 0x9a, 0xf6, 0x90, 0x11, 0x04, 0xd4, 0xa6, 0x04, 0x43, 0x4a, 0xe2, 0x8f, 0xa1, 0xa3, 0xb5, 0xe3, + 0x90, 0xbe, 0x9b, 0x52, 0x8f, 0x4f, 0x5d, 0x94, 0x8a, 0xfe, 0x9d, 0xbd, 0xce, 0x28, 0xf7, 0x51, + 0x97, 0x52, 0xa6, 0x5a, 0x60, 0xd4, 0x9f, 0x03, 0xa8, 0xce, 0x91, 0xd2, 0xc2, 0x5c, 0x0b, 0x4c, + 0x69, 0x61, 0xbe, 0xd1, 0x24, 0x6d, 0x1c, 0x01, 0x25, 0x2d, 0x2a, 0xa6, 0xaf, 0xa0, 0x6f, 0x36, + 0xf6, 0xd0, 0x3b, 0x3a, 0x85, 0xb9, 0x4e, 0xe0, 0xf8, 0xd2, 0xa2, 0x69, 0xd3, 0x26, 0x51, 0x9f, + 0xd9, 0xa4, 0x22, 0x7b, 0x00, 0x2b, 0x45, 0xcb, 0x09, 0x8d, 0x74, 0x22, 0x7a, 0x67, 0x6a, 0x7c, + 0xbe, 0x62, 0x46, 0x50, 0x5e, 0x65, 0x94, 0x3b, 0x68, 0x85, 0x52, 0xe6, 0xb5, 0x44, 0x49, 0x94, + 0x75, 0xb5, 0x4d, 0xa2, 0x5a, 0xbf, 0xaa, 0x44, 0x54, 0xef, 0x5a, 0x95, 0x88, 0x32, 0x3a, 0xdf, + 0x72, 0x5d, 0xf3, 0xce, 0x93, 0xa9, 0x6b, 0xa3, 0x71, 0x65, 0xea, 0xda, 0x6c, 0x54, 0xd9, 0xe7, + 0x19, 0xdd, 0x35, 0x9b, 0xa9, 0x21, 0x0a, 0xd3, 0x8c, 0x77, 0xa6, 0xa8, 0x45, 0xbb, 0xd0, 0xd1, + 0x5a, 0x1b, 0xca, 0x52, 0xe6, 0xbb, 0x30, 0xca, 0x52, 0xaa, 0x7a, 0x21, 0xe7, 0x18, 0x8b, 0x55, + 0xee, 0x52, 0xe3, 0x19, 0x26, 0xd2, 0xa5, 0xfc, 0x09, 0x80, 0xaa, 0x46, 0x29, 0x01, 0xe6, 0xea, + 0x94, 0xca, 0xbc, 0x4b, 0xc5, 0x2b, 0x73, 0xf7, 0xac, 0x42, 0xc8, 0xcc, 0xe5, 0x8e, 0x75, 0xed, + 0x96, 0x85, 0x5e, 0x42, 0x5f, 0xe1, 0x1f, 0x9c, 0x12, 0xff, 0x2c, 0x16, 0xe3, 0xaa, 0x29, 0x21, + 0xc0, 0x3b, 0x8c, 0xcb, 0x39, 0x1b, 0x99, 0x5c, 0xd2, 0x53, 0xe2, 0x53, 0x3d, 0xfd, 0x11, 0x74, + 0xb4, 0x3f, 0x54, 0x94, 0x9e, 0xe6, 0x7f, 0x5b, 0x19, 0x57, 0xd5, 0xcb, 0xcc, 0x90, 0x83, 0xf9, + 0xa2, 0xf4, 0xd8, 0x9b, 0x51, 0xda, 0x04, 0xfa, 0x66, 0xdd, 0x45, 0x99, 0x7d, 0x65, 0x11, 0x47, + 0x99, 0xfd, 0x82, 0x72, 0x8d, 0x21, 0x0b, 0xab, 0xd9, 0x63, 0x3d, 0xc4, 0x4d, 0x68, 0x54, 0x2f, + 0xea, 0x2f, 0x7a, 0x54, 0x2f, 0x97, 0x78, 0xf4, 0xa8, 0x3e, 0x57, 0xb0, 0x31, 0x65, 0xe2, 0x6c, + 0xe4, 0xc9, 0x50, 0xbb, 0x55, 0xd5, 0x17, 0x75, 0x26, 0x73, 0x05, 0x9c, 0xf1, 0xb8, 0x6a, 0xaa, + 0xca, 0x6e, 0x39, 0x03, 0x19, 0x52, 0xbf, 0x81, 0xb6, 0x7c, 0xed, 0xa3, 0xc2, 0x72, 0x4a, 0x25, + 0x81, 0xf1, 0x68, 0x7e, 0xa2, 0x64, 0xae, 0xcc, 0xb1, 0xa5, 0x62, 0x96, 0xd2, 0xc5, 0x30, 0x28, + 0x55, 0x0c, 0x50, 0xa1, 0xed, 0xea, 0x52, 0xc2, 0xd8, 0xfc, 0x25, 0x85, 0xb7, 0x61, 0xec, 0x0b, + 0x8c, 0xc1, 0x06, 0x5a, 0x63, 0x0c, 0xe4, 0x42, 0x6e, 0x52, 0xb7, 0x2c, 0x34, 0x81, 0xbe, 0x59, + 0x62, 0x50, 0x47, 0x5e, 0x59, 0x7a, 0x38, 0xd3, 0xa8, 0x10, 0x32, 0x98, 0x50, 0xb3, 0xa2, 0x3c, + 0x66, 0xa5, 0x32, 0x86, 0xa8, 0x47, 0xbc, 0x1d, 0x2b, 0xb1, 0xc8, 0x7e, 0x97, 0xb1, 0xba, 0x80, + 0xce, 0xcf, 0xb1, 0x92, 0x85, 0xe7, 0x5b, 0x16, 0x7a, 0x55, 0x7e, 0x70, 0x5e, 0x5c, 0xf0, 0x42, + 0x2a, 0x85, 0xe2, 0xca, 0xf7, 0x93, 0x3c, 0x7d, 0xc4, 0x42, 0x71, 0xc6, 0x51, 0xf8, 0x33, 0x0a, + 0x7d, 0x05, 0x4d, 0xf6, 0x38, 0x41, 0xeb, 0x2a, 0x5b, 0x54, 0x6f, 0xa0, 0xf1, 0x46, 0x09, 0x6a, + 0x46, 0x33, 0x9b, 0xb9, 0xd7, 0x9c, 0x88, 0xc4, 0x6a, 0x02, 0x7d, 0x9e, 0x9f, 0xc8, 0xc4, 0x5c, + 0xd9, 0x53, 0xe9, 0xdd, 0xa0, 0xec, 0xa9, 0x9c, 0xc3, 0x9b, 0x37, 0x8e, 0xa7, 0x28, 0xc7, 0x02, + 0xe7, 0x8e, 0x75, 0x6d, 0xb2, 0xcc, 0x7e, 0x8c, 0xfe, 0xe8, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, + 0x20, 0x61, 0x16, 0x94, 0x43, 0x2d, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4670,7 +4692,7 @@ type XudClient interface { Connect(ctx context.Context, in *ConnectRequest, opts ...grpc.CallOption) (*ConnectResponse, error) // Gets an address to deposit a given currency into the xud wallets. // shell: xucli deposit - Deposit(ctx context.Context, in *DepositRequest, opts ...grpc.CallOption) (*DepositResponse, error) + WalletDeposit(ctx context.Context, in *DepositRequest, opts ...grpc.CallOption) (*DepositResponse, error) // Discover nodes from a specific peer and apply new connections DiscoverNodes(ctx context.Context, in *DiscoverNodesRequest, opts ...grpc.CallOption) (*DiscoverNodesResponse, error) // Gets the total balance available across all payment channels and wallets for one or all currencies. @@ -4756,7 +4778,7 @@ type XudClient interface { Unban(ctx context.Context, in *UnbanRequest, opts ...grpc.CallOption) (*UnbanResponse, error) // Withdraws a given currency from the xud wallets to a specified address. // shell: xucli withdraw [fee] - Withdraw(ctx context.Context, in *WithdrawRequest, opts ...grpc.CallOption) (*WithdrawResponse, error) + WalletWithdraw(ctx context.Context, in *WithdrawRequest, opts ...grpc.CallOption) (*WithdrawResponse, error) } type xudClient struct { @@ -4812,9 +4834,9 @@ func (c *xudClient) Connect(ctx context.Context, in *ConnectRequest, opts ...grp return out, nil } -func (c *xudClient) Deposit(ctx context.Context, in *DepositRequest, opts ...grpc.CallOption) (*DepositResponse, error) { +func (c *xudClient) WalletDeposit(ctx context.Context, in *DepositRequest, opts ...grpc.CallOption) (*DepositResponse, error) { out := new(DepositResponse) - err := c.cc.Invoke(ctx, "/xudrpc.Xud/Deposit", in, out, opts...) + err := c.cc.Invoke(ctx, "/xudrpc.Xud/WalletDeposit", in, out, opts...) if err != nil { return nil, err } @@ -5111,9 +5133,9 @@ func (c *xudClient) Unban(ctx context.Context, in *UnbanRequest, opts ...grpc.Ca return out, nil } -func (c *xudClient) Withdraw(ctx context.Context, in *WithdrawRequest, opts ...grpc.CallOption) (*WithdrawResponse, error) { +func (c *xudClient) WalletWithdraw(ctx context.Context, in *WithdrawRequest, opts ...grpc.CallOption) (*WithdrawResponse, error) { out := new(WithdrawResponse) - err := c.cc.Invoke(ctx, "/xudrpc.Xud/Withdraw", in, out, opts...) + err := c.cc.Invoke(ctx, "/xudrpc.Xud/WalletWithdraw", in, out, opts...) if err != nil { return nil, err } @@ -5145,7 +5167,7 @@ type XudServer interface { Connect(context.Context, *ConnectRequest) (*ConnectResponse, error) // Gets an address to deposit a given currency into the xud wallets. // shell: xucli deposit - Deposit(context.Context, *DepositRequest) (*DepositResponse, error) + WalletDeposit(context.Context, *DepositRequest) (*DepositResponse, error) // Discover nodes from a specific peer and apply new connections DiscoverNodes(context.Context, *DiscoverNodesRequest) (*DiscoverNodesResponse, error) // Gets the total balance available across all payment channels and wallets for one or all currencies. @@ -5231,7 +5253,7 @@ type XudServer interface { Unban(context.Context, *UnbanRequest) (*UnbanResponse, error) // Withdraws a given currency from the xud wallets to a specified address. // shell: xucli withdraw [fee] - Withdraw(context.Context, *WithdrawRequest) (*WithdrawResponse, error) + WalletWithdraw(context.Context, *WithdrawRequest) (*WithdrawResponse, error) } func RegisterXudServer(s *grpc.Server, srv XudServer) { @@ -5328,20 +5350,20 @@ func _Xud_Connect_Handler(srv interface{}, ctx context.Context, dec func(interfa return interceptor(ctx, in, info, handler) } -func _Xud_Deposit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Xud_WalletDeposit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DepositRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(XudServer).Deposit(ctx, in) + return srv.(XudServer).WalletDeposit(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xudrpc.Xud/Deposit", + FullMethod: "/xudrpc.Xud/WalletDeposit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(XudServer).Deposit(ctx, req.(*DepositRequest)) + return srv.(XudServer).WalletDeposit(ctx, req.(*DepositRequest)) } return interceptor(ctx, in, info, handler) } @@ -5754,20 +5776,20 @@ func _Xud_Unban_Handler(srv interface{}, ctx context.Context, dec func(interface return interceptor(ctx, in, info, handler) } -func _Xud_Withdraw_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Xud_WalletWithdraw_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(WithdrawRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(XudServer).Withdraw(ctx, in) + return srv.(XudServer).WalletWithdraw(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/xudrpc.Xud/Withdraw", + FullMethod: "/xudrpc.Xud/WalletWithdraw", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(XudServer).Withdraw(ctx, req.(*WithdrawRequest)) + return srv.(XudServer).WalletWithdraw(ctx, req.(*WithdrawRequest)) } return interceptor(ctx, in, info, handler) } @@ -5797,8 +5819,8 @@ var _Xud_serviceDesc = grpc.ServiceDesc{ Handler: _Xud_Connect_Handler, }, { - MethodName: "Deposit", - Handler: _Xud_Deposit_Handler, + MethodName: "WalletDeposit", + Handler: _Xud_WalletDeposit_Handler, }, { MethodName: "DiscoverNodes", @@ -5873,8 +5895,8 @@ var _Xud_serviceDesc = grpc.ServiceDesc{ Handler: _Xud_Unban_Handler, }, { - MethodName: "Withdraw", - Handler: _Xud_Withdraw_Handler, + MethodName: "WalletWithdraw", + Handler: _Xud_WalletWithdraw_Handler, }, }, Streams: []grpc.StreamDesc{