Skip to content

Commit

Permalink
Bump channel force closure
Browse files Browse the repository at this point in the history
  • Loading branch information
hsjoberg committed May 30, 2024
1 parent 426895c commit 877d95d
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 3 deletions.
1 change: 1 addition & 0 deletions ios/LndMobile/Lnd.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ open class Lnd {
"VerifyMessage": { bytes, cb in LndmobileVerifyMessage(bytes, cb) },
"SignMessage": { bytes, cb in LndmobileSignMessage(bytes, cb) },
"SignerSignMessage": { bytes, cb in LndmobileSignerSignMessage(bytes, cb) },
"WalletKitListSweeps": { bytes, cb in LndmobileWalletKitListSweeps(bytes, cb) },

// autopilot
"AutopilotStatus": { bytes, cb in LndmobileAutopilotStatus(bytes, cb) },
Expand Down
63 changes: 62 additions & 1 deletion src/components/PendingChannelCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Long from "long";
import BigNumber from "bignumber.js";

import { style } from "./ChannelCard";
import { lnrpc } from "../../proto/lightning";
import { lnrpc, walletrpc } from "../../proto/lightning";
import { blixtTheme } from "../native-base-theme/variables/commonColor";
import { useStoreActions, useStoreState } from "../state/store";
import { identifyService, lightningServices } from "../utils/lightning-services";
Expand All @@ -16,6 +16,7 @@ import { getUnitNice, valueBitcoin, valueFiat } from "../utils/bitcoin-units";
import { useTranslation } from "react-i18next";
import { namespaces } from "../i18n/i18n.constants";
import { Alert } from "../utils/alert";
import { pendingSweeps } from "../lndmobile/wallet";

const dataLossChannelState = "ChanStatusLocalDataLoss|ChanStatusRestored";

Expand Down Expand Up @@ -98,6 +99,54 @@ export const PendingChannelCard = ({ channel, type, alias }: IPendingChannelCard
);
};

const dragForceCloseAnchor = async (
channel: lnrpc.PendingChannelsResponse.IWaitingCloseChannel,
) => {
Alert.prompt(t("channel.bumpFee"), t("channel.bumpFeeAlerts.enterFeeRate"), [
{
text: t("buttons.cancel", { ns: namespaces.common }),
style: "cancel",
onPress: () => {},
},
{
text: "OK",
onPress: async (feeRate) => {
if (!feeRate) {
Alert.alert(t("channel.bumpFeeAlerts.missingFeeRate"));
return;
}

const feeRateNumber = Number.parseInt(feeRate);

// Follows anchor sweep code in bumpForceCloseFee.go in lnd/cmd/lncli/walletrpc_active.go

//& Fetch waiting close channel commitments.
const sweeps = await pendingSweeps();

//& Retrieve pending sweeps.
const commitments = [channel.commitments?.localTxid, channel.commitments?.remoteTxid];

//& Match pending sweeps with commitments of the channel for which a bump
//& is requested and bump their fees.
for (const sweep of sweeps.pendingSweeps) {
//& Only bump anchor sweeps.
if (sweep.witnessType !== walletrpc.WitnessType.COMMITMENT_ANCHOR) {
continue;
}

if (commitments.includes(sweep.outpoint?.txidStr)) {
await bumpFee({
txid: sweep.outpoint?.txidStr ?? "",
index: sweep.outpoint?.outputIndex ?? 0,
feeRate: feeRateNumber,
});
}
}
},
},
]);
};

const bumpChannelFee = async (channel: lnrpc.PendingChannelsResponse.IPendingOpenChannel) => {
if (!channel.channel || !channel.channel.channelPoint) {
Alert.alert(t("msg.error", { ns: namespaces.common }));
Expand Down Expand Up @@ -391,6 +440,18 @@ export const PendingChannelCard = ({ channel, type, alias }: IPendingChannelCard
</Left>
</Row>
)}
<Row style={{ width: "100%" }}>
<Left>
<Button
style={{ marginTop: 14 }}
danger={true}
small={true}
onPress={() => bumpChannelFee(channel)}
>
<Text style={{ fontSize: 8 }}>{t("channel.bumpFee")}</Text>
</Button>
</Left>
</Row>
</>
)}
{type === "FORCE_CLOSING" && (
Expand Down
17 changes: 16 additions & 1 deletion src/lndmobile/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as base64 from "base64-js";

import { sendCommand, sendStreamCommand, decodeStreamResult } from "./utils";
import { stringToUint8Array } from "../utils";
import { lnrpc, signrpc } from "../../proto/lightning";
import { lnrpc, signrpc, walletrpc } from "../../proto/lightning";

/**
* @throws
Expand Down Expand Up @@ -156,6 +156,21 @@ export const signMessage = async (keyFamily: number, keyIndex: number, msg: Uint
return response;
};


/**
* @throws
*/
export const pendingSweeps = async (): Promise<walletrpc.PendingSweepsResponse> => {
const response = await sendCommand<walletrpc.IPendingSweepsRequest, walletrpc.PendingSweepsRequest, walletrpc.PendingSweepsResponse>({
request: walletrpc.PendingSweepsRequest,
response: walletrpc.PendingSweepsResponse,
method: "WalletKitPendingSweeps",
options: {
},
});
return response;
};

// TODO exception?
// TODO move to a more appropriate file?
export const subscribeInvoices = async (): Promise<string> => {
Expand Down
15 changes: 14 additions & 1 deletion src/windows/InitProcess/DEV_Commands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
getTransaction,
getTransactions,
} from "../../storage/database/transaction";
import { genSeed, initWallet, signMessage } from "../../lndmobile/wallet";
import { genSeed, initWallet, pendingSweeps, signMessage } from "../../lndmobile/wallet";
import { getPin, getWalletPassword } from "../../storage/keystore";
import { lnrpc, routerrpc } from "../../../proto/lightning";
import { modifyStatus, queryScores, status } from "../../lndmobile/autopilot";
Expand All @@ -71,6 +71,7 @@ import { blixtTheme } from "../../native-base-theme/variables/commonColor";
import { generateSecureRandom } from "react-native-securerandom";
import { localNotification } from "../../utils/push-notification";
import { sendCommand } from "../../lndmobile/utils";
import { getCFilter } from "../../lndmobile/neutrino";

let iCloudStorage: any;
console.log(PLATFORM);
Expand Down Expand Up @@ -145,6 +146,17 @@ export default function DEV_Commands({ navigation, continueCallback }: IProps) {
</>
)}
<Text style={{ width: "100%" }}>Random:</Text>
<Button
small
onPress={async () => {
Alert.prompt("Compact filter", undefined, async (hash) => {
const filter = await getCFilter(hash);
Alert.alert(filter.filter.byteLength.toString());
});
}}
>
<Text style={styles.buttonText}>getCFilter size</Text>
</Button>
<Button
small
onPress={async () => {
Expand Down Expand Up @@ -1282,6 +1294,7 @@ export default function DEV_Commands({ navigation, continueCallback }: IProps) {
["getNetworkInfo", getNetworkInfo],
["getTransactions", getTransactionsOnchain],
["closedChannels", closedChannels],
["pendingSweeps", pendingSweeps],
].map(([name, f], i) => {
return (
<Button
Expand Down

0 comments on commit 877d95d

Please sign in to comment.