Skip to content

Commit

Permalink
feat(mutinynet): use single function for invoice parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
thebrandonlucas committed Apr 22, 2024
1 parent eb0e114 commit 3326358
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 47 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"source.organizeImports": "explicit"
},
"typescript.preferences.importModuleSpecifier": "non-relative",
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
"i18n-ally.localesPaths": ["src/i18n", "src/i18n/locales"]
}
4 changes: 2 additions & 2 deletions src/app/screens/ConfirmPayment/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { act, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import lightningPayReq from "bolt11";
import { MemoryRouter } from "react-router-dom";
import { settingsFixture as mockSettings } from "~/../tests/fixtures/settings";
import type { OriginData } from "~/types";

import { decodeLightningInvoice } from "~/app/utils";
import ConfirmPayment from "./index";

const mockOrigin: OriginData = {
Expand Down Expand Up @@ -104,7 +104,7 @@ describe("ConfirmPayment", () => {
);
});

const satoshis = lightningPayReq.decode(paymentRequest).satoshis || 0;
const satoshis = decodeLightningInvoice(paymentRequest).satoshis || 0;

expect(await screen.findByText(`${satoshis} sats`)).toBeInTheDocument();

Expand Down
11 changes: 3 additions & 8 deletions src/app/screens/ConfirmPayment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Container from "@components/Container";
import PaymentSummary from "@components/PaymentSummary";
import PublisherCard from "@components/PublisherCard";
import ResultCard from "@components/ResultCard";
import lightningPayReq from "bolt11";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
Expand All @@ -14,6 +13,7 @@ import toast from "~/app/components/Toast";
import { useAccount } from "~/app/context/AccountContext";
import { useSettings } from "~/app/context/SettingsContext";
import { useNavigationState } from "~/app/hooks/useNavigationState";
import { decodeLightningInvoice } from "~/app/utils";
import { USER_REJECTED_ERROR } from "~/common/constants";
import api from "~/common/lib/api";
import msg from "~/common/lib/msg";
Expand All @@ -35,13 +35,8 @@ function ConfirmPayment() {

const navState = useNavigationState();
const paymentRequest = navState.args?.paymentRequest as string;
const signet = {
bech32: "tbs",
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0],
};
const invoice = lightningPayReq.decode(paymentRequest, signet);

const invoice = decodeLightningInvoice(paymentRequest);

const navigate = useNavigate();
const auth = useAccount();
Expand Down
4 changes: 2 additions & 2 deletions src/app/screens/ConfirmPaymentAsync/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import ConfirmOrCancel from "@components/ConfirmOrCancel";
import Container from "@components/Container";
import PaymentSummary from "@components/PaymentSummary";
import PublisherCard from "@components/PublisherCard";
import lightningPayReq from "bolt11";
import { useEffect, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
Expand All @@ -12,6 +11,7 @@ import ScreenHeader from "~/app/components/ScreenHeader";
import toast from "~/app/components/Toast";
import { useSettings } from "~/app/context/SettingsContext";
import { useNavigationState } from "~/app/hooks/useNavigationState";
import { decodeLightningInvoice } from "~/app/utils";
import { USER_REJECTED_ERROR } from "~/common/constants";
import api from "~/common/lib/api";
import msg from "~/common/lib/msg";
Expand All @@ -31,7 +31,7 @@ function ConfirmPaymentAsync() {

const navState = useNavigationState();
const paymentRequest = navState.args?.paymentRequest as string;
const invoice = lightningPayReq.decode(paymentRequest);
const invoice = decodeLightningInvoice(paymentRequest);

const navigate = useNavigate();

Expand Down
15 changes: 6 additions & 9 deletions src/app/screens/Send/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import Header from "@components/Header";
import IconButton from "@components/IconButton";
import TextField from "@components/form/TextField";
import { PopiconsChevronLeftLine } from "@popicons/react";
import lightningPayReq from "bolt11";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router-dom";
import QrcodeAdornment from "~/app/components/QrcodeAdornment";
import toast from "~/app/components/Toast";
import { extractLightningTagData, isBitcoinAddress } from "~/app/utils";
import {
decodeLightningInvoice,
extractLightningTagData,
isBitcoinAddress,
} from "~/app/utils";
import lnurlLib from "~/common/lib/lnurl";
import { isLNURLDetailsError } from "~/common/utils/typeHelpers";

Expand Down Expand Up @@ -96,13 +99,7 @@ function Send() {
state: { args: { bitcoinAddress: invoice } },
});
} else {
const signet = {
bech32: "tbs",
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0],
};
lightningPayReq.decode(invoice, signet); // throws if invalid.
decodeLightningInvoice(invoice); // throws if invalid.
navigate("/confirmPayment", {
state: {
args: {
Expand Down
27 changes: 26 additions & 1 deletion src/app/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { GetAccountInformationResponse } from "@getalby/sdk/dist/types";
import lightningPayReq from "bolt11";
import { useSettings } from "~/app/context/SettingsContext";
import api from "~/common/lib/api";
import { BrowserType, Theme } from "~/types";
import { BrowserType, CustomNetwork, Theme } from "~/types";

export function classNames(...classes: (string | boolean)[]) {
return classes.filter(Boolean).join(" ");
Expand Down Expand Up @@ -83,3 +84,27 @@ export function extractLightningTagData(url: string) {
return url.replace(/^lightning:/i, "");
}
}

export function decodeLightningInvoice(
invoice: string,
customNetwork?: CustomNetwork
) {
try {
return lightningPayReq.decode(invoice);
} catch (e) {
const err = e as Error;
// NOTE: is there a way to get network for the current account from here?
// This catch-and-rethrow is a workaround for us not having the network
const mutinynet = {
bech32: "tbs",
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0],
};
if (err.message === "Unknown coin bech32 prefix") {
return lightningPayReq.decode(invoice, customNetwork ?? mutinynet);
} else {
throw e;
}
}
}
10 changes: 2 additions & 8 deletions src/common/utils/paymentRequest.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import lightningPayReq from "bolt11";
import { decodeLightningInvoice } from "~/app/utils";

export function getPaymentRequestDescription(paymentRequest: string): string {
const signet = {
bech32: "tbs",
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0],
};
const decodedPaymentRequest = lightningPayReq.decode(paymentRequest, signet);
const decodedPaymentRequest = decodeLightningInvoice(paymentRequest);
const descriptionTag = decodedPaymentRequest.tags.find(
(tag) => tag.tagName === "description"
);
Expand Down
10 changes: 2 additions & 8 deletions src/extension/background-script/actions/ln/sendPayment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import lightningPayReq from "bolt11";
import PubSub from "pubsub-js";
import { decodeLightningInvoice } from "~/app/utils";
import pubsub from "~/common/lib/pubsub";
import state from "~/extension/background-script/state";
import { Message, MessageSendPayment } from "~/types";
Expand Down Expand Up @@ -28,13 +28,7 @@ export default async function sendPayment(
let response, paymentRequestDetails;

try {
const signet = {
bech32: "tbs",
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0],
};
paymentRequestDetails = lightningPayReq.decode(paymentRequest, signet);
paymentRequestDetails = decodeLightningInvoice(paymentRequest);

response = await connector.sendPayment({
paymentRequest,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import lightningPayReq from "bolt11";
import utils from "~/common/lib/utils";
import { getHostFromSender } from "~/common/utils/helpers";
import { Message, Sender } from "~/types";

import { decodeLightningInvoice } from "~/app/utils";
import db from "../../db";
import sendPayment from "../ln/sendPayment";

Expand All @@ -16,13 +16,8 @@ const sendPaymentOrPrompt = async (message: Message, sender: Sender) => {
error: "Payment request missing.",
};
}
const signet = {
bech32: "tbs",
pubKeyHash: 0x6f,
scriptHash: 0xc4,
validWitnessVersions: [0],
};
const paymentRequestDetails = lightningPayReq.decode(paymentRequest, signet);

const paymentRequestDetails = decodeLightningInvoice(paymentRequest);
if (await checkAllowance(host, paymentRequestDetails.satoshis || 0)) {
return sendPaymentWithAllowance(message);
} else {
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export type BitcoinNetworkType = "bitcoin" | "testnet" | "regtest";

export type LiquidNetworkType = "liquid" | "testnet" | "regtest";

export type CustomNetwork = {
bech32: string;
pubKeyHash: number;
scriptHash: number;
validWitnessVersions: number[];
};

export interface Account {
id: string;
connector: ConnectorType;
Expand Down

0 comments on commit 3326358

Please sign in to comment.