From cdc7c880fa5fa4cdaf52bd7c0471cf8c817de2c5 Mon Sep 17 00:00:00 2001
From: benthecarman
Date: Fri, 22 Mar 2024 16:08:05 -0500
Subject: [PATCH 01/20] Always pass along lnurl comment
---
src/routes/Send.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/routes/Send.tsx b/src/routes/Send.tsx
index 0cf91bde..94dab36f 100644
--- a/src/routes/Send.tsx
+++ b/src/routes/Send.tsx
@@ -509,13 +509,12 @@ export function Send() {
visibility() !== "Not Available" && contact()?.npub
? contact()?.npub
: undefined;
- const comment = zapNpub ? whatForInput() : undefined;
const payment = await state.mutiny_wallet?.lnurl_pay(
lnurlp()!,
amountSats(),
zapNpub, // zap_npub
tags,
- comment, // comment
+ whatForInput(), // comment
visibility()
);
sentDetails.payment_hash = payment?.payment_hash;
From 0dbcdc568bbaedb4231180c56219f61949f384dc Mon Sep 17 00:00:00 2001
From: benthecarman
Date: Tue, 9 Apr 2024 15:26:41 -0500
Subject: [PATCH 02/20] Try each federation guardian when joining
---
src/logic/errorDispatch.ts | 6 ++++
src/routes/settings/ManageFederations.tsx | 37 ++++++++++++++++++-----
2 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/src/logic/errorDispatch.ts b/src/logic/errorDispatch.ts
index f9002cdc..e8eae7ae 100644
--- a/src/logic/errorDispatch.ts
+++ b/src/logic/errorDispatch.ts
@@ -44,6 +44,7 @@ type MutinyError =
| "Failed to read or write json from the front end"
| "The given node pubkey is invalid."
| "Failed to get nostr data."
+ | "Error with NIP-07 extension"
| "Failed to get the bitcoin price."
| "Satoshi amount is invalid"
| "Failed to execute a dlc function"
@@ -54,6 +55,11 @@ type MutinyError =
| "Failed to create payjoin request."
| "Payjoin response error: {0}"
| "Payjoin configuration failed."
+ | "Error calling Cashu Mint"
+ | "Mint URL in token is empty"
+ | "Token has been already spent."
+ | "A federation is required"
+ | "Failed to connect to a federation."
| "Unknown Error";
export function matchError(e: unknown): Error {
diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx
index ec2b1d66..23d0a964 100644
--- a/src/routes/settings/ManageFederations.tsx
+++ b/src/routes/settings/ManageFederations.tsx
@@ -110,7 +110,7 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
f: FederationForm
) => {
const federation_code = f.federation_code.trim();
- await onSelect(federation_code);
+ await onSelect([federation_code]);
};
const [federations] = createResource(async () => {
@@ -124,14 +124,36 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
}
});
- const onSelect = async (inviteCode: string) => {
+ const onSelect = async (inviteCodes: string[]) => {
setSuccess("");
setError(undefined);
- setLoadingFederation(inviteCode);
try {
- const newFederation =
- await state.mutiny_wallet?.new_federation(inviteCode);
- console.log("New federation added:", newFederation);
+ for (const inviteCode of inviteCodes) {
+ try {
+ console.log("Adding federation:", inviteCode);
+ setLoadingFederation(inviteCode);
+ const newFederation =
+ await state.mutiny_wallet?.new_federation(inviteCode);
+ console.log("New federation added:", newFederation);
+ break;
+ } catch (e) {
+ const error = eify(e);
+ console.log("Error adding federation:", error.message);
+ // if we can't connect to the guardian, try to others,
+ // otherwise throw the error
+ if (
+ error.message ===
+ "Failed to connect to a federation." ||
+ error.message === "Invalid Arguments were given"
+ ) {
+ console.error(
+ "Failed to connect to guardian, trying another one"
+ );
+ } else {
+ throw e;
+ }
+ }
+ }
setSuccess(
i18n.t("settings.manage_federations.federation_added_success")
);
@@ -275,11 +297,10 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
- {/* FIXME: do something smarter than just taking first code */}
- onSelect(fed.invite_codes[0])
+ onSelect(fed.invite_codes)
}
loading={fed.invite_codes.includes(
loadingFederation()
From 07cafdeebe7df2d8ec25ed6ab9ffe0a853cc3513 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Mon, 8 Apr 2024 16:39:48 -0500
Subject: [PATCH 03/20] cache nostr profile fetching in activity view
---
src/components/Activity.tsx | 65 ++++++++++++++++++++++++++-----------
1 file changed, 46 insertions(+), 19 deletions(-)
diff --git a/src/components/Activity.tsx b/src/components/Activity.tsx
index 8f644638..a2c9b322 100644
--- a/src/components/Activity.tsx
+++ b/src/components/Activity.tsx
@@ -1,7 +1,16 @@
import { TagItem } from "@mutinywallet/mutiny-wasm";
-import { cache, createAsync, revalidate, useNavigate } from "@solidjs/router";
+import { cache, createAsync, useNavigate } from "@solidjs/router";
import { Plus, Save, Search, Shuffle, Users } from "lucide-solid";
-import { createEffect, createSignal, For, Match, Show, Switch } from "solid-js";
+import {
+ createEffect,
+ createMemo,
+ createResource,
+ createSignal,
+ For,
+ Match,
+ Show,
+ Switch
+} from "solid-js";
import {
ActivityDetailsModal,
@@ -16,6 +25,7 @@ import { PrivacyLevel } from "~/routes";
import { useMegaStore } from "~/state/megaStore";
import {
actuallyFetchNostrProfile,
+ createDeepSignal,
hexpubFromNpub,
profileToPseudoContact,
PseudoContact,
@@ -41,6 +51,21 @@ export interface IActivityItem {
privacy_level: PrivacyLevel;
}
+async function fetchContactForNpub(
+ npub: string
+): Promise {
+ const hexpub = await hexpubFromNpub(npub);
+ if (!hexpub) {
+ return undefined;
+ }
+ const profile = await actuallyFetchNostrProfile(hexpub);
+ if (!profile) {
+ return undefined;
+ }
+ const pseudoContact = profileToPseudoContact(profile);
+ return pseudoContact;
+}
+
export function UnifiedActivityItem(props: {
item: IActivityItem;
onClick: (id: string, kind: HackActivityType) => void;
@@ -55,12 +80,16 @@ export function UnifiedActivityItem(props: {
);
};
- const primaryContact = () => {
+ const primaryContact = createMemo(() => {
if (props.item.contacts.length === 0) {
return undefined;
}
return props.item.contacts[0];
- };
+ });
+
+ const getContact = cache(async (npub) => {
+ return await fetchContactForNpub(npub);
+ }, "profile");
const profileFromNostr = createAsync(async () => {
if (props.item.contacts.length === 0) {
@@ -70,16 +99,8 @@ export function UnifiedActivityItem(props: {
);
if (npub) {
try {
- const hexpub = await hexpubFromNpub(npub);
- if (!hexpub) {
- return undefined;
- }
- const profile = await actuallyFetchNostrProfile(hexpub);
- if (!profile) {
- return undefined;
- }
- const pseudoContact = profileToPseudoContact(profile);
- return pseudoContact;
+ const newContact = await getContact(npub);
+ return newContact;
} catch (e) {
console.error(e);
}
@@ -295,26 +316,32 @@ export function CombinedActivity() {
setDetailsOpen(true);
}
- const getActivity = cache(async () => {
+ async function getActivity() {
try {
console.log("refetching activity");
const activity = await state.mutiny_wallet?.get_activity(
50,
undefined
);
- return (activity || []) as IActivityItem[];
+
+ if (!activity) return [];
+
+ return activity as IActivityItem[];
} catch (e) {
console.error(e);
return [] as IActivityItem[];
}
- }, "activity");
+ }
- const activity = createAsync(() => getActivity(), { initialValue: [] });
+ const [activity, { refetch }] = createResource(getActivity, {
+ initialValue: [],
+ storage: createDeepSignal
+ });
createEffect(() => {
// Should re-run after every sync
if (!state.is_syncing) {
- revalidate("activity");
+ refetch();
}
});
From 115f11aa6cc449a25beccff6a675cd71873c5c01 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Wed, 10 Apr 2024 16:07:06 -0500
Subject: [PATCH 04/20] use suspense for loading items
---
src/components/Activity.tsx | 107 +++++++++++++++++++++++-------------
1 file changed, 68 insertions(+), 39 deletions(-)
diff --git a/src/components/Activity.tsx b/src/components/Activity.tsx
index a2c9b322..d0b9d313 100644
--- a/src/components/Activity.tsx
+++ b/src/components/Activity.tsx
@@ -9,6 +9,7 @@ import {
For,
Match,
Show,
+ Suspense,
Switch
} from "solid-js";
@@ -98,6 +99,7 @@ export function UnifiedActivityItem(props: {
l.startsWith("npub")
);
if (npub) {
+ await new Promise((r) => setTimeout(r, 1000));
try {
const newContact = await getContact(npub);
return newContact;
@@ -185,43 +187,70 @@ export function UnifiedActivityItem(props: {
return (
-
}
- icon={shouldShowShuffle() ? : undefined}
- primaryOnClick={() =>
- primaryContact()?.id
- ? navigate(`/chat/${primaryContact()?.id}`)
- : profileFromNostr()
- ? props.onNewContactClick(profileFromNostr()!)
- : undefined
- }
- amountOnClick={click}
- primaryName={
- props.item.inbound
- ? primaryContact()?.name
- ? primaryContact()!.name
- : profileFromNostr()?.name || "Unknown"
- : "You"
- }
- genericAvatar={shouldShowGeneric()}
- verb={verb()}
- message={message()}
- secondaryName={secondaryName()}
- amount={
- props.item.amount_sats
- ? BigInt(props.item.amount_sats || 0)
- : undefined
- }
- date={timeAgo(props.item.last_updated)}
- accent={props.item.inbound ? "green" : undefined}
- visibility={
- props.item.privacy_level === "Public" ? "public" : "private"
- }
- />
+ >
+ : undefined}
+ primaryOnClick={() =>
+ primaryContact()?.id
+ ? navigate(`/chat/${primaryContact()?.id}`)
+ : profileFromNostr()
+ ? props.onNewContactClick(profileFromNostr()!)
+ : undefined
+ }
+ amountOnClick={click}
+ primaryName={
+ props.item.inbound
+ ? primaryContact()?.name
+ ? primaryContact()!.name
+ : profileFromNostr()?.name || "Unknown"
+ : "You"
+ }
+ genericAvatar={shouldShowGeneric()}
+ verb={verb()}
+ message={message()}
+ secondaryName={secondaryName()}
+ amount={
+ props.item.amount_sats
+ ? BigInt(props.item.amount_sats || 0)
+ : undefined
+ }
+ date={timeAgo(props.item.last_updated)}
+ accent={props.item.inbound ? "green" : undefined}
+ visibility={
+ props.item.privacy_level === "Public"
+ ? "public"
+ : "private"
+ }
+ />
+
);
}
@@ -364,7 +393,7 @@ export function CombinedActivity() {
/>
-
+
navigate("/settings/federations")}
@@ -398,7 +427,7 @@ export function CombinedActivity() {
- = 0}>
+ = 0}>
navigate("/settings/backup")}
@@ -410,7 +439,7 @@ export function CombinedActivity() {
-
+
{(activityItem) => (
Date: Thu, 28 Mar 2024 18:00:06 -0500
Subject: [PATCH 05/20] Change nostr keys on the fly
---
src/components/ImportNsecForm.tsx | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/components/ImportNsecForm.tsx b/src/components/ImportNsecForm.tsx
index c2a4da4c..c8c3c344 100644
--- a/src/components/ImportNsecForm.tsx
+++ b/src/components/ImportNsecForm.tsx
@@ -1,10 +1,14 @@
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
+import { useNavigate } from "@solidjs/router";
import { SecureStoragePlugin } from "capacitor-secure-storage-plugin";
import { createSignal, Show } from "solid-js";
import { Button, InfoBox, SimpleInput } from "~/components";
+import { useMegaStore } from "~/state/megaStore";
export function ImportNsecForm() {
+ const [state, _actions] = useMegaStore();
+ const navigate = useNavigate();
const [nsec, setNsec] = createSignal("");
const [saving, setSaving] = createSignal(false);
const [error, setError] = createSignal();
@@ -19,8 +23,13 @@ export function ImportNsecForm() {
throw new Error("Invalid nsec");
}
await SecureStoragePlugin.set({ key: "nsec", value: trimmedNsec });
- // TODO: right now we need a reload to set the nsec
- window.location.href = "/";
+
+ const new_npub = await state.mutiny_wallet?.change_nostr_keys(
+ trimmedNsec,
+ undefined
+ );
+ console.log("Changed to new npub: ", new_npub);
+ navigate("/");
} catch (e) {
console.error(e);
setError("Invalid nsec");
From 936f66f454f3b7468dac8bcafeea9d368e95c14f Mon Sep 17 00:00:00 2001
From: benthecarman
Date: Wed, 10 Apr 2024 16:45:45 -0500
Subject: [PATCH 06/20] Skip setup is flag set
---
src/logic/mutinyWalletSetup.ts | 2 +-
src/state/megaStore.tsx | 14 +++++++++++++-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/logic/mutinyWalletSetup.ts b/src/logic/mutinyWalletSetup.ts
index 079cf7ab..c9c76675 100644
--- a/src/logic/mutinyWalletSetup.ts
+++ b/src/logic/mutinyWalletSetup.ts
@@ -321,7 +321,7 @@ export async function setupMutinyWallet(
network,
esplora,
rgs,
- lsp,
+ shouldUseLSPS ? undefined : lsp,
shouldUseLSPS ? lsps_connection_string : undefined,
shouldUseLSPS ? lsps_token : undefined,
auth,
diff --git a/src/state/megaStore.tsx b/src/state/megaStore.tsx
index 8c441266..0d7dda32 100644
--- a/src/state/megaStore.tsx
+++ b/src/state/megaStore.tsx
@@ -22,6 +22,7 @@ import {
getSettings,
initializeWasm,
MutinyWalletSettingStrings,
+ setSettings,
setupMutinyWallet
} from "~/logic/mutinyWalletSetup";
import { ParsedParams, toParsedParams } from "~/logic/waila";
@@ -194,6 +195,15 @@ export const Provider: ParentComponent = (props) => {
const settings = await getSettings();
setState({ load_stage: "setup" });
+ // handle lsp settings
+ if (searchParams.lsps) {
+ settings.lsp = "";
+ settings.lsps_connection_string = searchParams.lsps;
+ settings.lsps_token = searchParams.token;
+
+ await setSettings(settings);
+ }
+
const mutinyWallet = await setupMutinyWallet(
settings,
password,
@@ -509,6 +519,8 @@ export const Provider: ParentComponent = (props) => {
};
}
+ const [params, _] = useSearchParams();
+
onMount(async () => {
await checkForExistingTab();
if (state.existing_tab_detected) {
@@ -528,7 +540,7 @@ export const Provider: ParentComponent = (props) => {
setState({ load_stage: "checking_for_existing_wallet" });
const existing = await MutinyWallet.has_node_manager();
- if (!existing) {
+ if (!existing && !params.skip_setup) {
navigate("/setup");
return;
}
From 11e0b8655b9a9fa701bf65bcb1b0e1d463bedfe1 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Thu, 11 Apr 2024 09:56:22 -0500
Subject: [PATCH 07/20] pick a federation on setup
---
e2e/utils.ts | 10 +-
public/i18n/en.json | 14 ++-
public/i18n/es.json | 4 +-
src/components/ImportNsecForm.tsx | 8 +-
src/components/layout/Button.tsx | 4 +-
src/router.tsx | 9 +-
src/routes/settings/ManageFederations.tsx | 138 +++++++++++++---------
src/routes/setup/AddFederation.tsx | 65 ++++++++++
src/routes/setup/NewProfile.tsx | 8 +-
src/routes/setup/index.ts | 1 +
10 files changed, 188 insertions(+), 73 deletions(-)
create mode 100644 src/routes/setup/AddFederation.tsx
diff --git a/e2e/utils.ts b/e2e/utils.ts
index d4cafd33..603fd2d6 100644
--- a/e2e/utils.ts
+++ b/e2e/utils.ts
@@ -13,10 +13,14 @@ export async function loadHome(page: Page) {
await page.locator("button:has-text('Skip for now')").click();
+ await page.getByText("Pick a Federation").waitFor();
+
+ await page.locator("button:has-text('Skip for now')").click();
+
+ await page.locator(`button:has-text('Confirm')`).click();
+
// Should have a balance up top now
- await page.locator(`text=0 sats`).first();
- // Status light should be ready
- await page.locator(`title="READY"`).first();
+ await page.locator(`text=0 sats`).first().waitFor();
}
export async function visitSettings(page: Page) {
diff --git a/public/i18n/en.json b/public/i18n/en.json
index c3ee1abf..d7235153 100644
--- a/public/i18n/en.json
+++ b/public/i18n/en.json
@@ -551,13 +551,14 @@
"remove": "Remove",
"expires": "Expires",
"federation_id": "Federation ID",
- "description": "Mutiny has experimental support for the Fedimint protocol. Store funds in a federation at your own risk!",
- "learn_more": "Learn more about Fedimint.",
+ "description": "Federations are bitcoin-based networks that make it cheaper, quicker, and easier to use bitcoin.",
+ "learn_more": "Learn more",
"discover": "Discover Federations",
"manual": "Invite Code",
"created_at": "Created At",
"recommended_by": "Recommended By",
- "already_in_fed": "You're already in a federation!"
+ "already_in_fed": "You're already in a federation!",
+ "descriptionpart2": "Each one is ran by a group of different inviduals or companies. Discover one that you or your friends might trust below."
},
"gift": {
"give_sats_link": "Give sats as a gift",
@@ -743,13 +744,18 @@
},
"setup": {
"new_profile": {
- "description": "Mutiny makes payments social."
+ "description": "Mutiny makes payments social.",
+ "title": "Create your profile"
},
"skip": "Skip for now",
"import_profile": "Import existing nostr profile",
"import": {
"title": "Import nostr profile",
"description": "Login with an existing nostr account."
+ },
+ "federation": {
+ "pick": "Pick a federation",
+ "skip_confirm": "You'll need to pay chain and channel fees to use Mutiny, and miss out on advanced features such as lightning address. You can change your mind later in the settings."
}
}
}
diff --git a/public/i18n/es.json b/public/i18n/es.json
index 25e4e417..05e39539 100644
--- a/public/i18n/es.json
+++ b/public/i18n/es.json
@@ -495,8 +495,8 @@
"remove": "Eliminar",
"expires": "Expira",
"federation_id": "ID federación",
- "description": "Mutiny tiene soporte experimental para el protocolo Fedimint. ¡Almacene fondos en una federación bajo su propio riesgo!",
- "learn_more": "Aprenda más sobre Fedimint.",
+ "description": "",
+ "learn_more": "Aprenda más",
"created_at": "Creado En",
"recommended_by": "Recomendado por"
},
diff --git a/src/components/ImportNsecForm.tsx b/src/components/ImportNsecForm.tsx
index c8c3c344..45a60e11 100644
--- a/src/components/ImportNsecForm.tsx
+++ b/src/components/ImportNsecForm.tsx
@@ -6,7 +6,7 @@ import { createSignal, Show } from "solid-js";
import { Button, InfoBox, SimpleInput } from "~/components";
import { useMegaStore } from "~/state/megaStore";
-export function ImportNsecForm() {
+export function ImportNsecForm(props: { setup?: boolean }) {
const [state, _actions] = useMegaStore();
const navigate = useNavigate();
const [nsec, setNsec] = createSignal("");
@@ -29,7 +29,11 @@ export function ImportNsecForm() {
undefined
);
console.log("Changed to new npub: ", new_npub);
- navigate("/");
+ if (props.setup) {
+ navigate("/addfederation");
+ } else {
+ navigate("/");
+ }
} catch (e) {
console.error(e);
setError("Invalid nsec");
diff --git a/src/components/layout/Button.tsx b/src/components/layout/Button.tsx
index c9627ba4..c7ffb213 100644
--- a/src/components/layout/Button.tsx
+++ b/src/components/layout/Button.tsx
@@ -32,8 +32,10 @@ export const Button: ParentComponent = (props) => {
+
diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx
index 23d0a964..244362a4 100644
--- a/src/routes/settings/ManageFederations.tsx
+++ b/src/routes/settings/ManageFederations.tsx
@@ -6,7 +6,7 @@ import {
SubmitHandler
} from "@modular-forms/solid";
import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm";
-import { A, useSearchParams } from "@solidjs/router";
+import { A, useNavigate, useSearchParams } from "@solidjs/router";
import { BadgeCheck, Scan } from "lucide-solid";
import {
createResource,
@@ -26,12 +26,13 @@ import {
Button,
ConfirmDialog,
DefaultMain,
+ ExternalLink,
FancyCard,
InfoBox,
KeyValue,
LabelCircle,
LargeHeader,
- LoadingSpinner,
+ LoadingShimmer,
MediumHeader,
MiniStringShower,
MutinyWalletGuard,
@@ -81,9 +82,13 @@ type RefetchType = (
| null
| undefined;
-function AddFederationForm(props: { refetch?: RefetchType }) {
+export function AddFederationForm(props: {
+ refetch?: RefetchType;
+ setup?: boolean;
+}) {
const i18n = useI18n();
const [state, actions] = useMegaStore();
+ const navigate = useNavigate();
const [error, setError] = createSignal();
const [success, setSuccess] = createSignal("");
@@ -162,6 +167,9 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
await props.refetch();
}
reset(feedbackForm);
+ if (props.setup) {
+ navigate("/");
+ }
} catch (e) {
console.error("Error submitting federation:", e);
setError(eify(e));
@@ -171,56 +179,61 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
return (
<>
-
- {i18n.t("settings.manage_federations.manual")}
-
-
+
+ {i18n.t("settings.manage_federations.discover")}
+
+
+
-
-
-
+
+
+
@@ -247,13 +260,17 @@ function AddFederationForm(props: { refetch?: RefetchType }) {
-
-
-
+
+
+
+
+
{" "}
- {/* */}
{i18n.t("settings.manage_federations.title")}
{i18n.t("settings.manage_federations.description")}{" "}
+
+ {i18n.t("settings.manage_federations.descriptionpart2")}{" "}
+
+
+
+ {i18n.t("settings.manage_federations.learn_more")}
+
+
diff --git a/src/routes/setup/AddFederation.tsx b/src/routes/setup/AddFederation.tsx
new file mode 100644
index 00000000..3e2460e7
--- /dev/null
+++ b/src/routes/setup/AddFederation.tsx
@@ -0,0 +1,65 @@
+import { useNavigate } from "@solidjs/router";
+import { createSignal, Suspense } from "solid-js";
+
+import {
+ Button,
+ ConfirmDialog,
+ DefaultMain,
+ ExternalLink,
+ MutinyWalletGuard,
+ VStack
+} from "~/components";
+import { useI18n } from "~/i18n/context";
+
+import { AddFederationForm } from "../settings";
+
+export function AddFederation() {
+ const i18n = useI18n();
+ const navigate = useNavigate();
+
+ const [confirmOpen, setConfirmOpen] = createSignal(false);
+
+ async function handleSkip() {
+ navigate("/");
+ }
+
+ return (
+
+
+
+
+ {i18n.t("setup.federation.pick")}
+
+
+ {i18n.t("settings.manage_federations.description")}
+
+
+ {i18n.t("settings.manage_federations.descriptionpart2")}
+
+
+
setConfirmOpen(true)} intent="text">
+ {i18n.t("setup.skip")}
+
+
setConfirmOpen(false)}
+ >
+ {i18n.t("setup.federation.skip_confirm")}
+
+
+
+
+
+
+
+
+ {i18n.t("settings.manage_federations.learn_more")}
+
+
+
+
+
+ );
+}
diff --git a/src/routes/setup/NewProfile.tsx b/src/routes/setup/NewProfile.tsx
index 3850ec7c..7c554a4c 100644
--- a/src/routes/setup/NewProfile.tsx
+++ b/src/routes/setup/NewProfile.tsx
@@ -31,7 +31,7 @@ export function NewProfile() {
);
console.log("profile", profile);
localStorage.setItem("profile_setup_stage", "skipped");
- navigate("/");
+ navigate("/addfederation");
setSkipping(false);
}
@@ -46,7 +46,7 @@ export function NewProfile() {
);
console.log("profile", profile);
localStorage.setItem("profile_setup_stage", "saved");
- navigate("/");
+ navigate("/addfederation");
} catch (e) {
console.error(e);
}
@@ -57,7 +57,9 @@ export function NewProfile() {
-
Create your profile
+
+ {i18n.t("setup.new_profile.title")}
+
{i18n.t("setup.new_profile.description")}
diff --git a/src/routes/setup/index.ts b/src/routes/setup/index.ts
index 577594d3..81866c13 100644
--- a/src/routes/setup/index.ts
+++ b/src/routes/setup/index.ts
@@ -2,3 +2,4 @@ export * from "./Restore";
export * from "./ImportProfile";
export * from "./NewProfile";
export * from "./Root";
+export * from "./AddFederation";
From 99f461c99e2dafe2aa52c88045356455bddb3136 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 10:52:59 -0500
Subject: [PATCH 08/20] default to private zap
---
src/routes/Send.tsx | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/routes/Send.tsx b/src/routes/Send.tsx
index 94dab36f..28c0ebab 100644
--- a/src/routes/Send.tsx
+++ b/src/routes/Send.tsx
@@ -647,6 +647,11 @@ export function Send() {
const [visibility, setVisibility] =
createSignal("Not Available");
+ // If the contact has an npub set the default visibility to private zap
+ createEffect(() => {
+ contact()?.npub && setVisibility("Private");
+ });
+
function toggleVisibility() {
if (visibility() === "Not Available") {
setVisibility("Private");
From 2ce63c8a6e9d8d0c83cc3bcbc962fb1e6c1c06de Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 14:16:10 -0500
Subject: [PATCH 09/20] fix style typo
---
src/components/layout/Misc.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/layout/Misc.tsx b/src/components/layout/Misc.tsx
index 1a260e73..59e5bb79 100644
--- a/src/components/layout/Misc.tsx
+++ b/src/components/layout/Misc.tsx
@@ -138,7 +138,7 @@ export const DefaultMain = (props: { children?: JSX.Element }) => {
<>
{/* blur content that goes under the notification bar */}
{props.children}
From 2f027bc82eeca513981e7de05519724a5938be7e Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 14:12:00 -0500
Subject: [PATCH 10/20] allow text selection in dms
---
src/routes/Chat.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/routes/Chat.tsx b/src/routes/Chat.tsx
index 1af48816..1576c21e 100644
--- a/src/routes/Chat.tsx
+++ b/src/routes/Chat.tsx
@@ -179,7 +179,9 @@ function SingleMessage(props: {
- {props.dm.message}
+
+ {props.dm.message}
+
Date: Wed, 10 Apr 2024 19:10:31 -0500
Subject: [PATCH 11/20] switch to setup_new_profile
---
src/routes/setup/NewProfile.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/routes/setup/NewProfile.tsx b/src/routes/setup/NewProfile.tsx
index 7c554a4c..dfdec0fd 100644
--- a/src/routes/setup/NewProfile.tsx
+++ b/src/routes/setup/NewProfile.tsx
@@ -23,7 +23,7 @@ export function NewProfile() {
async function handleSkip() {
setSkipping(true);
// set up an empty profile so we at least have some kind0 event
- const profile = await state.mutiny_wallet?.edit_nostr_profile(
+ const profile = await state.mutiny_wallet?.setup_new_profile(
DEFAULT_NOSTR_NAME,
undefined,
undefined,
@@ -38,8 +38,8 @@ export function NewProfile() {
async function createProfile(p: EditableProfile) {
setCreating(true);
try {
- const profile = await state.mutiny_wallet?.edit_nostr_profile(
- p.nym ? p.nym : undefined,
+ const profile = await state.mutiny_wallet?.setup_new_profile(
+ p.nym ? p.nym : DEFAULT_NOSTR_NAME,
p.imageUrl ? p.imageUrl : undefined,
p.lightningAddress ? p.lightningAddress : undefined,
undefined
From 67340ef731dc73b2c4fbc1408d0625d0880eba42 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 14:05:25 -0500
Subject: [PATCH 12/20] bump to 0.6.4
---
android/app/build.gradle | 4 ++--
ios/App/App.xcodeproj/project.pbxproj | 4 ++--
package.json | 4 ++--
pnpm-lock.yaml | 9 ++++-----
4 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index aac04388..0f5dba04 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId "com.mutinywallet.mutinywallet"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 55
- versionName "0.6.3"
+ versionCode 56
+ versionName "0.6.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj
index c048ffab..2a5edffb 100644
--- a/ios/App/App.xcodeproj/project.pbxproj
+++ b/ios/App/App.xcodeproj/project.pbxproj
@@ -360,7 +360,7 @@
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- MARKETING_VERSION = 1.6.3;
+ MARKETING_VERSION = 1.6.4;
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = com.mutinywallet.mutiny;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -387,7 +387,7 @@
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.finance";
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- MARKETING_VERSION = 1.6.3;
+ MARKETING_VERSION = 1.6.4;
PRODUCT_BUNDLE_IDENTIFIER = com.mutinywallet.mutiny;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/package.json b/package.json
index efb02a13..190083d1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mutiny-wallet",
- "version": "0.6.3",
+ "version": "0.6.4",
"license": "MIT",
"packageManager": "pnpm@8.6.6",
"scripts": {
@@ -54,7 +54,7 @@
"@capacitor/toast": "^5.0.6",
"@kobalte/core": "^0.12.6",
"@kobalte/tailwindcss": "^0.9.0",
- "@mutinywallet/mutiny-wasm": "0.6.3",
+ "@mutinywallet/mutiny-wasm": "0.6.4",
"@modular-forms/solid": "^0.20.0",
"@solid-primitives/upload": "^0.0.117",
"@solidjs/meta": "^0.29.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f3353e32..edf1ce95 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -51,8 +51,8 @@ dependencies:
specifier: ^0.20.0
version: 0.20.0(solid-js@1.8.16)
'@mutinywallet/mutiny-wasm':
- specifier: 0.6.3
- version: 0.6.3
+ specifier: 0.6.4
+ version: 0.6.4
'@solid-primitives/upload':
specifier: ^0.0.117
version: 0.0.117(solid-js@1.8.16)
@@ -2085,8 +2085,8 @@ packages:
solid-js: 1.8.16
dev: false
- /@mutinywallet/mutiny-wasm@0.6.3:
- resolution: {integrity: sha512-mHcOoawa2HyYL1ssA0aOGN1IUVFmitiioe6XiwQiBPFtW3vE7Zg824xBZYPKnlf4jqdK1MSyRGaFoSPfe5QqCQ==}
+ /@mutinywallet/mutiny-wasm@0.6.4:
+ resolution: {integrity: sha512-fwHLZDdCAMkMv2sqipZ+77GZb2frNWUxeVpKDzUUvY42tf4hQtoWxGA6e7eo3tesD+NcdlDQojPilXWTAHBVOQ==}
dev: false
/@nodelib/fs.scandir@2.1.5:
@@ -7567,7 +7567,6 @@ packages:
/workbox-google-analytics@7.0.0:
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
- deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
dependencies:
workbox-background-sync: 7.0.0
workbox-core: 7.0.0
From ba062d5cd25726dfb0b1f88f898f4b3b758eb2b4 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 11:42:30 -0500
Subject: [PATCH 13/20] invite codes and list federations even if you're in one
---
public/i18n/en.json | 3 +-
src/components/FederationInviteShower.tsx | 55 +++++++++++++++++++++++
src/components/index.ts | 1 +
src/routes/settings/ManageFederations.tsx | 52 ++++++++++++---------
4 files changed, 89 insertions(+), 22 deletions(-)
create mode 100644 src/components/FederationInviteShower.tsx
diff --git a/public/i18n/en.json b/public/i18n/en.json
index d7235153..977e8106 100644
--- a/public/i18n/en.json
+++ b/public/i18n/en.json
@@ -558,7 +558,8 @@
"created_at": "Created At",
"recommended_by": "Recommended By",
"already_in_fed": "You're already in a federation!",
- "descriptionpart2": "Each one is ran by a group of different inviduals or companies. Discover one that you or your friends might trust below."
+ "descriptionpart2": "Each one is ran by a group of different inviduals or companies. Discover one that you or your friends might trust below.",
+ "join_me": "Join me"
},
"gift": {
"give_sats_link": "Give sats as a gift",
diff --git a/src/components/FederationInviteShower.tsx b/src/components/FederationInviteShower.tsx
new file mode 100644
index 00000000..12cb1e16
--- /dev/null
+++ b/src/components/FederationInviteShower.tsx
@@ -0,0 +1,55 @@
+import { Copy, QrCode } from "lucide-solid";
+import { createSignal, Show } from "solid-js";
+import { QRCodeSVG } from "solid-qr-code";
+
+import { SimpleDialog } from "~/components";
+import { useI18n } from "~/i18n/context";
+import { useCopy } from "~/utils";
+
+export function FederationInviteShower(props: {
+ name?: string;
+ inviteCode: string;
+}) {
+ const i18n = useI18n();
+ const [showQr, setShowQr] = createSignal(false);
+
+ const [copy, copied] = useCopy({ copiedTimeout: 1000 });
+
+ return (
+ <>
+
+ setShowQr(true)}>
+
+
+ copy(props.inviteCode)}
+ >
+
+
+
{" "}
+ {
+ setShowQr(open);
+ }}
+ title={i18n.t("settings.manage_federations.join_me")}
+ >
+
+
+ {props.name}
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/index.ts b/src/components/index.ts
index ab5ed260..b2c9e40e 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -57,3 +57,4 @@ export * from "./HomeBalance";
export * from "./EditProfileForm";
export * from "./ImportNsecForm";
export * from "./LightningAddressShower";
+export * from "./FederationInviteShower";
diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx
index 244362a4..b665f7a7 100644
--- a/src/routes/settings/ManageFederations.tsx
+++ b/src/routes/settings/ManageFederations.tsx
@@ -18,7 +18,6 @@ import {
Suspense,
Switch
} from "solid-js";
-import { QRCodeSVG } from "solid-qr-code";
import {
AmountSats,
@@ -28,6 +27,7 @@ import {
DefaultMain,
ExternalLink,
FancyCard,
+ FederationInviteShower,
InfoBox,
KeyValue,
LabelCircle,
@@ -85,6 +85,7 @@ type RefetchType = (
export function AddFederationForm(props: {
refetch?: RefetchType;
setup?: boolean;
+ browseOnly?: boolean;
}) {
const i18n = useI18n();
const [state, actions] = useMegaStore();
@@ -179,7 +180,7 @@ export function AddFederationForm(props: {
return (
<>
-
+
{i18n.t("settings.manage_federations.manual")}
@@ -223,6 +224,8 @@ export function AddFederationForm(props: {
+
+
{i18n.t("settings.manage_federations.discover")}
@@ -314,19 +317,21 @@ export function AddFederationForm(props: {
-
- onSelect(fed.invite_codes)
- }
- loading={fed.invite_codes.includes(
- loadingFederation()
- )}
- >
- {i18n.t(
- "settings.manage_federations.add"
- )}
-
+
+
+ onSelect(fed.invite_codes)
+ }
+ loading={fed.invite_codes.includes(
+ loadingFederation()
+ )}
+ >
+ {i18n.t(
+ "settings.manage_federations.add"
+ )}
+
+
)}
@@ -460,15 +465,15 @@ function FederationListItem(props: {
>
+
+
+
-
-
-
{i18n.t("settings.manage_federations.remove")}
@@ -580,6 +585,11 @@ export function ManageFederations() {
+
+
+
+
+
From 7480461ac286adbc979bc3c7e8d5eeebb36e8a84 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Thu, 11 Apr 2024 10:32:42 -0500
Subject: [PATCH 14/20] don't warn about 100k if using LSPS
---
src/components/ReceiveWarnings.tsx | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/components/ReceiveWarnings.tsx b/src/components/ReceiveWarnings.tsx
index 746051f1..3ba75d40 100644
--- a/src/components/ReceiveWarnings.tsx
+++ b/src/components/ReceiveWarnings.tsx
@@ -32,7 +32,10 @@ export function ReceiveWarnings(props: {
if (state.federations?.length !== 0 && props.from_fedi_to_ln !== true) {
return undefined;
}
- if ((state.balance?.lightning || 0n) === 0n) {
+ if (
+ (state.balance?.lightning || 0n) === 0n &&
+ !state.settings?.lsps_connection_string
+ ) {
return i18n.t("receive.amount_editable.receive_too_small", {
amount: "100,000"
});
From b00d6340667384f462513be4005d0fc1052fc42f Mon Sep 17 00:00:00 2001
From: benthecarman
Date: Wed, 10 Apr 2024 12:50:03 -0500
Subject: [PATCH 15/20] Unrecommend federations
---
src/routes/settings/ManageFederations.tsx | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx
index b665f7a7..1deeb741 100644
--- a/src/routes/settings/ManageFederations.tsx
+++ b/src/routes/settings/ManageFederations.tsx
@@ -378,6 +378,20 @@ function RecommendButton(props: { fed: MutinyFederationIdentity }) {
setRecommendLoading(false);
}
+ async function deleteRecommendation() {
+ setRecommendLoading(true);
+ try {
+ await state.mutiny_wallet?.delete_federation_recommendation(
+ props.fed.federation_id
+ );
+ setRecommended(false);
+ refetch();
+ } catch (e) {
+ console.error("Error deleting federation recommendation: ", e);
+ }
+ setRecommendLoading(false);
+ }
+
return (
@@ -385,6 +399,13 @@ function RecommendButton(props: { fed: MutinyFederationIdentity }) {
Recommended by you
+
+ Unrecommend
+
Date: Fri, 12 Apr 2024 16:02:41 -0500
Subject: [PATCH 16/20] styling for unrecommend
---
public/i18n/en.json | 6 ++--
src/components/layout/LoadingSpinner.tsx | 4 ++-
src/components/layout/SubtleButton.tsx | 35 +++++++++++++++++++
src/components/layout/index.ts | 1 +
src/routes/settings/ManageFederations.tsx | 42 +++++++++++++----------
5 files changed, 67 insertions(+), 21 deletions(-)
create mode 100644 src/components/layout/SubtleButton.tsx
diff --git a/public/i18n/en.json b/public/i18n/en.json
index 977e8106..1b2305a4 100644
--- a/public/i18n/en.json
+++ b/public/i18n/en.json
@@ -548,7 +548,7 @@
"federation_added_success": "Federation added successfully",
"federation_remove_confirm": "Are you sure you want to remove this federation? Make sure any funds you have are transferred to your lightning balance or another wallet first.",
"add": "Add",
- "remove": "Remove",
+ "remove": "Leave federation",
"expires": "Expires",
"federation_id": "Federation ID",
"description": "Federations are bitcoin-based networks that make it cheaper, quicker, and easier to use bitcoin.",
@@ -559,7 +559,9 @@
"recommended_by": "Recommended By",
"already_in_fed": "You're already in a federation!",
"descriptionpart2": "Each one is ran by a group of different inviduals or companies. Discover one that you or your friends might trust below.",
- "join_me": "Join me"
+ "join_me": "Join me",
+ "recommend": "Recommend federation",
+ "recommended_by_you": "Recommended by you"
},
"gift": {
"give_sats_link": "Give sats as a gift",
diff --git a/src/components/layout/LoadingSpinner.tsx b/src/components/layout/LoadingSpinner.tsx
index 560a9d88..5dda899c 100644
--- a/src/components/layout/LoadingSpinner.tsx
+++ b/src/components/layout/LoadingSpinner.tsx
@@ -2,13 +2,15 @@ export const LoadingSpinner = (props: {
big?: boolean;
wide?: boolean;
small?: boolean;
+ smallest?: boolean;
}) => {
return (
void;
+ loading?: boolean;
+ disabled?: boolean;
+ intent?: "red" | "green" | "blue";
+ type?: "button" | "submit";
+}) {
+ return (
+
props.onClick && props.onClick()}
+ disabled={props.loading || props.disabled}
+ class="flex items-center justify-center gap-2 rounded-xl border border-white/10 bg-neutral-900 p-2 no-underline active:-mb-[1px] active:mt-[1px] active:opacity-70"
+ classList={{
+ "text-m-grey-350": !props.intent,
+ "text-m-red": props.intent === "red",
+ "text-m-green": props.intent === "green",
+ "text-m-blue": props.intent === "blue"
+ }}
+ >
+
+ {/* Loading spinner has a weird padding on it */}
+
+
+
+
+ {props.children}
+
+ );
+}
diff --git a/src/components/layout/index.ts b/src/components/layout/index.ts
index 739257d4..55d58f7a 100644
--- a/src/components/layout/index.ts
+++ b/src/components/layout/index.ts
@@ -6,3 +6,4 @@ export * from "./Radio";
export * from "./TextField";
export * from "./ExternalLink";
export * from "./LoadingSpinner";
+export * from "./SubtleButton";
diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx
index 1deeb741..7ef73d0f 100644
--- a/src/routes/settings/ManageFederations.tsx
+++ b/src/routes/settings/ManageFederations.tsx
@@ -7,7 +7,7 @@ import {
} from "@modular-forms/solid";
import { FederationBalance, TagItem } from "@mutinywallet/mutiny-wasm";
import { A, useNavigate, useSearchParams } from "@solidjs/router";
-import { BadgeCheck, Scan } from "lucide-solid";
+import { BadgeCheck, LogOut, Scan, Trash } from "lucide-solid";
import {
createResource,
createSignal,
@@ -39,6 +39,7 @@ import {
NavBar,
NiceP,
showToast,
+ SubtleButton,
TextField,
VStack
} from "~/components";
@@ -345,6 +346,7 @@ export function AddFederationForm(props: {
function RecommendButton(props: { fed: MutinyFederationIdentity }) {
const [state] = useMegaStore();
+ const i18n = useI18n();
const [recommendLoading, setRecommendLoading] = createSignal(false);
// This is just some local state that makes it feel like they've recommended it
// even if they aren't a "real person"
@@ -395,26 +397,29 @@ function RecommendButton(props: { fed: MutinyFederationIdentity }) {
return (
-
-
- Recommended by you
-
-
- Unrecommend
-
+
+
+
+ {i18n.t(
+ "settings.manage_federations.recommended_by_you"
+ )}
+
+
+
+
+
-
- Recommend
-
+
+ {i18n.t("settings.manage_federations.recommend")}
+
);
@@ -495,9 +500,10 @@ function FederationListItem(props: {
-
+
+
{i18n.t("settings.manage_federations.remove")}
-
+
Date: Fri, 12 Apr 2024 14:55:15 -0500
Subject: [PATCH 17/20] handle invoices inside of message
---
src/routes/Chat.tsx | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/routes/Chat.tsx b/src/routes/Chat.tsx
index 1576c21e..aab1b87a 100644
--- a/src/routes/Chat.tsx
+++ b/src/routes/Chat.tsx
@@ -76,9 +76,20 @@ function SingleMessage(props: {
const parsed = createAsync(
async () => {
- const result = toParsedParams(props.dm.message, network);
+ let result = undefined;
+
+ // Look for a long word that might be an invoice
+ const split_message_by_whitespace = props.dm.message.split(/\s+/g);
+ for (const word of split_message_by_whitespace) {
+ if (word.length > 15) {
+ result = toParsedParams(word, network);
+ if (result.ok) {
+ break;
+ }
+ }
+ }
- if (!result.ok) {
+ if (!result || !result.ok) {
return undefined;
}
@@ -92,6 +103,10 @@ function SingleMessage(props: {
return {
type: "invoice",
status: "paid",
+ message_without_invoice: props.dm.message.replace(
+ result.value.original,
+ ""
+ ),
value: result.value.invoice,
amount: result.value.amount_sats
};
@@ -103,6 +118,10 @@ function SingleMessage(props: {
return {
type: "invoice",
status: "unpaid",
+ message_without_invoice: props.dm.message.replace(
+ result.value.original,
+ ""
+ ),
from: props.dm.from,
value: result.value.invoice,
amount: result.value.amount_sats
@@ -130,9 +149,9 @@ function SingleMessage(props: {
navWithContactId();
}
- function handlePay() {
+ function handlePay(invoice: string) {
actions.handleIncomingString(
- props.dm.message,
+ invoice,
(error) => {
showToast(error);
},
@@ -153,6 +172,11 @@ function SingleMessage(props: {
+
+
+ {parsed()?.message_without_invoice}
+
+
Lightning Invoice
@@ -167,7 +191,7 @@ function SingleMessage(props: {
handlePay(parsed()?.value || "")}
>
Pay
From e137e5eccdf22f745309bb60763d8306888658e6 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 16:45:41 -0500
Subject: [PATCH 18/20] fix private zap button logic
---
src/routes/Send.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/routes/Send.tsx b/src/routes/Send.tsx
index 28c0ebab..e73f4c43 100644
--- a/src/routes/Send.tsx
+++ b/src/routes/Send.tsx
@@ -647,9 +647,9 @@ export function Send() {
const [visibility, setVisibility] =
createSignal("Not Available");
- // If the contact has an npub set the default visibility to private zap
+ // If the contact has an npub and it's an lnurlp send set the default visibility to private zap
createEffect(() => {
- contact()?.npub && setVisibility("Private");
+ contact()?.npub && lnurlp() && setVisibility("Private");
});
function toggleVisibility() {
From 437adf7e73bf51e5b3f0661e394f37fd4345ca06 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 16:53:39 -0500
Subject: [PATCH 19/20] just commands for switching network
---
justfile | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/justfile b/justfile
index 70615194..efb2462f 100644
--- a/justfile
+++ b/justfile
@@ -20,3 +20,9 @@ test:
test-ui:
pnpm exec playwright test --ui
+
+mainnet:
+ cp .env.mainnet .env.local
+
+signet:
+ cp .env.signet .env.local
From 15926619c7804ff2241d6af00713a1f670ff6a03 Mon Sep 17 00:00:00 2001
From: Paul Miller
Date: Fri, 12 Apr 2024 18:31:34 -0500
Subject: [PATCH 20/20] fix width overflow for federation list
---
src/routes/settings/ManageFederations.tsx | 4 ++--
src/routes/setup/AddFederation.tsx | 8 +++-----
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/routes/settings/ManageFederations.tsx b/src/routes/settings/ManageFederations.tsx
index 7ef73d0f..cf3133ec 100644
--- a/src/routes/settings/ManageFederations.tsx
+++ b/src/routes/settings/ManageFederations.tsx
@@ -180,7 +180,7 @@ export function AddFederationForm(props: {
};
return (
- <>
+
{i18n.t("settings.manage_federations.manual")}
@@ -340,7 +340,7 @@ export function AddFederationForm(props: {
- >
+
);
}
diff --git a/src/routes/setup/AddFederation.tsx b/src/routes/setup/AddFederation.tsx
index 3e2460e7..20867ae3 100644
--- a/src/routes/setup/AddFederation.tsx
+++ b/src/routes/setup/AddFederation.tsx
@@ -48,11 +48,9 @@ export function AddFederation() {
>
{i18n.t("setup.federation.skip_confirm")}
-
-
-
-
-
+
+
+
{i18n.t("settings.manage_federations.learn_more")}