diff --git a/src/components/Failure.tsx b/src/components/Failure.tsx
new file mode 100644
index 00000000..6aefbbf9
--- /dev/null
+++ b/src/components/Failure.tsx
@@ -0,0 +1,41 @@
+import { A } from "@solidjs/router";
+import { Match, Switch } from "solid-js";
+
+import { InfoBox, MegaClock, MegaEx } from "~/components";
+import { useI18n } from "~/i18n/context";
+
+export function Failure(props: { reason: string }) {
+ const i18n = useI18n();
+
+ return (
+
+
+
+
+ {i18n.t("send.payment_pending")}
+
+
+ {i18n.t("send.payment_pending_description")}
+
+
+
+
+
+ {i18n.t("send.error_channel_reserves")}
+
+
+ {i18n.t("send.error_channel_reserves_explained")}{" "}
+ {i18n.t("common.why")}
+
+
+
+
+
+ {props.reason}
+
+
+
+ );
+}
diff --git a/src/components/ReceiveWarnings.tsx b/src/components/ReceiveWarnings.tsx
index 13564623..aa4d2dd1 100644
--- a/src/components/ReceiveWarnings.tsx
+++ b/src/components/ReceiveWarnings.tsx
@@ -5,7 +5,10 @@ import { FeesModal } from "~/components/MoreInfoModal";
import { useI18n } from "~/i18n/context";
import { useMegaStore } from "~/state/megaStore";
-export function ReceiveWarnings(props: { amountSats: string | bigint }) {
+export function ReceiveWarnings(props: {
+ amountSats: string | bigint;
+ from_fedi_to_ln: boolean;
+}) {
const i18n = useI18n();
const [state, _actions] = useMegaStore();
@@ -26,7 +29,7 @@ export function ReceiveWarnings(props: { amountSats: string | bigint }) {
});
const warningText = () => {
- if (state.federations?.length !== 0) {
+ if (state.federations?.length !== 0 && props.from_fedi_to_ln != true) {
return undefined;
}
if ((state.balance?.lightning || 0n) === 0n) {
diff --git a/src/components/SharpButton.tsx b/src/components/SharpButton.tsx
new file mode 100644
index 00000000..b17da582
--- /dev/null
+++ b/src/components/SharpButton.tsx
@@ -0,0 +1,21 @@
+import { JSX } from "solid-js";
+
+export function SharpButton(props: {
+ onClick: () => void;
+ children: JSX.Element;
+ disabled?: boolean;
+}) {
+ return (
+
+ );
+}
diff --git a/src/components/index.ts b/src/components/index.ts
index 241728ba..3b6a779f 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -36,6 +36,7 @@ export * from "./Restart";
export * from "./ResyncOnchain";
export * from "./SeedWords";
export * from "./SetupErrorDisplay";
+export * from "./Failure";
export * from "./ShareCard";
export * from "./Toaster";
export * from "./NostrActivity";
@@ -50,3 +51,4 @@ export * from "./FeeDisplay";
export * from "./ReceiveWarnings";
export * from "./SimpleInput";
export * from "./LabelCircle";
+export * from "./SharpButton";
diff --git a/src/i18n/en/translations.ts b/src/i18n/en/translations.ts
index 120f9e8f..44463015 100644
--- a/src/i18n/en/translations.ts
+++ b/src/i18n/en/translations.ts
@@ -3,6 +3,8 @@ export default {
title: "Mutiny Wallet",
nice: "Nice",
home: "Home",
+ e_sats: "eSATS",
+ e_sat: "eSAT",
sats: "SATS",
sat: "SAT",
fee: "Fee",
@@ -126,6 +128,7 @@ export default {
sats_sent: "sats sent"
},
what_for: "What's this for?",
+ zap_note: "Zap note",
error_low_balance:
"We do not have enough balance to pay the given amount.",
error_invoice_match:
@@ -144,7 +147,9 @@ export default {
payment_pending_description:
"It's taking a while, but it's possible this payment may still go through. Please check 'Activity' for the current status.",
hodl_invoice_warning:
- "This is a hodl invoice. Payments to hodl invoices can cause channel force closes, which results in high on-chain fees. Pay at your own risk!"
+ "This is a hodl invoice. Payments to hodl invoices can cause channel force closes, which results in high on-chain fees. Pay at your own risk!",
+ private: "Private",
+ anonzap: "Anon Zap"
},
feedback: {
header: "Give us feedback!",
@@ -595,6 +600,19 @@ export default {
connecting: "Connecting...",
confirm_swap: "Confirm Swap"
},
+ swap_lightning: {
+ insufficient_funds: "You don't have enough funds to swap to lightning",
+ header: "Swap to Lightning",
+ header_preview: "Preview Swap",
+ completed: "Swap Completed",
+ too_small:
+ "Invalid amount entered. You need to swap at least 100k sats.",
+ sats_added:
+ "+{{amount}} sats have been added to your Lightning balance",
+ sats_fee: "+{{amount}} sats fee",
+ confirm_swap: "Confirm Swap",
+ preview_swap: "Preview Swap Fee"
+ },
reload: {
mutiny_update: "Mutiny Update",
new_version_description:
diff --git a/src/router.tsx b/src/router.tsx
index 8eea78a7..557331ee 100644
--- a/src/router.tsx
+++ b/src/router.tsx
@@ -15,7 +15,8 @@ import {
Scanner,
Search,
Send,
- Swap
+ Swap,
+ SwapLightning
} from "~/routes";
import {
Admin,
@@ -101,6 +102,7 @@ export function Router() {
+
diff --git a/src/routes/Activity.tsx b/src/routes/Activity.tsx
index 773649bf..04ae3da0 100644
--- a/src/routes/Activity.tsx
+++ b/src/routes/Activity.tsx
@@ -71,7 +71,6 @@ function ContactRow() {
refetch();
}
- //
async function saveContact(id: string, contact: ContactFormValues) {
console.log("saving contact", id, contact);
const hexpub = await hexpubFromNpub(contact.npub?.trim());
@@ -95,6 +94,16 @@ function ContactRow() {
refetch();
}
+ async function deleteContact(id: string) {
+ try {
+ await state.mutiny_wallet?.delete_contact(id);
+ } catch (e) {
+ console.error(e);
+ showToast(eify(e));
+ }
+ refetch();
+ }
+
return (
@@ -106,6 +115,7 @@ function ContactRow() {
contact={contact}
gradient={gradients()?.get(contact.name)}
saveContact={saveContact}
+ deleteContact={deleteContact}
/>
)}
diff --git a/src/routes/Receive.tsx b/src/routes/Receive.tsx
index 51360623..6a347fb3 100644
--- a/src/routes/Receive.tsx
+++ b/src/routes/Receive.tsx
@@ -377,7 +377,10 @@ export function Receive() {
setAmountSats={setAmount}
onSubmit={getQr}
/>
-
+
diff --git a/src/routes/Search.tsx b/src/routes/Search.tsx
index a95c1cb6..ec6cacf5 100644
--- a/src/routes/Search.tsx
+++ b/src/routes/Search.tsx
@@ -465,6 +465,16 @@ function ContactButton(props: {
onClick: () => void;
}) {
const i18n = useI18n();
+
+ const primalUrl = createMemo(() => {
+ const originalUrl = props.contact.image_url;
+ if (!originalUrl) return undefined;
+
+ return `https://primal.b-cdn.net/media-cache?s=s&a=1&u=${encodeURIComponent(
+ originalUrl
+ )}`;
+ });
+
return (