Skip to content

Commit

Permalink
Merge pull request #2227 from kaloudis/pending-htlcs
Browse files Browse the repository at this point in the history
Pending HTLCs view
  • Loading branch information
kaloudis authored Jun 10, 2024
2 parents 857f27e + 62c16a8 commit 70529d2
Show file tree
Hide file tree
Showing 12 changed files with 577 additions and 38 deletions.
5 changes: 5 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ import Contacts from './views/Settings/Contacts';
import AddContact from './views/Settings/AddContact';
import ContactDetails from './views/ContactDetails';
import CurrencyConverter from './views/Settings/CurrencyConverter';
import PendingHTLCs from './views/PendingHTLCs';

// POS
import Order from './views/Order';
Expand Down Expand Up @@ -852,6 +853,10 @@ export default class App extends React.PureComponent {
name="LSPS1Order"
component={Orders}
/>
<Stack.Screen
name="PendingHTLCs"
component={PendingHTLCs}
/>
</Stack.Navigator>
</NavigationContainer>
</>
Expand Down
20 changes: 20 additions & 0 deletions assets/images/SVG/Hourglass.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions assets/images/SVG/Stopwatch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 14 additions & 1 deletion components/Channels/ChannelItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { themeColor } from './../../utils/ThemeUtils';
import Stores from '../../stores/Stores';

import ClockIcon from '../../assets/images/SVG/Clock.svg';
import HourglassIcon from '../../assets/images/SVG/Hourglass.svg';
import { localeString } from './../../utils/LocaleUtils';

export function ChannelItem({
Expand All @@ -22,6 +23,7 @@ export function ChannelItem({
outbound,
largestTotal,
status,
pendingHTLCs,
pendingTimelock,
noBorder,
hideLabels,
Expand All @@ -32,7 +34,8 @@ export function ChannelItem({
outbound: number;
largestTotal?: number;
status?: Status;
pendingTimelock?: String;
pendingHTLCs?: boolean;
pendingTimelock?: string;
noBorder?: boolean;
hideLabels?: boolean;
selected?: boolean;
Expand Down Expand Up @@ -70,6 +73,16 @@ export function ChannelItem({
</Body>
</View>
)}
{pendingHTLCs ? (
<View style={{ flexDirection: 'row', marginRight: 5 }}>
<HourglassIcon
fill={themeColor('highlight')}
width={17}
height={17}
style={{ marginRight: 5 }}
/>
</View>
) : null}
{pendingTimelock ? (
<View style={{ flexDirection: 'row', marginRight: 5 }}>
<ClockIcon
Expand Down
5 changes: 3 additions & 2 deletions components/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ interface SwitchProps {
value: boolean;
onValueChange?: any;
disabled?: boolean;
trackEnabledColor?: string;
}

function Switch(props: SwitchProps) {
const { value, onValueChange, disabled } = props;
const { value, onValueChange, disabled, trackEnabledColor } = props;
return (
<RNSwitch
value={value}
onValueChange={onValueChange}
trackColor={{
false: themeColor('disabled'),
true: themeColor('highlight')
true: trackEnabledColor || themeColor('highlight')
}}
thumbColor={
value ? themeColor('highlight') : themeColor('disabled')
Expand Down
28 changes: 27 additions & 1 deletion components/WalletHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import Add from '../assets/images/SVG/Add.svg';
import Alert from '../assets/images/SVG/Alert.svg';
import ClipboardSVG from '../assets/images/SVG/Clipboard.svg';
import Gear from '../assets/images/SVG/Gear.svg';
import Hourglass from '../assets/images/SVG/Hourglass.svg';
import POS from '../assets/images/SVG/POS.svg';
import Search from '../assets/images/SVG/Search.svg';
import Temple from '../assets/images/SVG/Temple.svg';
Expand Down Expand Up @@ -156,6 +157,23 @@ const ClipboardBadge = ({
</TouchableOpacity>
);

const PendingHtlcBadge = ({
navigation
}: {
navigation: StackNavigationProp<any, any>;
clipboard: string;
}) => (
<TouchableOpacity
onPress={() =>
navigation.navigate('PendingHTLCs', {
animation: 'slide_from_bottom'
})
}
>
<Hourglass fill={themeColor('highlight')} width="35" height="35" />
</TouchableOpacity>
);

const POSBadge = ({
setPosStatus,
getOrders
Expand Down Expand Up @@ -244,7 +262,7 @@ export default class WalletHeader extends React.Component<
PosStore,
SyncStore
} = this.props;
const { filteredPendingChannels } = ChannelsStore!;
const { filteredPendingChannels, pendingHTLCs } = ChannelsStore!;
const { settings, posStatus, setPosStatus, implementation } =
SettingsStore!;
const { paid, redeemingAll } = LightningAddressStore!;
Expand Down Expand Up @@ -583,6 +601,14 @@ export default class WalletHeader extends React.Component<
/>
</View>
)}
{pendingHTLCs.length > 0 && (
<View style={{ marginRight: 15 }}>
<PendingHtlcBadge
navigation={navigation}
clipboard={clipboard}
/>
</View>
)}
{isSyncing && (
<View
style={{
Expand Down
9 changes: 8 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1192,5 +1192,12 @@
"components.AlertModal.resetEGS": "Reset express graph sync data",
"components.AlertModal.neutrinoPeers": "Problematic neutrino peers",
"components.AlertModal.neutrinoExplainer": "Neutrino peers with over 200ms ping time can cause performance issues in the app.",
"components.AlertModal.reviewPeers": "Review neutrino peers list"
"components.AlertModal.reviewPeers": "Review neutrino peers list",
"views.PendingHTLCs.title": "Pending HTLCs",
"views.PendingHTLCs.noPendingHTLCs": "No pending HTLCs",
"views.PendingHTLCs.incoming": "Incoming",
"views.PendingHTLCs.outgoing": "Outgoing",
"views.PendingHTLCs.expirationHeight": "Expiration height",
"views.PendingHTLCs.recommendationIOS": "It's recommended to leave ZEUS running while there are pending HTLCs to prevent force closes.",
"views.PendingHTLCs.recommendationAndroid": "It's recommended to enable Persistent LND or leave ZEUS running while there are pending HTLCs to prevent force closes."
}
33 changes: 31 additions & 2 deletions stores/ChannelsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ interface ChannelInfoIndex {
[key: string]: ChannelInfo;
}

interface PendingHTLC {
incoming: boolean;
amount: number;
hash_lock: string;
expiration_height: number;
htlc_index: number;
forwarding_channel: number;
forwarding_htlc_index: number;
}

export enum ChannelsType {
Open = 0,
Pending = 1,
Expand Down Expand Up @@ -76,6 +86,8 @@ export default class ChannelsStore {
// external account funding
@observable public funded_psbt: string = '';
@observable public pending_chan_ids: Array<string>;
// pending HTLCs
@observable public pendingHTLCs: Array<PendingHTLC>;

settingsStore: SettingsStore;

Expand All @@ -97,7 +109,8 @@ export default class ChannelsStore {
async () => {
if (this.channels) {
this.enrichedChannels = await this.enrichChannels(
this.channels
this.channels,
true
);
this.filterChannels();
}
Expand Down Expand Up @@ -173,6 +186,7 @@ export default class ChannelsStore {
this.totalInbound = 0;
this.totalOffline = 0;
this.channelsType = ChannelsType.Open;
this.pendingHTLCs = [];
};

@action
Expand Down Expand Up @@ -286,7 +300,10 @@ export default class ChannelsStore {
};

@action
enrichChannels = async (channels: Array<Channel>) => {
enrichChannels = async (
channels: Array<Channel>,
setPendingHtlcs?: boolean
) => {
if (channels.length === 0) return;

const channelsWithMissingAliases = channels?.filter(
Expand Down Expand Up @@ -323,6 +340,8 @@ export default class ChannelsStore {
this.aliasesById[channel.channelId!] = nodeInfo.alias;
}

if (setPendingHtlcs) this.pendingHTLCs = [];

for (const channel of channels) {
if (channel.alias == null) {
channel.alias = this.nodes[channel.remotePubkey]?.alias;
Expand All @@ -332,8 +351,18 @@ export default class ChannelsStore {
channel.remotePubkey ||
channel.channelId ||
localeString('models.Channel.unknownId');

if (BackendUtils.isLNDBased() && setPendingHtlcs) {
channel.pending_htlcs?.forEach((htlc: any) => {
htlc.channelDisplayName = channel.displayName;
});

this.pendingHTLCs.push(...channel.pending_htlcs);
}
}

console.log('Pending HTLCs', this.pendingHTLCs);

this.loading = false;
return channels;
};
Expand Down
49 changes: 45 additions & 4 deletions views/Channels/Channel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
View
} from 'react-native';

import { Divider } from 'react-native-elements';
import { Divider, Icon, ListItem } from 'react-native-elements';
import { inject, observer } from 'mobx-react';
import { Route } from '@react-navigation/native';
import { StackNavigationProp } from '@react-navigation/stack';
Expand Down Expand Up @@ -40,6 +40,7 @@ import SettingsStore from '../../stores/SettingsStore';
import NodeInfoStore from '../../stores/NodeInfoStore';

import Edit from '../../assets/images/SVG/Edit.svg';
import HourglassIcon from '../../assets/images/SVG/Hourglass.svg';

interface ChannelProps {
navigation: StackNavigationProp<any, any>;
Expand Down Expand Up @@ -205,7 +206,8 @@ export default class ChannelView extends React.Component<
pendingOpen,
closing,
zero_conf,
getCommitmentType
getCommitmentType,
pending_htlcs
} = channel;

const privateChannel = channel.private;
Expand Down Expand Up @@ -434,6 +436,45 @@ export default class ChannelView extends React.Component<
}
/>
)}
{!!pending_htlcs && pending_htlcs.length > 0 && (
<ListItem
containerStyle={{
backgroundColor: 'transparent',
marginLeft: -13,
marginRight: -20
}}
onPress={() =>
navigation.navigate('PendingHTLCs', {
pending_htlcs
})
}
>
<ListItem.Content>
<ListItem.Title
style={{
color: themeColor('highlight'),
fontFamily: 'PPNeueMontreal-Book'
}}
>
<View style={{ flexDirection: 'row' }}>
<HourglassIcon
fill={themeColor('highlight')}
width={17}
height={17}
style={{ marginRight: 5 }}
/>
</View>
{`${localeString(
'views.PendingHTLCs.title'
)} (${pending_htlcs.length})`}
</ListItem.Title>
</ListItem.Content>
<Icon
name="keyboard-arrow-right"
color={themeColor('secondaryText')}
/>
</ListItem>
)}
<KeyValue
keyValue={localeString('views.Channel.channelBalance')}
/>
Expand Down Expand Up @@ -712,8 +753,8 @@ const styles = StyleSheet.create({
fontFamily: 'PPNeueMontreal-Book'
},
content: {
paddingLeft: 20,
paddingRight: 20
marginLeft: 20,
marginRight: 20
},
center: {
alignItems: 'center'
Expand Down
2 changes: 2 additions & 0 deletions views/Channels/ChannelsPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export default class ChannelsPane extends React.PureComponent<ChannelsProps> {
<ChannelItem
title={item.displayName}
status={getStatus()}
pendingHTLCs={item?.pending_htlcs?.length > 0}
inbound={item.remoteBalance}
outbound={item.localBalance}
largestTotal={largestChannelSats}
Expand All @@ -139,6 +140,7 @@ export default class ChannelsPane extends React.PureComponent<ChannelsProps> {
inbound={item.remoteBalance}
outbound={item.localBalance}
status={getStatus()}
pendingHTLCs={item?.pending_htlcs?.length > 0}
pendingTimelock={
item.forceClose
? forceCloseTimeLabel(item.blocks_til_maturity)
Expand Down
Loading

0 comments on commit 70529d2

Please sign in to comment.