Advanced Payment Options

Advanced Payment Options
This commit is contained in:
Shahana Farooqui 2020-01-02 20:35:01 -05:00
parent 05bdd61091
commit 98f4d5e4e9
14 changed files with 44 additions and 36 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -12,5 +12,5 @@
<link rel="stylesheet" href="styles.84a3ca15f237e7d708f3.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.dee2c800c6a182585bb1.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.cb4e9f676564b92e59d1.js" defer></script></body>
<script src="runtime.b6bb1c19ae62dbcce211.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.fc2cc2a8b081589ad3ae.js" defer></script></body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"3de0a26964d460363d96",6:"f324f927e59831e67524",7:"1962b0f58ca9e13bdc03"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

View file

@ -1 +0,0 @@
!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],p=0,s=[];p<a.length;p++)i=a[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++)0!==o[t[a]]&&(n=!1);n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={0:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+""+({}[e]||e)+"."+{1:"3de0a26964d460363d96",6:"f324f927e59831e67524",7:"bc81c5d83e6736182735"}[e]+".js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,(function(r){return e[r]}).bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="",i.oe=function(e){throw console.error(e),e};var a=window.webpackJsonp=window.webpackJsonp||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var f=c;t()}([]);

View file

@ -87,7 +87,6 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
resetData() {
this.selectedPeer = '';
this.fundingAmount = 0;
this.showAdvanced = false;
this.spendUnconfirmed = false;
this.isPrivate = false;
this.selTransType = '0';

View file

@ -14,7 +14,7 @@ import { SessionService } from '../../shared/services/session.service';
import { GetInfo, GetInfoChain, Fees, Balance, NetworkInfo, Payment, GraphNode, Transaction, SwitchReq, ListInvoices, PendingChannelsGroup } from '../../shared/models/lndModels';
import { InvoiceInformationComponent } from '../../shared/components/data-modal/invoice-information/invoice-information.component';
import { OpenChannelComponent } from '../../shared/components/data-modal/open-channel/open-channel.component';
import { CurrencyUnitEnum, AlertTypeEnum, FEE_LIMIT_TYPES } from '../../shared/services/consts-enums-functions';
import { CurrencyUnitEnum, AlertTypeEnum, FEE_LIMIT_TYPES, DataTypeEnum } from '../../shared/services/consts-enums-functions';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
@ -666,20 +666,29 @@ export class LNDEffects implements OnDestroy {
if (sendRes.payment_error) {
this.logger.error('Error: ' + sendRes.payment_error);
const myErr = {status: sendRes.payment_error.status, error: sendRes.payment_error.error.message};
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions/' + action.payload[0], myErr);
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions/' + action.payload.paymentReq, myErr);
return of({type: RTLActions.VOID});
} else {
const confirmationMsg = { 'Destination': action.payload[1].destination, 'Timestamp': action.payload[1].timestamp_str, 'Expiry': action.payload[1].expiry };
confirmationMsg['Amount (' + ((undefined === store.nodeData.smaller_currency_unit) ?
CurrencyUnitEnum.SATS : store.nodeData.smaller_currency_unit) + ')'] = action.payload[1].num_satoshis;
const msg = [];
msg['Total Fee (' + ((undefined === store.nodeData.smaller_currency_unit) ? CurrencyUnitEnum.SATS : store.nodeData.smaller_currency_unit) + ')'] =
(sendRes.payment_route.total_fees_msat / 1000);
Object.assign(msg, confirmationMsg);
let msg = [];
if(sendRes.payment_route && sendRes.payment_route.total_fees_msat) {
msg = [
[{key: 'destination', value: action.payload.paymentDecoded.destination, title: 'Destination', width: 100, type: DataTypeEnum.STRING}],
[{key: 'num_satoshis', value: action.payload.paymentDecoded.num_satoshis, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.STRING},
{key: 'total_fees_msat', value: (sendRes.payment_route.total_fees_msat / 1000), title: 'Total Fee (mSats)', width: 50, type: DataTypeEnum.STRING}],
[{key: 'timestamp_str', value: action.payload.paymentDecoded.timestamp_str, title: 'Timestamp', width: 50, type: DataTypeEnum.DATE_TIME},
{key: 'expiry', value: action.payload.paymentDecoded.expiry, title: 'Expiry', width: 50, type: DataTypeEnum.STRING}]
];
} else {
msg = [
[{key: 'destination', value: action.payload.paymentDecoded.destination, title: 'Destination', width: 100, type: DataTypeEnum.STRING}],
[{key: 'num_satoshis', value: action.payload.paymentDecoded.num_satoshis, title: 'Amount (Sats)', width: 32, type: DataTypeEnum.STRING},
{key: 'timestamp_str', value: action.payload.paymentDecoded.timestamp_str, title: 'Timestamp', width: 32, type: DataTypeEnum.DATE_TIME},
{key: 'expiry', value: action.payload.paymentDecoded.expiry, title: 'Expiry', width: 32, type: DataTypeEnum.STRING}]
];
}
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Payment Sent',
titleMessage: 'Payment Sent Successfully!',
message: msg
}}));
this.store.dispatch(new RTLActions.FetchAllChannels());
@ -692,7 +701,7 @@ export class LNDEffects implements OnDestroy {
}
}),
catchError((err: any) => {
const myErr = {status: err.status, error: typeof(err.error.error) === 'object' ? err.error.error : {error: err.error.error}};
const myErr = {status: err.status, error: err.error && err.error.error && typeof(err.error.error) === 'object' ? err.error.error : {error: err.error && err.error.error ? err.error.error : 'Unknown Error'}};
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions', myErr);
return of({type: RTLActions.VOID});
})
@ -1135,7 +1144,7 @@ export class LNDEffects implements OnDestroy {
} else {
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({
width: '55%', data: {
data: {
type: alertType,
alertTitle: alertTitle,
message: { code: err.status, message: err.error.error, URL: errURL },

View file

@ -11,21 +11,20 @@
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
</button>
</div>
<div *ngIf="showDetails && showAdvanced" fxFlex="100" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select tabindex="5" [(value)]="selFeeLimitType">
<div *ngIf="showDetails && showAdvanced" fxFlex="100" fxFlex.gt-sm="75" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<mat-select tabindex="5" [(value)]="selFeeLimitType" Placeholder="Fee Limits">
<mat-option *ngFor="let feeLimitType of feeLimitTypes" [value]="feeLimitType">
{{feeLimitType.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="33">
<input matInput [(ngModel)]="feeLimit" placeholder="Fee Limit" type="number" name="feeLimit" step="1" min="0" required tabindex="6" #feeLmt="ngModel" [disabled]="selFeeLimitType === feeLimitTypes[0]">
<mat-error *ngIf="selFeeLimitType !== feeLimitTypes[0] && !feeLimit">Fees Limit is required.</mat-error>
<mat-form-field fxFlex="26">
<input matInput [(ngModel)]="feeLimit" [placeholder]="selFeeLimitType.placeholder" type="number" name="feeLimit" step="1" min="0" required tabindex="6" #feeLmt="ngModel" [disabled]="selFeeLimitType === feeLimitTypes[0]">
<mat-error *ngIf="selFeeLimitType !== feeLimitTypes[0] && !feeLimit">{{selFeeLimitType.placeholder}} is required.</mat-error>
</mat-form-field>
<mat-form-field fxFlex="33" fxLayoutAlign="start end">
<mat-select tabindex="7" [(value)]="selActiveChannel">
<mat-option [value]="null"></mat-option>
<mat-form-field fxFlex="40" fxLayoutAlign="start end">
<mat-select tabindex="7" [(value)]="selActiveChannel" placeholder="First Outgoing Channel">
<mat-option *ngFor="let activeChannel of activeChannels" [value]="activeChannel">
{{activeChannel.remote_alias || activeChannel.chan_id}}
</mat-option>

View file

@ -155,7 +155,7 @@ export class LightningPaymentsComponent implements OnInit, OnDestroy {
if (confirmRes) {
this.paymentDecoded.num_satoshis = confirmRes[0].inputValue;
this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...'));
this.store.dispatch(new RTLActions.SendPayment({paymentDecoded: this.paymentDecoded, outgoingChannel: this.selActiveChannel, feeLimitType: this.selFeeLimitType, feeLimit: this.feeLimit, zeroAmtInvoice: true}));
this.store.dispatch(new RTLActions.SendPayment({paymentReq: this.paymentRequest, paymentDecoded: this.paymentDecoded, zeroAmtInvoice: true, outgoingChannel: this.selActiveChannel, feeLimitType: this.selFeeLimitType, feeLimit: this.feeLimit}));
this.resetData();
}
});
@ -181,7 +181,7 @@ export class LightningPaymentsComponent implements OnInit, OnDestroy {
.subscribe(confirmRes => {
if (confirmRes) {
this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...'));
this.store.dispatch(new RTLActions.SendPayment({paymentReq: this.paymentRequest, outgoingChannel: this.selActiveChannel, feeLimitType: this.selFeeLimitType, feeLimit: this.feeLimit, zeroAmtInvoice: false}));
this.store.dispatch(new RTLActions.SendPayment({paymentReq: this.paymentRequest, paymentDecoded: this.paymentDecoded, zeroAmtInvoice: false, outgoingChannel: this.selActiveChannel, feeLimitType: this.selFeeLimitType, feeLimit: this.feeLimit}));
this.resetData();
}
});
@ -214,14 +214,15 @@ export class LightningPaymentsComponent implements OnInit, OnDestroy {
this.selActiveChannel = null;
this.feeLimit = null;
this.selFeeLimitType = FEE_LIMIT_TYPES[0];
this.feeLimitTypes = FEE_LIMIT_TYPES;
}
}
resetData() {
this.paymentDecoded = {};
this.paymentRequest = '';
this.showAdvanced = false;
this.selActiveChannel = null;
this.feeLimit = null;
this.selFeeLimitType = FEE_LIMIT_TYPES[0];
this.form.reset();
}

View file

@ -2,7 +2,7 @@
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" (ngSubmit)="queryRoutesForm.form.valid && onQueryRoutes()" #queryRoutesForm="ngForm">
<div fxFlex="100" class="alert alert-warn">
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
<span>The actual fee can be different from the estimate shown on this page.</span>
<span>The actual routing fee on a payment can be different from the fee shown on query routes.</span>
</div>
<mat-form-field fxFlex="69" fxLayoutAlign="start end">
<input matInput placeholder="Destination Pubkey" name="destinationPubkey" [(ngModel)]="destinationPubkey" tabindex="1" required #destPubkey="ngModel">

View file

@ -36,10 +36,10 @@ export const TRANS_TYPES = [
];
export const FEE_LIMIT_TYPES = [
{id: 'none', name: 'No Limit'},
{id: 'fixed', name: 'Fixed in Sats'},
{id: 'fixed_msat', name: 'Fixed in mSats'},
{id: 'percent', name: 'Percentage of Payment Amount'}
{id: 'none', name: 'No Fee Limit', placeholder: 'No Limit'},
{id: 'fixed', name: 'Fixed (Sats)', placeholder: 'Fixed Limit in Sats'},
// {id: 'fixed_msat', name: 'Fixed in mSats'},
{id: 'percent', name: 'Percentage of Payment Amount', placeholder: 'Percentage Limit'}
];
export const NODE_SETTINGS = {

View file

@ -480,7 +480,7 @@ export class SetDecodedPayment implements Action {
export class SendPayment implements Action {
readonly type = SEND_PAYMENT;
constructor(public payload: { paymentReq?: string, paymentDecoded?: PayRequest, outgoingChannel?: Channel, feeLimitType?: {id: string, name: string}, feeLimit?: number, zeroAmtInvoice: boolean }) {}
constructor(public payload: { paymentReq: string, paymentDecoded: PayRequest, zeroAmtInvoice: boolean, outgoingChannel?: Channel, feeLimitType?: {id: string, name: string}, feeLimit?: number }) {}
}
export class FetchGraphNode implements Action {