Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lightning Node Connect: LSP support #1629

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion backends/LightningNodeConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,16 @@ export default class LightningNodeConnect {
await this.lnc.lnd.lightning
.lookupInvoice({ r_hash: Base64Utils.hexToBase64(data.r_hash) })
.then((data: lnrpc.Invoice) => snakeize(data));
channelAcceptor = (data: lnrpc.channelAcceptRequest) =>
this.lnc.lnd.lightning.channelAcceptor(data);
channelAcceptorAnswer = (data: lnrpc.channelAcceptorResponse) => {
console.log('^^^backend', data);
return this.lnc.call('lnrpc.Lightning.ChannelAcceptor', {
pending_chan_id: data.pending_chan_id,
zero_conf: data.zero_conf,
accept: data.accept
});
};
subscribeInvoice = (r_hash: string) =>
this.lnc.lnd.invoices.subscribeSingleInvoice({ r_hash });
subscribeInvoices = () => this.lnc.lnd.lightning.subscribeInvoices();
Expand Down Expand Up @@ -388,7 +398,7 @@ export default class LightningNodeConnect {
supportsAddressTypeSelection = () => true;
supportsTaproot = () => this.supports('v0.15.0');
supportsBumpFee = () => true;
supportsLSPs = () => false;
supportsLSPs = () => true;
supportsNetworkInfo = () => false;
supportsSimpleTaprootChannels = () => this.supports('v0.17.0');
supportsCustomPreimages = () => true;
Expand Down
6 changes: 3 additions & 3 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ PODS:
- RNVectorIcons (7.1.0):
- React
- SocketRocket (0.6.1)
- SwiftProtobuf (1.23.0)
- SwiftProtobuf (1.25.2)
- TcpSockets (4.0.0):
- React
- Yoga (1.14.0)
Expand Down Expand Up @@ -830,10 +830,10 @@ SPEC CHECKSUMS:
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
RNVectorIcons: bc69e6a278b14842063605de32bec61f0b251a59
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
SwiftProtobuf: b70d65f419fbfe61a2d58003456ca5da58e337d6
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
TcpSockets: 4ef55305239923b343ed0a378b1fac188b1373b0
Yoga: 86fed2e4d425ee4c6eab3813ba1791101ee153c6

PODFILE CHECKSUM: 643f83a7955aa123651bac4a54204e22598914df

COCOAPODS: 1.12.1
COCOAPODS: 1.15.2
2 changes: 2 additions & 0 deletions ios/zeus.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2134,6 +2134,7 @@
"-ld_classic",
"-Wl",
"-ld_classic",
"-Wl -ld_classic ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
Expand Down Expand Up @@ -2211,6 +2212,7 @@
"-ld_classic",
"-Wl",
"-ld_classic",
"-Wl -ld_classic ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
Expand Down
7 changes: 7 additions & 0 deletions lndmobile/LndMobileInjection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
listPayments,
listInvoices,
subscribeChannelGraph,
channelAcceptorAnswer,
sendKeysendPaymentV2
} from './index';
import {
Expand Down Expand Up @@ -196,6 +197,11 @@ export interface ILndMobileInjections {
) => Promise<lnrpc.QueryRoutesResponse>;
listPayments: () => Promise<lnrpc.ListPaymentsResponse>;
subscribeChannelGraph: () => Promise<string>;
channelAcceptorAnswer: (
pending_chan_id: Uint8Array,
zero_conf: boolean,
accept: boolean
) => void;
sendKeysendPaymentV2: ({
amt,
max_shard_size_msat,
Expand Down Expand Up @@ -382,6 +388,7 @@ export default {
listPayments,
listInvoices,
subscribeChannelGraph,
channelAcceptorAnswer,
sendKeysendPaymentV2
},
channel: {
Expand Down
22 changes: 22 additions & 0 deletions lndmobile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,28 @@ export const subscribeChannelGraph = async (): Promise<string> => {
return response;
};

/**
* @throws
*/
export const channelAcceptorAnswer = async (
pending_chan_id: Uint8Array,
zero_conf: boolean,
accept: boolean
) => {
await sendStreamCommand<
lnrpc.IChannelAcceptResponse,
lnrpc.ChannelAcceptResponse
>({
request: lnrpc.ChannelAcceptResponse,
method: 'ChannelAcceptor',
options: {
pending_chan_id,
zero_conf,
accept
}
});
};

export type IReadLndLogResponse = string[];
/**
* @throws
Expand Down
73 changes: 60 additions & 13 deletions stores/LSPStore.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { action, observable } from 'mobx';
import ReactNativeBlobUtil from 'react-native-blob-util';
import { NativeEventEmitter, NativeModules } from 'react-native';

import SettingsStore from './SettingsStore';
import ChannelsStore from './ChannelsStore';
Expand All @@ -8,6 +9,7 @@ import stores from './Stores';
import lndMobile from '../lndmobile/LndMobileInjection';
const { channel } = lndMobile;

import BackendUtils from '../utils/BackendUtils';
import Base64Utils from '../utils/Base64Utils';
import { LndMobileEventEmitter } from '../utils/LndMobileUtils';
import { localeString } from '../utils/LocaleUtils';
Expand Down Expand Up @@ -170,22 +172,67 @@ export default class LSPStore {

@action
public initChannelAcceptor = async () => {
const { implementation } = this.settingsStore;
if (this.channelAcceptor) return;
this.channelAcceptor = LndMobileEventEmitter.addListener(
'ChannelAcceptor',
async (event: any) => {
try {
const channelAcceptRequest =
channel.decodeChannelAcceptRequest(event.data);

await this.handleChannelAcceptorEvent(channelAcceptRequest);
} catch (error: any) {
console.error('channel acceptance error: ' + error.message);

if (implementation === 'embedded-lnd') {
this.channelAcceptor = LndMobileEventEmitter.addListener(
'ChannelAcceptor',
async (event: any) => {
try {
const result = channel.decodeChannelAcceptRequest(
event.data
);
await this.handleChannelAcceptorEvent(result);
} catch (error: any) {
console.error(
'channelAcceptorEvent embedded-lnd error:',
error.message
);
}
}
}
);
);

await channel.channelAcceptor();
}

// if (implementation === 'lightning-node-connect') {
// const { LncModule } = NativeModules;
// const eventEmitter = new NativeEventEmitter(LncModule);
// console.log('hERE', eventEmitter);
// const call = BackendUtils.channelAcceptor();
// console.log('call', call)
// this.channelAcceptor = eventEmitter.addListener(
// 'lnrpc.Lightning.ChannelAcceptor',
// (event: any) => {
// // console.log('-->', event);
// if (event.result) {
// try {
// const result = JSON.parse(event.result);
// console.log('~~RESULT', result);
// // only allow zero conf chans from the LSP
// const isZeroConfAllowed =
// result.node_pubkey === this.info.pub_key;

// BackendUtils.channelAcceptorAnswer({
// pending_chan_id: result.pending_chan_id,
// zero_conf:
// !result.wants_zero_conf ||
// isZeroConfAllowed,
// accept: isZeroConfAllowed
// });
// } catch (error: any) {
// console.error(
// 'channelAcceptorEvent lightning-node-connect error:',
// error.message
// );
// }
// }
// }
// );

await channel.channelAcceptor();
// console.log('~~~this.channelAcceptor', this.channelAcceptor);
// }
};

@action
Expand Down
3 changes: 3 additions & 0 deletions utils/BackendUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ class BackendUtils {
this.call('publishTransaction', args);
bumpFee = (...args: any[]) => this.call('bumpFee', args);
lookupInvoice = (...args: any[]) => this.call('lookupInvoice', args);
channelAcceptor = (...args: any[]) => this.call('channelAcceptor', args);
channelAcceptorAnswer = (...args: any[]) =>
this.call('channelAcceptorAnswer', args);
subscribeInvoice = (...args: any[]) => this.call('subscribeInvoice', args);
subscribeInvoices = (...args: any[]) =>
this.call('subscribeInvoices', args);
Expand Down
57 changes: 51 additions & 6 deletions views/Wallet/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
AppState,
BackHandler,
Linking,
NativeEventEmitter,
NativeEventSubscription,
NativeModules,
PanResponder,
PanResponderInstance,
Platform,
Expand Down Expand Up @@ -120,6 +122,8 @@ export default class Wallet extends React.Component<WalletProps, WalletState> {
private handleAppStateChangeSubscription: NativeEventSubscription;
private backPressSubscription: NativeEventSubscription;

channelAcceptor: any;

constructor(props) {
super(props);
this.state = {
Expand Down Expand Up @@ -369,12 +373,6 @@ export default class Wallet extends React.Component<WalletProps, WalletState> {
embeddedLndNetwork === 'Testnet'
);
}
if (BackendUtils.supportsLSPs()) {
if (SettingsStore.settings.enableLSP) {
LSPStore.getLSPInfo();
}
LSPStore.initChannelAcceptor();
}
NodeInfoStore.getNodeInfo();
if (BackendUtils.supportsAccounts()) UTXOsStore.listAccounts();
await BalanceStore.getCombinedBalance(false);
Expand Down Expand Up @@ -455,6 +453,53 @@ export default class Wallet extends React.Component<WalletProps, WalletState> {
}
}

if (BackendUtils.supportsLSPs()) {
if (SettingsStore.settings.enableLSP) {
await LSPStore.getLSPInfo();
}

if (implementation === 'lightning-node-connect') {
// if (this.channelAcceptor) return;
const { LncModule } = NativeModules;
const eventEmitter = new NativeEventEmitter(LncModule);
console.log('hERE~~3', eventEmitter);
const call = BackendUtils.channelAcceptor();
console.log('call', call)
this.channelAcceptor = eventEmitter.addListener(
call,
(event: any) => {
console.log('>>event', event);
if (event.result) {
try {
const result = JSON.parse(event.result);
console.log('~~RESULT', result);
// // only allow zero conf chans from the LSP
const isZeroConfAllowed =
result.node_pubkey === LSPStore.info.pub_key;

BackendUtils.channelAcceptorAnswer({
pending_chan_id: result.pending_chan_id,
zero_conf:
!result.wants_zero_conf ||
isZeroConfAllowed,
accept: isZeroConfAllowed
});
} catch (error: any) {
console.error(
'channelAcceptorEvent lightning-node-connect error:',
error.message
);
}
}
}
);

console.log('~~~this.channelAcceptor', this.channelAcceptor);
} else {
LSPStore.initChannelAcceptor();
}
}

if (connecting) {
setConnectingStatus(false);
}
Expand Down