You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RTL/src/app/store/rtl.reducers.ts

322 lines
10 KiB
TypeScript

import { ActionReducerMap } from '@ngrx/store';
import { ErrorPayload } from '../shared/models/errorPayload';
import { RTLConfiguration, LightningNode } from '../shared/models/RTLconfig';
import {
GetInfoRoot, GetInfo, GetInfoChain, Peer, AddressType, Fees, NetworkInfo, Balance, Channel, Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes, QueryRoutes
} from '../shared/models/lndModels';
import * as fromCL from '../clightning/store/cl.reducers';
import * as RTLActions from './rtl.actions';
export interface LNDState {
information: GetInfo;
peers: Peer[];
fees: Fees;
networkInfo: NetworkInfo;
channelBalance: Balance;
blockchainBalance: Balance;
allChannels: Channel[];
closedChannels: ClosedChannel[];
pendingChannels: PendingChannels;
numberOfActiveChannels: number;
numberOfInactiveChannels: number;
numberOfPendingChannels: number;
totalLocalBalance: number;
totalRemoteBalance: number;
totalInvoices: number;
transactions: Transaction[];
payments: Payment[];
invoices: ListInvoices;
forwardingHistory: SwitchRes;
addressTypes: AddressType[];
}
export interface RootState {
effectErrors: ErrorPayload[];
selNode: LightningNode;
appConfig: RTLConfiguration;
nodeData: GetInfoRoot
}
const initLNDState: LNDState = {
information: {},
peers: [],
fees: {},
networkInfo: {},
channelBalance: {balance: '', btc_balance: ''},
blockchainBalance: { total_balance: '', btc_total_balance: ''},
allChannels: [],
closedChannels: [],
pendingChannels: {},
numberOfActiveChannels: 0,
numberOfInactiveChannels: 0,
numberOfPendingChannels: -1,
totalLocalBalance: -1,
totalRemoteBalance: -1,
totalInvoices: -1,
transactions: [],
payments: [],
invoices: {invoices: []},
forwardingHistory: {},
addressTypes: [
{ addressId: '0', addressTp: 'p2wkh', addressDetails: 'Pay to witness key hash'},
{ addressId: '1', addressTp: 'np2wkh', addressDetails: 'Pay to nested witness key hash (default)'}
]
}
const initNodeSettings = { flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false };
const initNodeAuthentication = { nodeAuthType: 'CUSTOM', lndConfigPath: '', bitcoindConfigPath: '' };
const initRootState: RootState = {
effectErrors: [],
selNode: {settings: initNodeSettings, authentication: initNodeAuthentication},
appConfig: {
selectedNodeIndex: -1,
sso: { rtlSSO: 0, logoutRedirectLink: '/login' },
nodes: [{ settings: initNodeSettings, authentication: initNodeAuthentication}]
},
nodeData: { identity_pubkey: 'abc', alias: 'xyz', testnet: true, chains: [{chain: "bitcoin", network: "testnet"}], version: 'v0', currency_unit: 'BTC', smaller_currency_unit: 'SATS', numberOfPendingChannels: -1 }
};
export function RootReducer(state = initRootState, action: RTLActions.RTLActions) {
switch (action.type) {
case RTLActions.CLEAR_EFFECT_ERROR:
const clearedEffectErrors = [...state.effectErrors];
const removeEffectIdx = state.effectErrors.findIndex(err => {
return err.action === action.payload;
});
if (removeEffectIdx > -1) {
clearedEffectErrors.splice(removeEffectIdx, 1);
}
return {
...state,
effectErrors: clearedEffectErrors
};
case RTLActions.EFFECT_ERROR:
return {
...state,
effectErrors: [...state.effectErrors, action.payload]
};
case RTLActions.RESET_STORE:
return {
...initRootState,
appConfig: state.appConfig,
selNode: action.payload,
// cl: initCLState
};
case RTLActions.SET_SELECTED_NODE:
return {
...state,
selNode: action.payload
};
case RTLActions.SET_RTL_CONFIG:
return {
...state,
selNode: action.payload.nodes.find(node => +node.index === action.payload.selectedNodeIndex),
appConfig: action.payload
};
default:
return state;
}
}
export function LNDReducer(state = initLNDState, action: RTLActions.RTLActions) {
switch (action.type) {
case RTLActions.SET_INFO:
if (undefined !== action.payload.chains) {
if (typeof action.payload.chains[0] === 'string') {
action.payload.smaller_currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats';
action.payload.currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC';
} else if (typeof action.payload.chains[0] === 'object' && action.payload.chains[0].hasOwnProperty('chain')) {
const getInfoChain = <GetInfoChain>action.payload.chains[0];
action.payload.smaller_currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats';
action.payload.currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC';
}
action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0];
} else {
action.payload.smaller_currency_unit = 'Sats';
action.payload.currency_unit = 'BTC';
action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0];
}
return {
...state,
information: action.payload
};
case RTLActions.SET_PEERS:
return {
...state,
peers: action.payload
};
case RTLActions.ADD_PEER:
return {
...state,
peers: [...state.peers, action.payload]
};
case RTLActions.REMOVE_PEER:
const modifiedPeers = [...state.peers];
const removePeerIdx = state.peers.findIndex(peer => {
return peer.pub_key === action.payload.pubkey;
});
if (removePeerIdx > -1) {
modifiedPeers.splice(removePeerIdx, 1);
}
return {
...state,
peers: modifiedPeers
};
case RTLActions.ADD_INVOICE:
const newInvoices = state.invoices;
newInvoices.invoices.unshift(action.payload);
return {
...state,
invoices: newInvoices
};
case RTLActions.SET_FEES:
return {
...state,
fees: action.payload
};
case RTLActions.SET_CLOSED_CHANNELS:
return {
...state,
closedChannels: action.payload,
};
case RTLActions.SET_PENDING_CHANNELS:
let pendingChannels = -1;
if (action.payload) {
pendingChannels = 0;
if (action.payload.pending_closing_channels) {
pendingChannels = pendingChannels + action.payload.pending_closing_channels.length;
}
if (action.payload.pending_force_closing_channels) {
pendingChannels = pendingChannels + action.payload.pending_force_closing_channels.length;
}
if (action.payload.pending_open_channels) {
pendingChannels = pendingChannels + action.payload.pending_open_channels.length;
}
if (action.payload.waiting_close_channels) {
pendingChannels = pendingChannels + action.payload.waiting_close_channels.length;
}
}
return {
...state,
pendingChannels: action.payload,
numberOfPendingChannels: pendingChannels,
};
case RTLActions.SET_CHANNELS:
let localBal = 0, remoteBal = 0, activeChannels = 0, inactiveChannels = 0;
if (action.payload) {
action.payload.filter(channel => {
if (undefined !== channel.local_balance) {
localBal = +localBal + +channel.local_balance;
}
if (undefined !== channel.remote_balance) {
remoteBal = +remoteBal + +channel.remote_balance;
}
if (channel.active === true) {
activeChannels = activeChannels + 1;
} else {
inactiveChannels = inactiveChannels + 1;
}
});
}
return {
...state,
allChannels: action.payload,
numberOfActiveChannels: activeChannels,
numberOfInactiveChannels: inactiveChannels,
totalLocalBalance: localBal,
totalRemoteBalance: remoteBal
};
case RTLActions.REMOVE_CHANNEL:
const modifiedChannels = [...state.allChannels];
const removeChannelIdx = state.allChannels.findIndex(channel => {
return channel.channel_point === action.payload.channelPoint;
});
if (removeChannelIdx > -1) {
modifiedChannels.splice(removeChannelIdx, 1);
}
return {
...state,
allChannels: modifiedChannels
};
case RTLActions.SET_BALANCE:
if (action.payload.target === 'channels') {
return {
...state,
channelBalance: action.payload.balance
};
} else {
return {
...state,
blockchainBalance: action.payload.balance
};
}
case RTLActions.SET_NETWORK:
return {
...state,
networkInfo: action.payload
};
case RTLActions.SET_INVOICES:
return {
...state,
invoices: action.payload
};
case RTLActions.SET_TOTAL_INVOICES:
return {
...state,
totalInvoices: action.payload
};
case RTLActions.SET_TRANSACTIONS:
return {
...state,
transactions: action.payload
};
case RTLActions.SET_PAYMENTS:
return {
...state,
payments: action.payload
};
case RTLActions.SET_FORWARDING_HISTORY:
if (action.payload.forwarding_events) {
const storedChannels = [...state.allChannels];
action.payload.forwarding_events.forEach(event => {
if (storedChannels) {
for (let idx = 0; idx < storedChannels.length; idx++) {
if (storedChannels[idx].chan_id.toString() === event.chan_id_in) {
event.alias_in = storedChannels[idx].remote_alias;
if (event.alias_out) { return; }
}
if (storedChannels[idx].chan_id.toString() === event.chan_id_out) {
event.alias_out = storedChannels[idx].remote_alias;
if (event.alias_in) { return; }
}
}
}
});
} else {
action.payload = {};
}
return {
...state,
forwardingHistory: action.payload
};
default:
return state;
}
}
export interface RTLState {
root: RootState;
lnd: LNDState;
cl: fromCL.CLState;
}
export const RTLReducer: ActionReducerMap<RTLState> = {
root: RootReducer,
lnd: LNDReducer,
cl: fromCL.CLReducer
};