From 5bc07c7cddef5ce80244373e9ada7874f430111d Mon Sep 17 00:00:00 2001 From: michael1011 Date: Sat, 24 Aug 2024 15:10:30 +0200 Subject: [PATCH] feat: get paystatus from mpay plugin --- lib/lightning/cln/ClnClient.ts | 21 +- lib/lightning/cln/MpayClient.ts | 10 + lib/proto/mpay/mpay_grpc_pb.d.ts | 17 + lib/proto/mpay/mpay_grpc_pb.js | 34 + lib/proto/mpay/mpay_pb.d.ts | 224 +++ lib/proto/mpay/mpay_pb.js | 1742 ++++++++++++++++++++ tools/plugins/mpay/pay/mpay.py | 21 +- tools/plugins/mpay/protos/mpay.proto | 53 + tools/plugins/mpay/protos/mpay_pb2.py | 22 +- tools/plugins/mpay/protos/mpay_pb2.pyi | 78 + tools/plugins/mpay/protos/mpay_pb2_grpc.py | 44 + tools/plugins/mpay/rpc/server.py | 17 +- tools/plugins/mpay/rpc/transformers.py | 68 +- tools/plugins/mpay/utils.py | 7 + 14 files changed, 2342 insertions(+), 16 deletions(-) diff --git a/lib/lightning/cln/ClnClient.ts b/lib/lightning/cln/ClnClient.ts index b62a7e12..db9879aa 100644 --- a/lib/lightning/cln/ClnClient.ts +++ b/lib/lightning/cln/ClnClient.ts @@ -20,6 +20,7 @@ import { ListfundsOutputs, ListpaysPays } from '../../proto/cln/node_pb'; import * as primitivesrpc from '../../proto/cln/primitives_pb'; import { HoldClient } from '../../proto/hold/hold_grpc_pb'; import * as holdrpc from '../../proto/hold/hold_pb'; +import * as mpayrpc from '../../proto/mpay/mpay_pb'; import { WalletBalance } from '../../wallet/providers/WalletProviderInterface'; import { msatToSat, satToMsat, scidClnToLnd } from '../ChannelUtils'; import Errors from '../Errors'; @@ -720,7 +721,25 @@ class ClnClient }; } - // TODO: find a way to check "paystatus" + // ... has failed... + if (this.mpay !== undefined) { + for (const payStatus of (await this.mpay.payStatus(invoice)).statusList) { + for (const attempt of payStatus.attemptsList) { + if ( + attempt.state === + mpayrpc.PayStatusResponse.PayStatus.Attempt.AttemptState + .ATTEMPT_PENDING || + attempt.failure === undefined + ) { + continue; + } + + if (ClnClient.errIsIncorrectPaymentDetails(attempt.failure.message)) { + throw attempt.failure.message; + } + } + } + } // ... or is still pending const hasPendingPayments = pays.some( diff --git a/lib/lightning/cln/MpayClient.ts b/lib/lightning/cln/MpayClient.ts index ade232a1..0823905f 100644 --- a/lib/lightning/cln/MpayClient.ts +++ b/lib/lightning/cln/MpayClient.ts @@ -77,6 +77,16 @@ class Mpay extends BaseClient { public getInfo = (): Promise => this.unaryNodeCall('getInfo', new mpayrpc.GetInfoRequest()); + public payStatus = (invoice: string) => { + const req = new mpayrpc.PayStatusRequest(); + req.setBolt11(invoice); + + return this.unaryNodeCall< + mpayrpc.PayStatusRequest, + mpayrpc.PayStatusResponse.AsObject + >('payStatus', req); + }; + public sendPayment = async ( invoice: string, maxFeeMsat: number, diff --git a/lib/proto/mpay/mpay_grpc_pb.d.ts b/lib/proto/mpay/mpay_grpc_pb.d.ts index 06682536..5c4c7053 100644 --- a/lib/proto/mpay/mpay_grpc_pb.d.ts +++ b/lib/proto/mpay/mpay_grpc_pb.d.ts @@ -13,6 +13,7 @@ interface IMpayService extends grpc.ServiceDefinition { @@ -60,6 +61,15 @@ interface IMpayService_IResetPathMemory extends grpc.MethodDefinition; responseDeserialize: grpc.deserialize; } +interface IMpayService_IPayStatus extends grpc.MethodDefinition { + path: "/mpay.Mpay/PayStatus"; + requestStream: false; + responseStream: false; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} export const MpayService: IMpayService; @@ -69,6 +79,7 @@ export interface IMpayServer extends grpc.UntypedServiceImplementation { listPayments: grpc.handleUnaryCall; pay: grpc.handleUnaryCall; resetPathMemory: grpc.handleUnaryCall; + payStatus: grpc.handleUnaryCall; } export interface IMpayClient { @@ -87,6 +98,9 @@ export interface IMpayClient { resetPathMemory(request: mpay_pb.ResetPathMemoryRequest, callback: (error: grpc.ServiceError | null, response: mpay_pb.ResetPathMemoryResponse) => void): grpc.ClientUnaryCall; resetPathMemory(request: mpay_pb.ResetPathMemoryRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: mpay_pb.ResetPathMemoryResponse) => void): grpc.ClientUnaryCall; resetPathMemory(request: mpay_pb.ResetPathMemoryRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: mpay_pb.ResetPathMemoryResponse) => void): grpc.ClientUnaryCall; + payStatus(request: mpay_pb.PayStatusRequest, callback: (error: grpc.ServiceError | null, response: mpay_pb.PayStatusResponse) => void): grpc.ClientUnaryCall; + payStatus(request: mpay_pb.PayStatusRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: mpay_pb.PayStatusResponse) => void): grpc.ClientUnaryCall; + payStatus(request: mpay_pb.PayStatusRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: mpay_pb.PayStatusResponse) => void): grpc.ClientUnaryCall; } export class MpayClient extends grpc.Client implements IMpayClient { @@ -106,4 +120,7 @@ export class MpayClient extends grpc.Client implements IMpayClient { public resetPathMemory(request: mpay_pb.ResetPathMemoryRequest, callback: (error: grpc.ServiceError | null, response: mpay_pb.ResetPathMemoryResponse) => void): grpc.ClientUnaryCall; public resetPathMemory(request: mpay_pb.ResetPathMemoryRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: mpay_pb.ResetPathMemoryResponse) => void): grpc.ClientUnaryCall; public resetPathMemory(request: mpay_pb.ResetPathMemoryRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: mpay_pb.ResetPathMemoryResponse) => void): grpc.ClientUnaryCall; + public payStatus(request: mpay_pb.PayStatusRequest, callback: (error: grpc.ServiceError | null, response: mpay_pb.PayStatusResponse) => void): grpc.ClientUnaryCall; + public payStatus(request: mpay_pb.PayStatusRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: mpay_pb.PayStatusResponse) => void): grpc.ClientUnaryCall; + public payStatus(request: mpay_pb.PayStatusRequest, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: mpay_pb.PayStatusResponse) => void): grpc.ClientUnaryCall; } diff --git a/lib/proto/mpay/mpay_grpc_pb.js b/lib/proto/mpay/mpay_grpc_pb.js index e8c43a4c..6cba3ff6 100644 --- a/lib/proto/mpay/mpay_grpc_pb.js +++ b/lib/proto/mpay/mpay_grpc_pb.js @@ -92,6 +92,28 @@ function deserialize_mpay_PayResponse(buffer_arg) { return mpay_pb.PayResponse.deserializeBinary(new Uint8Array(buffer_arg)); } +function serialize_mpay_PayStatusRequest(arg) { + if (!(arg instanceof mpay_pb.PayStatusRequest)) { + throw new Error('Expected argument of type mpay.PayStatusRequest'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_mpay_PayStatusRequest(buffer_arg) { + return mpay_pb.PayStatusRequest.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_mpay_PayStatusResponse(arg) { + if (!(arg instanceof mpay_pb.PayStatusResponse)) { + throw new Error('Expected argument of type mpay.PayStatusResponse'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_mpay_PayStatusResponse(buffer_arg) { + return mpay_pb.PayStatusResponse.deserializeBinary(new Uint8Array(buffer_arg)); +} + function serialize_mpay_ResetPathMemoryRequest(arg) { if (!(arg instanceof mpay_pb.ResetPathMemoryRequest)) { throw new Error('Expected argument of type mpay.ResetPathMemoryRequest'); @@ -171,6 +193,18 @@ var MpayService = exports.MpayService = { responseSerialize: serialize_mpay_ResetPathMemoryResponse, responseDeserialize: deserialize_mpay_ResetPathMemoryResponse, }, + // Workaround to expose the paystatus command via gRPC, since CLN doesn't +payStatus: { + path: '/mpay.Mpay/PayStatus', + requestStream: false, + responseStream: false, + requestType: mpay_pb.PayStatusRequest, + responseType: mpay_pb.PayStatusResponse, + requestSerialize: serialize_mpay_PayStatusRequest, + requestDeserialize: deserialize_mpay_PayStatusRequest, + responseSerialize: serialize_mpay_PayStatusResponse, + responseDeserialize: deserialize_mpay_PayStatusResponse, + }, }; exports.MpayClient = grpc.makeGenericClientConstructor(MpayService); diff --git a/lib/proto/mpay/mpay_pb.d.ts b/lib/proto/mpay/mpay_pb.d.ts index baa3dea4..d91e1a23 100644 --- a/lib/proto/mpay/mpay_pb.d.ts +++ b/lib/proto/mpay/mpay_pb.d.ts @@ -501,3 +501,227 @@ export namespace ResetPathMemoryResponse { hops: number, } } + +export class PayStatusRequest extends jspb.Message { + + hasBolt11(): boolean; + clearBolt11(): void; + getBolt11(): string | undefined; + setBolt11(value: string): PayStatusRequest; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): PayStatusRequest.AsObject; + static toObject(includeInstance: boolean, msg: PayStatusRequest): PayStatusRequest.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: PayStatusRequest, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): PayStatusRequest; + static deserializeBinaryFromReader(message: PayStatusRequest, reader: jspb.BinaryReader): PayStatusRequest; +} + +export namespace PayStatusRequest { + export type AsObject = { + bolt11?: string, + } +} + +export class PayStatusResponse extends jspb.Message { + clearStatusList(): void; + getStatusList(): Array; + setStatusList(value: Array): PayStatusResponse; + addStatus(value?: PayStatusResponse.PayStatus, index?: number): PayStatusResponse.PayStatus; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): PayStatusResponse.AsObject; + static toObject(includeInstance: boolean, msg: PayStatusResponse): PayStatusResponse.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: PayStatusResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): PayStatusResponse; + static deserializeBinaryFromReader(message: PayStatusResponse, reader: jspb.BinaryReader): PayStatusResponse; +} + +export namespace PayStatusResponse { + export type AsObject = { + statusList: Array, + } + + + export class PayStatus extends jspb.Message { + getBolt11(): string; + setBolt11(value: string): PayStatus; + getAmountMsat(): number; + setAmountMsat(value: number): PayStatus; + getDestination(): string; + setDestination(value: string): PayStatus; + clearAttemptsList(): void; + getAttemptsList(): Array; + setAttemptsList(value: Array): PayStatus; + addAttempts(value?: PayStatusResponse.PayStatus.Attempt, index?: number): PayStatusResponse.PayStatus.Attempt; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): PayStatus.AsObject; + static toObject(includeInstance: boolean, msg: PayStatus): PayStatus.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: PayStatus, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): PayStatus; + static deserializeBinaryFromReader(message: PayStatus, reader: jspb.BinaryReader): PayStatus; + } + + export namespace PayStatus { + export type AsObject = { + bolt11: string, + amountMsat: number, + destination: string, + attemptsList: Array, + } + + + export class Attempt extends jspb.Message { + getStrategy(): string; + setStrategy(value: string): Attempt; + getStartTime(): number; + setStartTime(value: number): Attempt; + getAgeInSeconds(): number; + setAgeInSeconds(value: number): Attempt; + + hasEndTime(): boolean; + clearEndTime(): void; + getEndTime(): number | undefined; + setEndTime(value: number): Attempt; + getState(): PayStatusResponse.PayStatus.Attempt.AttemptState; + setState(value: PayStatusResponse.PayStatus.Attempt.AttemptState): Attempt; + + hasSuccess(): boolean; + clearSuccess(): void; + getSuccess(): PayStatusResponse.PayStatus.Attempt.Success | undefined; + setSuccess(value?: PayStatusResponse.PayStatus.Attempt.Success): Attempt; + + hasFailure(): boolean; + clearFailure(): void; + getFailure(): PayStatusResponse.PayStatus.Attempt.Failure | undefined; + setFailure(value?: PayStatusResponse.PayStatus.Attempt.Failure): Attempt; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): Attempt.AsObject; + static toObject(includeInstance: boolean, msg: Attempt): Attempt.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: Attempt, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): Attempt; + static deserializeBinaryFromReader(message: Attempt, reader: jspb.BinaryReader): Attempt; + } + + export namespace Attempt { + export type AsObject = { + strategy: string, + startTime: number, + ageInSeconds: number, + endTime?: number, + state: PayStatusResponse.PayStatus.Attempt.AttemptState, + success?: PayStatusResponse.PayStatus.Attempt.Success.AsObject, + failure?: PayStatusResponse.PayStatus.Attempt.Failure.AsObject, + } + + + export class Success extends jspb.Message { + getId(): number; + setId(value: number): Success; + getPaymentPreimage(): string; + setPaymentPreimage(value: string): Success; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): Success.AsObject; + static toObject(includeInstance: boolean, msg: Success): Success.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: Success, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): Success; + static deserializeBinaryFromReader(message: Success, reader: jspb.BinaryReader): Success; + } + + export namespace Success { + export type AsObject = { + id: number, + paymentPreimage: string, + } + } + + export class Failure extends jspb.Message { + getMessage(): string; + setMessage(value: string): Failure; + getCode(): number; + setCode(value: number): Failure; + + hasData(): boolean; + clearData(): void; + getData(): PayStatusResponse.PayStatus.Attempt.Failure.Data | undefined; + setData(value?: PayStatusResponse.PayStatus.Attempt.Failure.Data): Failure; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): Failure.AsObject; + static toObject(includeInstance: boolean, msg: Failure): Failure.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: Failure, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): Failure; + static deserializeBinaryFromReader(message: Failure, reader: jspb.BinaryReader): Failure; + } + + export namespace Failure { + export type AsObject = { + message: string, + code: number, + data?: PayStatusResponse.PayStatus.Attempt.Failure.Data.AsObject, + } + + + export class Data extends jspb.Message { + getId(): number; + setId(value: number): Data; + getRawMessage(): string; + setRawMessage(value: string): Data; + getFailCode(): number; + setFailCode(value: number): Data; + getFailCodename(): string; + setFailCodename(value: string): Data; + getErringIndex(): number; + setErringIndex(value: number): Data; + getErringNode(): string; + setErringNode(value: string): Data; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): Data.AsObject; + static toObject(includeInstance: boolean, msg: Data): Data.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: Data, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): Data; + static deserializeBinaryFromReader(message: Data, reader: jspb.BinaryReader): Data; + } + + export namespace Data { + export type AsObject = { + id: number, + rawMessage: string, + failCode: number, + failCodename: string, + erringIndex: number, + erringNode: string, + } + } + + } + + + export enum AttemptState { + ATTEMPT_PENDING = 0, + ATTEMPT_COMPLETED = 1, + } + + } + + } + +} diff --git a/lib/proto/mpay/mpay_pb.js b/lib/proto/mpay/mpay_pb.js index 14df0570..1780416d 100644 --- a/lib/proto/mpay/mpay_pb.js +++ b/lib/proto/mpay/mpay_pb.js @@ -36,6 +36,14 @@ goog.exportSymbol('proto.mpay.ListPaymentsResponse.Payment.Attempt.Hop', null, g goog.exportSymbol('proto.mpay.PaginationParams', null, global); goog.exportSymbol('proto.mpay.PayRequest', null, global); goog.exportSymbol('proto.mpay.PayResponse', null, global); +goog.exportSymbol('proto.mpay.PayStatusRequest', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse.PayStatus', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse.PayStatus.Attempt', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data', null, global); +goog.exportSymbol('proto.mpay.PayStatusResponse.PayStatus.Attempt.Success', null, global); goog.exportSymbol('proto.mpay.ResetPathMemoryRequest', null, global); goog.exportSymbol('proto.mpay.ResetPathMemoryResponse', null, global); /** @@ -374,6 +382,153 @@ if (goog.DEBUG && !COMPILED) { */ proto.mpay.ResetPathMemoryResponse.displayName = 'proto.mpay.ResetPathMemoryResponse'; } +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusRequest = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.mpay.PayStatusRequest, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusRequest.displayName = 'proto.mpay.PayStatusRequest'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.mpay.PayStatusResponse.repeatedFields_, null); +}; +goog.inherits(proto.mpay.PayStatusResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusResponse.displayName = 'proto.mpay.PayStatusResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusResponse.PayStatus = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.mpay.PayStatusResponse.PayStatus.repeatedFields_, null); +}; +goog.inherits(proto.mpay.PayStatusResponse.PayStatus, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusResponse.PayStatus.displayName = 'proto.mpay.PayStatusResponse.PayStatus'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.mpay.PayStatusResponse.PayStatus.Attempt, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusResponse.PayStatus.Attempt.displayName = 'proto.mpay.PayStatusResponse.PayStatus.Attempt'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.mpay.PayStatusResponse.PayStatus.Attempt.Success, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.displayName = 'proto.mpay.PayStatusResponse.PayStatus.Attempt.Success'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.displayName = 'proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.displayName = 'proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data'; +} @@ -3930,4 +4085,1591 @@ proto.mpay.ResetPathMemoryResponse.prototype.setHops = function(value) { }; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusRequest.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusRequest.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusRequest} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusRequest.toObject = function(includeInstance, msg) { + var f, obj = { + bolt11: jspb.Message.getFieldWithDefault(msg, 1, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusRequest} + */ +proto.mpay.PayStatusRequest.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusRequest; + return proto.mpay.PayStatusRequest.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusRequest} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusRequest} + */ +proto.mpay.PayStatusRequest.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setBolt11(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusRequest.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusRequest.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusRequest} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusRequest.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = /** @type {string} */ (jspb.Message.getField(message, 1)); + if (f != null) { + writer.writeString( + 1, + f + ); + } +}; + + +/** + * optional string bolt11 = 1; + * @return {string} + */ +proto.mpay.PayStatusRequest.prototype.getBolt11 = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusRequest} returns this + */ +proto.mpay.PayStatusRequest.prototype.setBolt11 = function(value) { + return jspb.Message.setField(this, 1, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.mpay.PayStatusRequest} returns this + */ +proto.mpay.PayStatusRequest.prototype.clearBolt11 = function() { + return jspb.Message.setField(this, 1, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.mpay.PayStatusRequest.prototype.hasBolt11 = function() { + return jspb.Message.getField(this, 1) != null; +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.mpay.PayStatusResponse.repeatedFields_ = [1]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusResponse.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.toObject = function(includeInstance, msg) { + var f, obj = { + statusList: jspb.Message.toObjectList(msg.getStatusList(), + proto.mpay.PayStatusResponse.PayStatus.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusResponse} + */ +proto.mpay.PayStatusResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusResponse; + return proto.mpay.PayStatusResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusResponse} + */ +proto.mpay.PayStatusResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new proto.mpay.PayStatusResponse.PayStatus; + reader.readMessage(value,proto.mpay.PayStatusResponse.PayStatus.deserializeBinaryFromReader); + msg.addStatus(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getStatusList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 1, + f, + proto.mpay.PayStatusResponse.PayStatus.serializeBinaryToWriter + ); + } +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.mpay.PayStatusResponse.PayStatus.repeatedFields_ = [4]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusResponse.PayStatus.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusResponse.PayStatus} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.toObject = function(includeInstance, msg) { + var f, obj = { + bolt11: jspb.Message.getFieldWithDefault(msg, 1, ""), + amountMsat: jspb.Message.getFieldWithDefault(msg, 2, 0), + destination: jspb.Message.getFieldWithDefault(msg, 3, ""), + attemptsList: jspb.Message.toObjectList(msg.getAttemptsList(), + proto.mpay.PayStatusResponse.PayStatus.Attempt.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusResponse.PayStatus} + */ +proto.mpay.PayStatusResponse.PayStatus.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusResponse.PayStatus; + return proto.mpay.PayStatusResponse.PayStatus.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusResponse.PayStatus} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusResponse.PayStatus} + */ +proto.mpay.PayStatusResponse.PayStatus.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setBolt11(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setAmountMsat(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setDestination(value); + break; + case 4: + var value = new proto.mpay.PayStatusResponse.PayStatus.Attempt; + reader.readMessage(value,proto.mpay.PayStatusResponse.PayStatus.Attempt.deserializeBinaryFromReader); + msg.addAttempts(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusResponse.PayStatus.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusResponse.PayStatus} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getBolt11(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getAmountMsat(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getDestination(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getAttemptsList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 4, + f, + proto.mpay.PayStatusResponse.PayStatus.Attempt.serializeBinaryToWriter + ); + } +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusResponse.PayStatus.Attempt.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.toObject = function(includeInstance, msg) { + var f, obj = { + strategy: jspb.Message.getFieldWithDefault(msg, 1, ""), + startTime: jspb.Message.getFieldWithDefault(msg, 2, 0), + ageInSeconds: jspb.Message.getFieldWithDefault(msg, 3, 0), + endTime: jspb.Message.getFieldWithDefault(msg, 4, 0), + state: jspb.Message.getFieldWithDefault(msg, 5, 0), + success: (f = msg.getSuccess()) && proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.toObject(includeInstance, f), + failure: (f = msg.getFailure()) && proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.toObject(includeInstance, f) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusResponse.PayStatus.Attempt; + return proto.mpay.PayStatusResponse.PayStatus.Attempt.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setStrategy(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setStartTime(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint64()); + msg.setAgeInSeconds(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint64()); + msg.setEndTime(value); + break; + case 5: + var value = /** @type {!proto.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState} */ (reader.readEnum()); + msg.setState(value); + break; + case 6: + var value = new proto.mpay.PayStatusResponse.PayStatus.Attempt.Success; + reader.readMessage(value,proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.deserializeBinaryFromReader); + msg.setSuccess(value); + break; + case 7: + var value = new proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure; + reader.readMessage(value,proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.deserializeBinaryFromReader); + msg.setFailure(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusResponse.PayStatus.Attempt.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getStrategy(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getStartTime(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getAgeInSeconds(); + if (f !== 0) { + writer.writeUint64( + 3, + f + ); + } + f = /** @type {number} */ (jspb.Message.getField(message, 4)); + if (f != null) { + writer.writeUint64( + 4, + f + ); + } + f = message.getState(); + if (f !== 0.0) { + writer.writeEnum( + 5, + f + ); + } + f = message.getSuccess(); + if (f != null) { + writer.writeMessage( + 6, + f, + proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.serializeBinaryToWriter + ); + } + f = message.getFailure(); + if (f != null) { + writer.writeMessage( + 7, + f, + proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.serializeBinaryToWriter + ); + } +}; + + +/** + * @enum {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState = { + ATTEMPT_PENDING: 0, + ATTEMPT_COMPLETED: 1 +}; + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.toObject = function(includeInstance, msg) { + var f, obj = { + id: jspb.Message.getFieldWithDefault(msg, 1, 0), + paymentPreimage: jspb.Message.getFieldWithDefault(msg, 2, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusResponse.PayStatus.Attempt.Success; + return proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setId(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setPaymentPreimage(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getId(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } + f = message.getPaymentPreimage(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } +}; + + +/** + * optional uint64 id = 1; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.prototype.getId = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.prototype.setId = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional string payment_preimage = 2; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.prototype.getPaymentPreimage = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Success.prototype.setPaymentPreimage = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.toObject = function(includeInstance, msg) { + var f, obj = { + message: jspb.Message.getFieldWithDefault(msg, 1, ""), + code: jspb.Message.getFieldWithDefault(msg, 2, 0), + data: (f = msg.getData()) && proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.toObject(includeInstance, f) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure; + return proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setMessage(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setCode(value); + break; + case 3: + var value = new proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data; + reader.readMessage(value,proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.deserializeBinaryFromReader); + msg.setData(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getMessage(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getCode(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getData(); + if (f != null) { + writer.writeMessage( + 3, + f, + proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.serializeBinaryToWriter + ); + } +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.toObject = function(opt_includeInstance) { + return proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.toObject = function(includeInstance, msg) { + var f, obj = { + id: jspb.Message.getFieldWithDefault(msg, 1, 0), + rawMessage: jspb.Message.getFieldWithDefault(msg, 2, ""), + failCode: jspb.Message.getFieldWithDefault(msg, 3, 0), + failCodename: jspb.Message.getFieldWithDefault(msg, 4, ""), + erringIndex: jspb.Message.getFieldWithDefault(msg, 5, 0), + erringNode: jspb.Message.getFieldWithDefault(msg, 6, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data; + return proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setId(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setRawMessage(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFailCode(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setFailCodename(value); + break; + case 5: + var value = /** @type {number} */ (reader.readUint64()); + msg.setErringIndex(value); + break; + case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setErringNode(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getId(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } + f = message.getRawMessage(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getFailCode(); + if (f !== 0) { + writer.writeUint64( + 3, + f + ); + } + f = message.getFailCodename(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getErringIndex(); + if (f !== 0) { + writer.writeUint64( + 5, + f + ); + } + f = message.getErringNode(); + if (f.length > 0) { + writer.writeString( + 6, + f + ); + } +}; + + +/** + * optional uint64 id = 1; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.getId = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.setId = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional string raw_message = 2; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.getRawMessage = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.setRawMessage = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional uint64 fail_code = 3; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.getFailCode = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.setFailCode = function(value) { + return jspb.Message.setProto3IntField(this, 3, value); +}; + + +/** + * optional string fail_codename = 4; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.getFailCodename = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.setFailCodename = function(value) { + return jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional uint64 erring_index = 5; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.getErringIndex = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.setErringIndex = function(value) { + return jspb.Message.setProto3IntField(this, 5, value); +}; + + +/** + * optional string erring_node = 6; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.getErringNode = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data.prototype.setErringNode = function(value) { + return jspb.Message.setProto3StringField(this, 6, value); +}; + + +/** + * optional string message = 1; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.getMessage = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.setMessage = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint64 code = 2; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.getCode = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.setCode = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional Data data = 3; + * @return {?proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.getData = function() { + return /** @type{?proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data} */ ( + jspb.Message.getWrapperField(this, proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data, 3)); +}; + + +/** + * @param {?proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.Data|undefined} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} returns this +*/ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.setData = function(value) { + return jspb.Message.setWrapperField(this, 3, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.clearData = function() { + return this.setData(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure.prototype.hasData = function() { + return jspb.Message.getField(this, 3) != null; +}; + + +/** + * optional string strategy = 1; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getStrategy = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setStrategy = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint64 start_time = 2; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getStartTime = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setStartTime = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional uint64 age_in_seconds = 3; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getAgeInSeconds = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setAgeInSeconds = function(value) { + return jspb.Message.setProto3IntField(this, 3, value); +}; + + +/** + * optional uint64 end_time = 4; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getEndTime = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setEndTime = function(value) { + return jspb.Message.setField(this, 4, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.clearEndTime = function() { + return jspb.Message.setField(this, 4, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.hasEndTime = function() { + return jspb.Message.getField(this, 4) != null; +}; + + +/** + * optional AttemptState state = 5; + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getState = function() { + return /** @type {!proto.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setState = function(value) { + return jspb.Message.setProto3EnumField(this, 5, value); +}; + + +/** + * optional Success success = 6; + * @return {?proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getSuccess = function() { + return /** @type{?proto.mpay.PayStatusResponse.PayStatus.Attempt.Success} */ ( + jspb.Message.getWrapperField(this, proto.mpay.PayStatusResponse.PayStatus.Attempt.Success, 6)); +}; + + +/** + * @param {?proto.mpay.PayStatusResponse.PayStatus.Attempt.Success|undefined} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this +*/ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setSuccess = function(value) { + return jspb.Message.setWrapperField(this, 6, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.clearSuccess = function() { + return this.setSuccess(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.hasSuccess = function() { + return jspb.Message.getField(this, 6) != null; +}; + + +/** + * optional Failure failure = 7; + * @return {?proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.getFailure = function() { + return /** @type{?proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure} */ ( + jspb.Message.getWrapperField(this, proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure, 7)); +}; + + +/** + * @param {?proto.mpay.PayStatusResponse.PayStatus.Attempt.Failure|undefined} value + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this +*/ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.setFailure = function(value) { + return jspb.Message.setWrapperField(this, 7, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.clearFailure = function() { + return this.setFailure(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.mpay.PayStatusResponse.PayStatus.Attempt.prototype.hasFailure = function() { + return jspb.Message.getField(this, 7) != null; +}; + + +/** + * optional string bolt11 = 1; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.getBolt11 = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.setBolt11 = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint64 amount_msat = 2; + * @return {number} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.getAmountMsat = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.mpay.PayStatusResponse.PayStatus} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.setAmountMsat = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional string destination = 3; + * @return {string} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.getDestination = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.mpay.PayStatusResponse.PayStatus} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.setDestination = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * repeated Attempt attempts = 4; + * @return {!Array} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.getAttemptsList = function() { + return /** @type{!Array} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.mpay.PayStatusResponse.PayStatus.Attempt, 4)); +}; + + +/** + * @param {!Array} value + * @return {!proto.mpay.PayStatusResponse.PayStatus} returns this +*/ +proto.mpay.PayStatusResponse.PayStatus.prototype.setAttemptsList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 4, value); +}; + + +/** + * @param {!proto.mpay.PayStatusResponse.PayStatus.Attempt=} opt_value + * @param {number=} opt_index + * @return {!proto.mpay.PayStatusResponse.PayStatus.Attempt} + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.addAttempts = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.mpay.PayStatusResponse.PayStatus.Attempt, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.mpay.PayStatusResponse.PayStatus} returns this + */ +proto.mpay.PayStatusResponse.PayStatus.prototype.clearAttemptsList = function() { + return this.setAttemptsList([]); +}; + + +/** + * repeated PayStatus status = 1; + * @return {!Array} + */ +proto.mpay.PayStatusResponse.prototype.getStatusList = function() { + return /** @type{!Array} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.mpay.PayStatusResponse.PayStatus, 1)); +}; + + +/** + * @param {!Array} value + * @return {!proto.mpay.PayStatusResponse} returns this +*/ +proto.mpay.PayStatusResponse.prototype.setStatusList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 1, value); +}; + + +/** + * @param {!proto.mpay.PayStatusResponse.PayStatus=} opt_value + * @param {number=} opt_index + * @return {!proto.mpay.PayStatusResponse.PayStatus} + */ +proto.mpay.PayStatusResponse.prototype.addStatus = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.mpay.PayStatusResponse.PayStatus, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.mpay.PayStatusResponse} returns this + */ +proto.mpay.PayStatusResponse.prototype.clearStatusList = function() { + return this.setStatusList([]); +}; + + goog.object.extend(exports, proto.mpay); diff --git a/tools/plugins/mpay/pay/mpay.py b/tools/plugins/mpay/pay/mpay.py index 91666d19..1c97bef2 100644 --- a/tools/plugins/mpay/pay/mpay.py +++ b/tools/plugins/mpay/pay/mpay.py @@ -17,7 +17,8 @@ class MPay: default_max_fee_perc: float = 0.05 - _pl: Plugin + pl: Plugin + _db: Database _router: Router @@ -28,7 +29,7 @@ class MPay: _invoice_checker: InvoiceChecker def __init__(self, pl: Plugin, db: Database, routes: Routes) -> None: - self._pl = pl + self.pl = pl self._db = db self._excludes = Excludes() self._pay = PaymentHelper(pl) @@ -42,7 +43,7 @@ def init(self) -> None: self._invoice_checker.init() def reset_excludes(self) -> None: - self._pl.log("Resetting temporary exclude list") + self.pl.log("Resetting temporary exclude list") self._excludes.reset() def pay( @@ -54,7 +55,7 @@ def pay( max_delay: int | None = None, ) -> PaymentResult: self._invoice_checker.check(bolt11) - dec = self._pl.rpc.decodepay(bolt11) + dec = self.pl.rpc.decodepay(bolt11) amount = dec["amount_msat"] payment_hash = dec["payment_hash"] @@ -71,14 +72,14 @@ def pay( session.commit() max_fee = self._calculate_fee(amount, max_fee, exempt_fee) - self._pl.log( + self.pl.log( f"Paying {payment_hash} for {amount} with max fee " f"{fee_with_percent(dec['amount_msat'], max_fee)}" ) try: return Payer( - self._pl, + self.pl, self._router, self._pay, self._channels, @@ -97,7 +98,7 @@ def pay( payment.ok = False session.commit() - self._pl.log(f"Payment {payment_hash} failed: {format_error(e)}", level="warn") + self.pl.log(f"Payment {payment_hash} failed: {format_error(e)}", level="warn") raise @@ -108,7 +109,7 @@ def pay( def _check_for_paid(self, payment_hash: str) -> PaymentResult | None: res = [ entry - for entry in self._pl.rpc.listpays(payment_hash=payment_hash, status="complete")["pays"] + for entry in self.pl.rpc.listpays(payment_hash=payment_hash, status="complete")["pays"] if "preimage" in entry ] @@ -138,11 +139,11 @@ def _calculate_fee( return Millisatoshi(max_fee) calculated = Millisatoshi(round((int(amount) * self.default_max_fee_perc) / 100)) - self._pl.log(f"Calculated default max fee of {calculated}") + self.pl.log(f"Calculated default max fee of {calculated}") exemption = Millisatoshi(exempt_fee) if calculated < exemption: - self._pl.log(f"Using exempt fee of {exemption}") + self.pl.log(f"Using exempt fee of {exemption}") return exemption return calculated diff --git a/tools/plugins/mpay/protos/mpay.proto b/tools/plugins/mpay/protos/mpay.proto index 650e6f3a..7fe2eec6 100644 --- a/tools/plugins/mpay/protos/mpay.proto +++ b/tools/plugins/mpay/protos/mpay.proto @@ -11,6 +11,9 @@ service Mpay { rpc Pay (PayRequest) returns (PayResponse) {} rpc ResetPathMemory (ResetPathMemoryRequest) returns (ResetPathMemoryResponse) {} + + // Workaround to expose the paystatus command via gRPC, since CLN doesn't + rpc PayStatus (PayStatusRequest) returns (PayStatusResponse) {} } message GetInfoRequest {} @@ -112,3 +115,53 @@ message ResetPathMemoryResponse { uint64 attempts = 2; uint64 hops = 3; } + +message PayStatusRequest { + optional string bolt11 = 1; +} + +message PayStatusResponse { + message PayStatus { + message Attempt { + enum AttemptState { + ATTEMPT_PENDING = 0; + ATTEMPT_COMPLETED = 1; + } + + message Success { + uint64 id = 1; + string payment_preimage = 2; + } + + message Failure { + message Data { + uint64 id = 1; + string raw_message = 2; + uint64 fail_code = 3; + string fail_codename = 4; + uint64 erring_index = 5; + string erring_node = 6; + } + + string message = 1; + uint64 code = 2; + optional Data data = 3; + } + + string strategy = 1; + uint64 start_time = 2; + uint64 age_in_seconds = 3; + optional uint64 end_time = 4; + AttemptState state = 5; + optional Success success = 6; + optional Failure failure = 7; + } + + string bolt11 = 1; + uint64 amount_msat = 2; + string destination = 3; + repeated Attempt attempts = 4; + } + + repeated PayStatus status = 1; +} diff --git a/tools/plugins/mpay/protos/mpay_pb2.py b/tools/plugins/mpay/protos/mpay_pb2.py index e843db76..8fb06bf9 100644 --- a/tools/plugins/mpay/protos/mpay_pb2.py +++ b/tools/plugins/mpay/protos/mpay_pb2.py @@ -24,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmpay.proto\x12\x04mpay\"\x10\n\x0eGetInfoRequest\"\"\n\x0fGetInfoResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x98\x01\n\x10GetRoutesRequest\x12\x18\n\x0b\x64\x65stination\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bmin_success\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x1c\n\x0fmin_success_ema\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0e\n\x0c_destinationB\x0e\n\x0c_min_successB\x12\n\x10_min_success_ema\"\xa0\x02\n\x11GetRoutesResponse\x12\x33\n\x06routes\x18\x01 \x03(\x0b\x32#.mpay.GetRoutesResponse.RoutesEntry\x1a\x86\x01\n\x06Routes\x12\x34\n\x06routes\x18\x02 \x03(\x0b\x32$.mpay.GetRoutesResponse.Routes.Route\x1a\x46\n\x05Route\x12\r\n\x05route\x18\x01 \x03(\t\x12\x14\n\x0csuccess_rate\x18\x02 \x01(\x01\x12\x18\n\x10success_rate_ema\x18\x03 \x01(\x01\x1aM\n\x0bRoutesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12-\n\x05value\x18\x02 \x01(\x0b\x32\x1e.mpay.GetRoutesResponse.Routes:\x02\x38\x01\"{\n\x13ListPaymentsRequest\x12\x10\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x12\x16\n\x0cpayment_hash\x18\x02 \x01(\tH\x00\x12,\n\npagination\x18\x03 \x01(\x0b\x32\x16.mpay.PaginationParamsH\x00\x42\x0c\n\nidentifier\"1\n\x10PaginationParams\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\r\n\x05limit\x18\x02 \x01(\r\"\xd2\x03\n\x14ListPaymentsResponse\x12\x34\n\x08payments\x18\x01 \x03(\x0b\x32\".mpay.ListPaymentsResponse.Payment\x1a\x83\x03\n\x07Payment\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\t\x12\x0e\n\x06\x61mount\x18\x04 \x01(\x04\x12\n\n\x02ok\x18\x05 \x01(\x08\x12<\n\x08\x61ttempts\x18\x06 \x03(\x0b\x32*.mpay.ListPaymentsResponse.Payment.Attempt\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x1a\xd2\x01\n\x07\x41ttempt\x12\n\n\x02id\x18\x01 \x01(\x04\x12\n\n\x02ok\x18\x02 \x01(\x08\x12\x0c\n\x04time\x18\x03 \x01(\x04\x12<\n\x04hops\x18\x04 \x03(\x0b\x32..mpay.ListPaymentsResponse.Payment.Attempt.Hop\x12\x12\n\ncreated_at\x18\x05 \x01(\x04\x1aO\n\x03Hop\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0c\n\x04node\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x11\n\tdirection\x18\x04 \x01(\x04\x12\n\n\x02ok\x18\x05 \x01(\x08\"\xc2\x01\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x19\n\x0cmax_fee_msat\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x65xempt_fee_msat\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07timeout\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x16\n\tmax_delay\x18\x05 \x01(\x04H\x03\x88\x01\x01\x42\x0f\n\r_max_fee_msatB\x12\n\x10_exempt_fee_msatB\n\n\x08_timeoutB\x0c\n\n_max_delay\"\xd4\x01\n\x0bPayResponse\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\t\x12\x18\n\x10payment_preimage\x18\x02 \x01(\t\x12\x10\n\x08\x66\x65\x65_msat\x18\x03 \x01(\x04\x12\x0c\n\x04time\x18\x04 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x05 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x06 \x01(\x04\x12\x18\n\x10\x61mount_sent_msat\x18\x07 \x01(\x04\x12\r\n\x05parts\x18\x08 \x01(\r\x12\x0e\n\x06status\x18\t \x01(\t\x12\x12\n\ncreated_at\x18\n \x01(\x04\"\xa0\x01\n\x16ResetPathMemoryRequest\x12%\n\x18\x65xclude_permanent_memory\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12%\n\x18\x65xclude_temporary_memory\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x1b\n\x19_exclude_permanent_memoryB\x1b\n\x19_exclude_temporary_memory\"K\n\x17ResetPathMemoryResponse\x12\x10\n\x08payments\x18\x01 \x01(\x04\x12\x10\n\x08\x61ttempts\x18\x02 \x01(\x04\x12\x0c\n\x04hops\x18\x03 \x01(\x04\x32\xc9\x02\n\x04Mpay\x12\x38\n\x07GetInfo\x12\x14.mpay.GetInfoRequest\x1a\x15.mpay.GetInfoResponse\"\x00\x12>\n\tGetRoutes\x12\x16.mpay.GetRoutesRequest\x1a\x17.mpay.GetRoutesResponse\"\x00\x12G\n\x0cListPayments\x12\x19.mpay.ListPaymentsRequest\x1a\x1a.mpay.ListPaymentsResponse\"\x00\x12,\n\x03Pay\x12\x10.mpay.PayRequest\x1a\x11.mpay.PayResponse\"\x00\x12P\n\x0fResetPathMemory\x12\x1c.mpay.ResetPathMemoryRequest\x1a\x1d.mpay.ResetPathMemoryResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmpay.proto\x12\x04mpay\"\x10\n\x0eGetInfoRequest\"\"\n\x0fGetInfoResponse\x12\x0f\n\x07version\x18\x01 \x01(\t\"\x98\x01\n\x10GetRoutesRequest\x12\x18\n\x0b\x64\x65stination\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bmin_success\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x1c\n\x0fmin_success_ema\x18\x03 \x01(\x02H\x02\x88\x01\x01\x42\x0e\n\x0c_destinationB\x0e\n\x0c_min_successB\x12\n\x10_min_success_ema\"\xa0\x02\n\x11GetRoutesResponse\x12\x33\n\x06routes\x18\x01 \x03(\x0b\x32#.mpay.GetRoutesResponse.RoutesEntry\x1a\x86\x01\n\x06Routes\x12\x34\n\x06routes\x18\x02 \x03(\x0b\x32$.mpay.GetRoutesResponse.Routes.Route\x1a\x46\n\x05Route\x12\r\n\x05route\x18\x01 \x03(\t\x12\x14\n\x0csuccess_rate\x18\x02 \x01(\x01\x12\x18\n\x10success_rate_ema\x18\x03 \x01(\x01\x1aM\n\x0bRoutesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12-\n\x05value\x18\x02 \x01(\x0b\x32\x1e.mpay.GetRoutesResponse.Routes:\x02\x38\x01\"{\n\x13ListPaymentsRequest\x12\x10\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x12\x16\n\x0cpayment_hash\x18\x02 \x01(\tH\x00\x12,\n\npagination\x18\x03 \x01(\x0b\x32\x16.mpay.PaginationParamsH\x00\x42\x0c\n\nidentifier\"1\n\x10PaginationParams\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\r\n\x05limit\x18\x02 \x01(\r\"\xd2\x03\n\x14ListPaymentsResponse\x12\x34\n\x08payments\x18\x01 \x03(\x0b\x32\".mpay.ListPaymentsResponse.Payment\x1a\x83\x03\n\x07Payment\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\t\x12\x14\n\x0cpayment_hash\x18\x03 \x01(\t\x12\x0e\n\x06\x61mount\x18\x04 \x01(\x04\x12\n\n\x02ok\x18\x05 \x01(\x08\x12<\n\x08\x61ttempts\x18\x06 \x03(\x0b\x32*.mpay.ListPaymentsResponse.Payment.Attempt\x12\x12\n\ncreated_at\x18\x07 \x01(\x04\x1a\xd2\x01\n\x07\x41ttempt\x12\n\n\x02id\x18\x01 \x01(\x04\x12\n\n\x02ok\x18\x02 \x01(\x08\x12\x0c\n\x04time\x18\x03 \x01(\x04\x12<\n\x04hops\x18\x04 \x03(\x0b\x32..mpay.ListPaymentsResponse.Payment.Attempt.Hop\x12\x12\n\ncreated_at\x18\x05 \x01(\x04\x1aO\n\x03Hop\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0c\n\x04node\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x11\n\tdirection\x18\x04 \x01(\x04\x12\n\n\x02ok\x18\x05 \x01(\x08\"\xc2\x01\n\nPayRequest\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x19\n\x0cmax_fee_msat\x18\x02 \x01(\x04H\x00\x88\x01\x01\x12\x1c\n\x0f\x65xempt_fee_msat\x18\x03 \x01(\x04H\x01\x88\x01\x01\x12\x14\n\x07timeout\x18\x04 \x01(\x04H\x02\x88\x01\x01\x12\x16\n\tmax_delay\x18\x05 \x01(\x04H\x03\x88\x01\x01\x42\x0f\n\r_max_fee_msatB\x12\n\x10_exempt_fee_msatB\n\n\x08_timeoutB\x0c\n\n_max_delay\"\xd4\x01\n\x0bPayResponse\x12\x14\n\x0cpayment_hash\x18\x01 \x01(\t\x12\x18\n\x10payment_preimage\x18\x02 \x01(\t\x12\x10\n\x08\x66\x65\x65_msat\x18\x03 \x01(\x04\x12\x0c\n\x04time\x18\x04 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x05 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x06 \x01(\x04\x12\x18\n\x10\x61mount_sent_msat\x18\x07 \x01(\x04\x12\r\n\x05parts\x18\x08 \x01(\r\x12\x0e\n\x06status\x18\t \x01(\t\x12\x12\n\ncreated_at\x18\n \x01(\x04\"\xa0\x01\n\x16ResetPathMemoryRequest\x12%\n\x18\x65xclude_permanent_memory\x18\x01 \x01(\x08H\x00\x88\x01\x01\x12%\n\x18\x65xclude_temporary_memory\x18\x02 \x01(\x08H\x01\x88\x01\x01\x42\x1b\n\x19_exclude_permanent_memoryB\x1b\n\x19_exclude_temporary_memory\"K\n\x17ResetPathMemoryResponse\x12\x10\n\x08payments\x18\x01 \x01(\x04\x12\x10\n\x08\x61ttempts\x18\x02 \x01(\x04\x12\x0c\n\x04hops\x18\x03 \x01(\x04\"2\n\x10PayStatusRequest\x12\x13\n\x06\x62olt11\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_bolt11\"\x94\x07\n\x11PayStatusResponse\x12\x31\n\x06status\x18\x01 \x03(\x0b\x32!.mpay.PayStatusResponse.PayStatus\x1a\xcb\x06\n\tPayStatus\x12\x0e\n\x06\x62olt11\x18\x01 \x01(\t\x12\x13\n\x0b\x61mount_msat\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x65stination\x18\x03 \x01(\t\x12;\n\x08\x61ttempts\x18\x04 \x03(\x0b\x32).mpay.PayStatusResponse.PayStatus.Attempt\x1a\xc6\x05\n\x07\x41ttempt\x12\x10\n\x08strategy\x18\x01 \x01(\t\x12\x12\n\nstart_time\x18\x02 \x01(\x04\x12\x16\n\x0e\x61ge_in_seconds\x18\x03 \x01(\x04\x12\x15\n\x08\x65nd_time\x18\x04 \x01(\x04H\x00\x88\x01\x01\x12\x45\n\x05state\x18\x05 \x01(\x0e\x32\x36.mpay.PayStatusResponse.PayStatus.Attempt.AttemptState\x12G\n\x07success\x18\x06 \x01(\x0b\x32\x31.mpay.PayStatusResponse.PayStatus.Attempt.SuccessH\x01\x88\x01\x01\x12G\n\x07\x66\x61ilure\x18\x07 \x01(\x0b\x32\x31.mpay.PayStatusResponse.PayStatus.Attempt.FailureH\x02\x88\x01\x01\x1a/\n\x07Success\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x18\n\x10payment_preimage\x18\x02 \x01(\t\x1a\xfa\x01\n\x07\x46\x61ilure\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\x04\x12I\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x36.mpay.PayStatusResponse.PayStatus.Attempt.Failure.DataH\x00\x88\x01\x01\x1a|\n\x04\x44\x61ta\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x13\n\x0braw_message\x18\x02 \x01(\t\x12\x11\n\tfail_code\x18\x03 \x01(\x04\x12\x15\n\rfail_codename\x18\x04 \x01(\t\x12\x14\n\x0c\x65rring_index\x18\x05 \x01(\x04\x12\x13\n\x0b\x65rring_node\x18\x06 \x01(\tB\x07\n\x05_data\":\n\x0c\x41ttemptState\x12\x13\n\x0f\x41TTEMPT_PENDING\x10\x00\x12\x15\n\x11\x41TTEMPT_COMPLETED\x10\x01\x42\x0b\n\t_end_timeB\n\n\x08_successB\n\n\x08_failure2\x89\x03\n\x04Mpay\x12\x38\n\x07GetInfo\x12\x14.mpay.GetInfoRequest\x1a\x15.mpay.GetInfoResponse\"\x00\x12>\n\tGetRoutes\x12\x16.mpay.GetRoutesRequest\x1a\x17.mpay.GetRoutesResponse\"\x00\x12G\n\x0cListPayments\x12\x19.mpay.ListPaymentsRequest\x1a\x1a.mpay.ListPaymentsResponse\"\x00\x12,\n\x03Pay\x12\x10.mpay.PayRequest\x1a\x11.mpay.PayResponse\"\x00\x12P\n\x0fResetPathMemory\x12\x1c.mpay.ResetPathMemoryRequest\x1a\x1d.mpay.ResetPathMemoryResponse\"\x00\x12>\n\tPayStatus\x12\x16.mpay.PayStatusRequest\x1a\x17.mpay.PayStatusResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -67,6 +67,22 @@ _globals['_RESETPATHMEMORYREQUEST']._serialized_end=1738 _globals['_RESETPATHMEMORYRESPONSE']._serialized_start=1740 _globals['_RESETPATHMEMORYRESPONSE']._serialized_end=1815 - _globals['_MPAY']._serialized_start=1818 - _globals['_MPAY']._serialized_end=2147 + _globals['_PAYSTATUSREQUEST']._serialized_start=1817 + _globals['_PAYSTATUSREQUEST']._serialized_end=1867 + _globals['_PAYSTATUSRESPONSE']._serialized_start=1870 + _globals['_PAYSTATUSRESPONSE']._serialized_end=2786 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS']._serialized_start=1943 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS']._serialized_end=2786 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT']._serialized_start=2076 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT']._serialized_end=2786 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_SUCCESS']._serialized_start=2389 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_SUCCESS']._serialized_end=2436 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_FAILURE']._serialized_start=2439 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_FAILURE']._serialized_end=2689 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_FAILURE_DATA']._serialized_start=2556 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_FAILURE_DATA']._serialized_end=2680 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_ATTEMPTSTATE']._serialized_start=2691 + _globals['_PAYSTATUSRESPONSE_PAYSTATUS_ATTEMPT_ATTEMPTSTATE']._serialized_end=2749 + _globals['_MPAY']._serialized_start=2789 + _globals['_MPAY']._serialized_end=3182 # @@protoc_insertion_point(module_scope) diff --git a/tools/plugins/mpay/protos/mpay_pb2.pyi b/tools/plugins/mpay/protos/mpay_pb2.pyi index 32c7212e..6d5cea36 100644 --- a/tools/plugins/mpay/protos/mpay_pb2.pyi +++ b/tools/plugins/mpay/protos/mpay_pb2.pyi @@ -1,4 +1,5 @@ from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union @@ -174,3 +175,80 @@ class ResetPathMemoryResponse(_message.Message): attempts: int hops: int def __init__(self, payments: _Optional[int] = ..., attempts: _Optional[int] = ..., hops: _Optional[int] = ...) -> None: ... + +class PayStatusRequest(_message.Message): + __slots__ = ("bolt11",) + BOLT11_FIELD_NUMBER: _ClassVar[int] + bolt11: str + def __init__(self, bolt11: _Optional[str] = ...) -> None: ... + +class PayStatusResponse(_message.Message): + __slots__ = ("status",) + class PayStatus(_message.Message): + __slots__ = ("bolt11", "amount_msat", "destination", "attempts") + class Attempt(_message.Message): + __slots__ = ("strategy", "start_time", "age_in_seconds", "end_time", "state", "success", "failure") + class AttemptState(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + ATTEMPT_PENDING: _ClassVar[PayStatusResponse.PayStatus.Attempt.AttemptState] + ATTEMPT_COMPLETED: _ClassVar[PayStatusResponse.PayStatus.Attempt.AttemptState] + ATTEMPT_PENDING: PayStatusResponse.PayStatus.Attempt.AttemptState + ATTEMPT_COMPLETED: PayStatusResponse.PayStatus.Attempt.AttemptState + class Success(_message.Message): + __slots__ = ("id", "payment_preimage") + ID_FIELD_NUMBER: _ClassVar[int] + PAYMENT_PREIMAGE_FIELD_NUMBER: _ClassVar[int] + id: int + payment_preimage: str + def __init__(self, id: _Optional[int] = ..., payment_preimage: _Optional[str] = ...) -> None: ... + class Failure(_message.Message): + __slots__ = ("message", "code", "data") + class Data(_message.Message): + __slots__ = ("id", "raw_message", "fail_code", "fail_codename", "erring_index", "erring_node") + ID_FIELD_NUMBER: _ClassVar[int] + RAW_MESSAGE_FIELD_NUMBER: _ClassVar[int] + FAIL_CODE_FIELD_NUMBER: _ClassVar[int] + FAIL_CODENAME_FIELD_NUMBER: _ClassVar[int] + ERRING_INDEX_FIELD_NUMBER: _ClassVar[int] + ERRING_NODE_FIELD_NUMBER: _ClassVar[int] + id: int + raw_message: str + fail_code: int + fail_codename: str + erring_index: int + erring_node: str + def __init__(self, id: _Optional[int] = ..., raw_message: _Optional[str] = ..., fail_code: _Optional[int] = ..., fail_codename: _Optional[str] = ..., erring_index: _Optional[int] = ..., erring_node: _Optional[str] = ...) -> None: ... + MESSAGE_FIELD_NUMBER: _ClassVar[int] + CODE_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + message: str + code: int + data: PayStatusResponse.PayStatus.Attempt.Failure.Data + def __init__(self, message: _Optional[str] = ..., code: _Optional[int] = ..., data: _Optional[_Union[PayStatusResponse.PayStatus.Attempt.Failure.Data, _Mapping]] = ...) -> None: ... + STRATEGY_FIELD_NUMBER: _ClassVar[int] + START_TIME_FIELD_NUMBER: _ClassVar[int] + AGE_IN_SECONDS_FIELD_NUMBER: _ClassVar[int] + END_TIME_FIELD_NUMBER: _ClassVar[int] + STATE_FIELD_NUMBER: _ClassVar[int] + SUCCESS_FIELD_NUMBER: _ClassVar[int] + FAILURE_FIELD_NUMBER: _ClassVar[int] + strategy: str + start_time: int + age_in_seconds: int + end_time: int + state: PayStatusResponse.PayStatus.Attempt.AttemptState + success: PayStatusResponse.PayStatus.Attempt.Success + failure: PayStatusResponse.PayStatus.Attempt.Failure + def __init__(self, strategy: _Optional[str] = ..., start_time: _Optional[int] = ..., age_in_seconds: _Optional[int] = ..., end_time: _Optional[int] = ..., state: _Optional[_Union[PayStatusResponse.PayStatus.Attempt.AttemptState, str]] = ..., success: _Optional[_Union[PayStatusResponse.PayStatus.Attempt.Success, _Mapping]] = ..., failure: _Optional[_Union[PayStatusResponse.PayStatus.Attempt.Failure, _Mapping]] = ...) -> None: ... + BOLT11_FIELD_NUMBER: _ClassVar[int] + AMOUNT_MSAT_FIELD_NUMBER: _ClassVar[int] + DESTINATION_FIELD_NUMBER: _ClassVar[int] + ATTEMPTS_FIELD_NUMBER: _ClassVar[int] + bolt11: str + amount_msat: int + destination: str + attempts: _containers.RepeatedCompositeFieldContainer[PayStatusResponse.PayStatus.Attempt] + def __init__(self, bolt11: _Optional[str] = ..., amount_msat: _Optional[int] = ..., destination: _Optional[str] = ..., attempts: _Optional[_Iterable[_Union[PayStatusResponse.PayStatus.Attempt, _Mapping]]] = ...) -> None: ... + STATUS_FIELD_NUMBER: _ClassVar[int] + status: _containers.RepeatedCompositeFieldContainer[PayStatusResponse.PayStatus] + def __init__(self, status: _Optional[_Iterable[_Union[PayStatusResponse.PayStatus, _Mapping]]] = ...) -> None: ... diff --git a/tools/plugins/mpay/protos/mpay_pb2_grpc.py b/tools/plugins/mpay/protos/mpay_pb2_grpc.py index 531daa44..6bf5aaf7 100644 --- a/tools/plugins/mpay/protos/mpay_pb2_grpc.py +++ b/tools/plugins/mpay/protos/mpay_pb2_grpc.py @@ -59,6 +59,11 @@ def __init__(self, channel): request_serializer=mpay__pb2.ResetPathMemoryRequest.SerializeToString, response_deserializer=mpay__pb2.ResetPathMemoryResponse.FromString, _registered_method=True) + self.PayStatus = channel.unary_unary( + '/mpay.Mpay/PayStatus', + request_serializer=mpay__pb2.PayStatusRequest.SerializeToString, + response_deserializer=mpay__pb2.PayStatusResponse.FromString, + _registered_method=True) class MpayServicer(object): @@ -94,6 +99,13 @@ def ResetPathMemory(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def PayStatus(self, request, context): + """Workaround to expose the paystatus command via gRPC, since CLN doesn't + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_MpayServicer_to_server(servicer, server): rpc_method_handlers = { @@ -122,6 +134,11 @@ def add_MpayServicer_to_server(servicer, server): request_deserializer=mpay__pb2.ResetPathMemoryRequest.FromString, response_serializer=mpay__pb2.ResetPathMemoryResponse.SerializeToString, ), + 'PayStatus': grpc.unary_unary_rpc_method_handler( + servicer.PayStatus, + request_deserializer=mpay__pb2.PayStatusRequest.FromString, + response_serializer=mpay__pb2.PayStatusResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'mpay.Mpay', rpc_method_handlers) @@ -267,3 +284,30 @@ def ResetPathMemory(request, timeout, metadata, _registered_method=True) + + @staticmethod + def PayStatus(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/mpay.Mpay/PayStatus', + mpay__pb2.PayStatusRequest.SerializeToString, + mpay__pb2.PayStatusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/tools/plugins/mpay/rpc/server.py b/tools/plugins/mpay/rpc/server.py index a272bebb..c55a7879 100644 --- a/tools/plugins/mpay/rpc/server.py +++ b/tools/plugins/mpay/rpc/server.py @@ -18,12 +18,18 @@ ListPaymentsResponse, PayRequest, PayResponse, + PayStatusRequest, + PayStatusResponse, ResetPathMemoryRequest, ResetPathMemoryResponse, ) from plugins.mpay.protos.mpay_pb2_grpc import MpayServicer, add_MpayServicer_to_server from plugins.mpay.rpc.grpc_server import GrpcServer -from plugins.mpay.rpc.transformers import payment_to_grpc, routes_to_grpc +from plugins.mpay.rpc.transformers import ( + pay_status_response_to_grpc, + payment_to_grpc, + routes_to_grpc, +) class MpayService(MpayServicer): @@ -133,6 +139,15 @@ def ResetPathMemory( # noqa: N802 hops=0, ) + def PayStatus( # noqa: N802 + self, + request: PayStatusRequest, + context: grpc.ServicerContext, # noqa: ARG002 + ) -> PayStatusResponse: + return pay_status_response_to_grpc( + self._mpay.pl.rpc.paystatus(request.bolt11 if request.bolt11 != "" else None) + ) + class Server(GrpcServer): _db: Database diff --git a/tools/plugins/mpay/rpc/transformers.py b/tools/plugins/mpay/rpc/transformers.py index bf566316..8bea8b00 100644 --- a/tools/plugins/mpay/rpc/transformers.py +++ b/tools/plugins/mpay/rpc/transformers.py @@ -1,6 +1,14 @@ +from typing import Any + from plugins.mpay.data.route_stats import RouteStats from plugins.mpay.db.models import Attempt, Hop, Payment -from plugins.mpay.protos.mpay_pb2 import GetRoutesResponse, ListPaymentsResponse +from plugins.mpay.protos.mpay_pb2 import GetRoutesResponse, ListPaymentsResponse, PayStatusResponse +from plugins.mpay.utils import parse_time + +PAY_STATUS_STATE_TO_GRPC = { + "pending": PayStatusResponse.PayStatus.Attempt.AttemptState.ATTEMPT_PENDING, + "completed": PayStatusResponse.PayStatus.Attempt.AttemptState.ATTEMPT_COMPLETED, +} def routes_to_grpc(routes: list[RouteStats]) -> GetRoutesResponse.Routes: @@ -45,3 +53,61 @@ def hop_to_grpc(hop: Hop) -> ListPaymentsResponse.Payment.Attempt.Hop: direction=hop.direction, ok=hop.ok, ) + + +def pay_status_response_to_grpc(res: dict[str, Any]) -> PayStatusResponse: + return PayStatusResponse( + status=[ + PayStatusResponse.PayStatus( + bolt11=status["bolt11"], + amount_msat=int(status["amount_msat"]), + destination=status["destination"], + attempts=[_pay_status_attempt_to_grpc(attempt) for attempt in status["attempts"]], + ) + for status in res["pay"] + ] + ) + + +def _pay_status_attempt_to_grpc( + res: dict[str, Any], +) -> PayStatusResponse.PayStatus.Attempt: + def transform_failure_data( + failure_data: dict[str, Any], + ) -> PayStatusResponse.PayStatus.Attempt.Failure.Data: + return PayStatusResponse.PayStatus.Attempt.Failure.Data( + id=failure_data["id"], + raw_message=failure_data["raw_message"], + fail_code=failure_data["failcode"], + fail_codename=failure_data["failcodename"], + erring_index=failure_data["erring_index"], + erring_node=failure_data["erring_node"], + ) + + def transform_failure( + failure: dict[str, Any], + ) -> PayStatusResponse.PayStatus.Attempt.Failure: + return PayStatusResponse.PayStatus.Attempt.Failure( + message=failure["message"], + code=failure["code"], + data=transform_failure_data(failure["data"]) if "data" in failure else None, + ) + + attempt = PayStatusResponse.PayStatus.Attempt( + strategy=res.get("strategy", ""), + start_time=parse_time(res["start_time"]), + age_in_seconds=res["age_in_seconds"], + state=PAY_STATUS_STATE_TO_GRPC[res["state"]], + success=PayStatusResponse.PayStatus.Attempt.Success( + id=res["success"]["id"], + payment_preimage=res["success"]["payment_preimage"], + ) + if "success" in res + else None, + failure=transform_failure(res["failure"]) if "failure" in res else None, + ) + + if "end_time" in res: + attempt.end_time = parse_time(res["end_time"]) + + return attempt diff --git a/tools/plugins/mpay/utils.py b/tools/plugins/mpay/utils.py index 946127e5..cff19356 100644 --- a/tools/plugins/mpay/utils.py +++ b/tools/plugins/mpay/utils.py @@ -7,6 +7,13 @@ def time_now() -> datetime: return datetime.now(tz=timezone.utc) +def parse_time(time: str) -> int: + try: + return int(datetime.strptime(time, "%Y-%m-%dT%H:%M:%S.%f%z").timestamp()) + except ValueError: + return 0 + + def format_error(e: BaseException) -> str: return str(e) if str(e) != "" else repr(e)