feat: wire up force close channel support for LDK Node

This commit is contained in:
Evan Kaloudis
2026-03-26 20:01:33 -04:00
parent 0243dfb2c1
commit 9c32a1a5bf
12 changed files with 1407 additions and 136 deletions
+34
View File
@@ -198,6 +198,7 @@ export interface ChannelDetails {
forceCloseSpendDelay?: number;
inboundHtlcMinimumMsat: number;
inboundHtlcMaximumMsat?: number;
shortChannelId?: string;
}
export interface ClosedChannelDetails {
@@ -402,6 +403,34 @@ export interface Lsps1OrderStatus {
channelInfo?: Lsps1ChannelInfo;
}
// ============================================================================
// LSPS7 Types
// ============================================================================
export type Lsps7OrderState = 'created' | 'completed' | 'failed';
export interface Lsps7OriginalOrder {
id: string;
service: string;
}
export interface Lsps7ExtendableChannel {
shortChannelId: string;
maxChannelExtensionExpiryBlocks: number;
expirationBlock: number;
originalOrder?: Lsps7OriginalOrder;
extensionOrderIds?: string[];
}
export interface Lsps7OrderResponse {
orderId: string;
orderState: Lsps7OrderState;
channelExtensionExpiryBlocks: number;
newChannelExpiryBlock: number;
paymentInfo: Lsps1PaymentInfo;
channel: Lsps7ExtendableChannel;
}
// ============================================================================
// Module Interface
// ============================================================================
@@ -459,6 +488,11 @@ export interface ILdkNodeModule {
userChannelId: string,
counterpartyNodeId: string
): Promise<void>;
forceCloseChannel(
userChannelId: string,
counterpartyNodeId: string,
reason: string
): Promise<void>;
// On-chain Methods
newOnchainAddress(): Promise<string>;
+104 -2
View File
@@ -15,7 +15,9 @@ import type {
PeerDetails,
LdkNodeEvent,
Lsps1OrderResponse,
Lsps1OrderStatus
Lsps1OrderStatus,
Lsps7ExtendableChannel,
Lsps7OrderResponse
} from './LdkNode.d';
const { LdkNodeModule } = NativeModules;
@@ -84,6 +86,22 @@ const setLiquiditySourceLsps2 = async ({
);
};
const setLiquiditySourceLsps7 = async ({
nodeId,
address,
token
}: {
nodeId: string;
address: string;
token?: string | null;
}): Promise<void> => {
return await LdkNodeModule.setLiquiditySourceLsps7(
nodeId,
address,
token ?? null
);
};
const setTrustedPeers0conf = async (peers: string[]): Promise<void> => {
return await LdkNodeModule.setTrustedPeers0conf(peers);
};
@@ -211,6 +229,22 @@ const closeChannel = async ({
return await LdkNodeModule.closeChannel(userChannelId, counterpartyNodeId);
};
const forceCloseChannel = async ({
userChannelId,
counterpartyNodeId,
reason
}: {
userChannelId: string;
counterpartyNodeId: string;
reason?: string;
}): Promise<void> => {
return await LdkNodeModule.forceCloseChannel(
userChannelId,
counterpartyNodeId,
reason ?? ''
);
};
// ============================================================================
// On-chain Functions
// ============================================================================
@@ -520,6 +554,41 @@ const lsps1CheckOrderStatus = async (
return await LdkNodeModule.lsps1CheckOrderStatus(orderId);
};
// ============================================================================
// LSPS7 Functions
// ============================================================================
const lsps7GetExtendableChannels = async (): Promise<
Lsps7ExtendableChannel[]
> => {
return await LdkNodeModule.lsps7GetExtendableChannels();
};
const lsps7CreateOrder = async ({
shortChannelId,
channelExtensionExpiryBlocks,
token,
refundOnchainAddress
}: {
shortChannelId: string;
channelExtensionExpiryBlocks: number;
token?: string | null;
refundOnchainAddress?: string | null;
}): Promise<Lsps7OrderResponse> => {
return await LdkNodeModule.lsps7CreateOrder(
shortChannelId,
channelExtensionExpiryBlocks,
token ?? null,
refundOnchainAddress ?? null
);
};
const lsps7CheckOrderStatus = async (
orderId: string
): Promise<Lsps7OrderResponse> => {
return await LdkNodeModule.lsps7CheckOrderStatus(orderId);
};
// ============================================================================
// Message Signing Functions
// ============================================================================
@@ -641,6 +710,18 @@ const initializeNode = async ({
} catch (e) {
console.log('LDK Node: LSPS2 configuration failed');
}
// Also configure LSPS7 with the same LSP for channel lease extensions
try {
await setLiquiditySourceLsps7({
nodeId: lsps1Config.nodeId,
address: lsps1Config.address,
token: lsps1Config.token
});
console.log('LDK Node: LSPS7 liquidity source configured');
} catch (e) {
console.log('LDK Node: LSPS7 configuration failed');
}
}
// Set trusted peers for zero-conf channels (e.g., LSP)
@@ -741,6 +822,11 @@ export interface ILdkNodeInjections {
userChannelId: string;
counterpartyNodeId: string;
}) => Promise<void>;
forceCloseChannel: (params: {
userChannelId: string;
counterpartyNodeId: string;
reason?: string;
}) => Promise<void>;
};
onchain: {
newOnchainAddress: () => Promise<string>;
@@ -839,6 +925,16 @@ export interface ILdkNodeInjections {
}) => Promise<Lsps1OrderResponse>;
checkOrderStatus: (orderId: string) => Promise<Lsps1OrderStatus>;
};
lsps7: {
getExtendableChannels: () => Promise<Lsps7ExtendableChannel[]>;
createOrder: (params: {
shortChannelId: string;
channelExtensionExpiryBlocks: number;
token?: string | null;
refundOnchainAddress?: string | null;
}) => Promise<Lsps7OrderResponse>;
checkOrderStatus: (orderId: string) => Promise<Lsps7OrderResponse>;
};
signing: {
signMessage: (message: string) => Promise<string>;
verifySignature: (params: {
@@ -908,7 +1004,8 @@ const LdkNodeInjection: ILdkNodeInjections = {
listChannels,
listClosedChannels,
openChannel,
closeChannel
closeChannel,
forceCloseChannel
},
onchain: {
newOnchainAddress,
@@ -948,6 +1045,11 @@ const LdkNodeInjection: ILdkNodeInjections = {
requestChannel: lsps1RequestChannel,
checkOrderStatus: lsps1CheckOrderStatus
},
lsps7: {
getExtendableChannels: lsps7GetExtendableChannels,
createOrder: lsps7CreateOrder,
checkOrderStatus: lsps7CheckOrderStatus
},
signing: {
signMessage,
verifySignature