This commit is contained in:
Paul Miller
2023-10-03 13:53:25 -05:00
committed by Tony Giorgio
parent 51dd99a62c
commit 85448fb7a5
4 changed files with 94 additions and 33 deletions

View File

@@ -465,13 +465,16 @@ export default {
already_claimed: "This gift has already been claimed",
sender_is_poor:
"The sender doesn't have enough balance to pay this gift.",
sender_timed_out:
"Gift payment timed out. The sender may be offline, or this gift has already been claimed.",
sender_generic_error: "Sender sent error: {{error}}",
receive_header: "You've been gifted some sats!",
receive_description:
"You must be pretty special. To claim your money just hit the big button. Funds will be added to your balance the next time your gifter is online.",
"You must be pretty special. To claim your money just hit the big button. Funds will be added to this wallet the next time your gifter is online.",
receive_claimed:
"Gift claimed! You should see the gift hit your balance shortly.",
receive_cta: "Claim Gift",
receive_try_again: "Try Again",
send_header: "Create Gift",
send_explainer:
"Give the gift of sats. Create a Mutiny gift URL that can be claimed by anyone with a web browser.",
@@ -489,6 +492,8 @@ export default {
send_delete_button: "Delete Gift",
send_delete_confirm:
"Are you sure you want to delete this gift? Is this your rugpull moment?",
send_tip:
"Your copy of Mutiny Wallet needs to be open for the gift to be redeemed.",
need_plus:
"Upgrade to Mutiny+ to enable gifting. Gifting allows you to create a Mutiny gift URL that can be claimed by anyone with a web browser."
}

View File

@@ -1,4 +1,12 @@
import { createResource, createSignal, Match, Show, Switch } from "solid-js";
import {
createMemo,
createResource,
createSignal,
Match,
Show,
Suspense,
Switch
} from "solid-js";
import { useSearchParams } from "solid-start";
import treasureClosed from "~/assets/treasure-closed.png";
@@ -6,6 +14,7 @@ import treasure from "~/assets/treasure.gif";
import {
AmountFiat,
AmountSats,
BackLink,
Button,
ButtonLink,
DefaultMain,
@@ -24,39 +33,37 @@ import { Network } from "~/logic/mutinyWalletSetup";
import { useMegaStore } from "~/state/megaStore";
import { eify } from "~/utils";
export default function GiftPage() {
function InboundWarning() {
const [state, _] = useMegaStore();
const i18n = useI18n();
const [claimSuccess, setClaimSuccess] = createSignal(false);
const [error, setError] = createSignal<Error>();
const [loading, setLoading] = createSignal(false);
const [searchParams] = useSearchParams();
const [inboundCapacity] = createResource(async () => {
try {
const channels = await state.mutiny_wallet?.list_channels();
let inbound = 0;
let inbound = 0n;
for (const channel of channels) {
inbound += channel.size - (channel.balance + channel.reserve);
inbound =
inbound +
BigInt(channel.size) -
BigInt(channel.balance + channel.reserve);
}
return inbound;
} catch (e) {
console.error(e);
return 0;
return 0n;
}
});
const warningText = () => {
const amount = Number(searchParams.amount);
if (isNaN(amount)) {
const warningText = createMemo(() => {
if (isNaN(Number(searchParams.amount))) {
return undefined;
}
const amount = BigInt(searchParams.amount);
const network = state.mutiny_wallet?.get_network() as Network;
const threshold = network === "bitcoin" ? 50000 : 10000;
@@ -68,12 +75,31 @@ export default function GiftPage() {
});
}
if (amount > (inboundCapacity() || 0)) {
if (inboundCapacity() && inboundCapacity()! > amount) {
return undefined;
} else {
return i18n.t("settings.gift.setup_fee_lightning");
}
});
return undefined;
};
return (
<Show when={warningText()}>
<InfoBox accent="blue">
{warningText()} <FeesModal />
</InfoBox>
</Show>
);
}
export default function GiftPage() {
const [state, _] = useMegaStore();
const i18n = useI18n();
const [claimSuccess, setClaimSuccess] = createSignal(false);
const [error, setError] = createSignal<Error>();
const [loading, setLoading] = createSignal(false);
const [searchParams] = useSearchParams();
async function claim() {
const amount = Number(searchParams.amount);
@@ -84,7 +110,6 @@ export default function GiftPage() {
BigInt(amount),
nwc
);
console.log("claim result", claimResult);
if (claimResult === "Already Claimed") {
throw new Error(i18n.t("settings.gift.already_claimed"));
}
@@ -105,16 +130,27 @@ export default function GiftPage() {
setClaimSuccess(true);
} catch (e) {
console.error(e);
setError(eify(e));
const err = eify(e);
if (err.message === "Payment timed out.") {
setError(new Error(i18n.t("settings.gift.sender_timed_out")));
} else {
setError(err);
}
} finally {
setLoading(false);
}
}
async function tryAgain() {
setError(undefined);
await claim();
}
return (
<MutinyWalletGuard>
<SafeArea>
<DefaultMain>
<BackLink />
<Show when={searchParams.nwc_uri && searchParams.amount}>
<VStack>
<FancyCard>
@@ -173,12 +209,10 @@ export default function GiftPage() {
"settings.gift.receive_description"
)}
</NiceP>
<Show
when={warningText() && !claimSuccess()}
>
<InfoBox accent="blue">
{warningText()} <FeesModal />
</InfoBox>
<Show when={!claimSuccess()}>
<Suspense>
<InboundWarning />
</Suspense>
</Show>
<Switch>
<Match when={error()}>
@@ -188,6 +222,15 @@ export default function GiftPage() {
<ButtonLink href="/" intent="red">
{i18n.t("common.dangit")}
</ButtonLink>
<Button
intent="inactive"
onClick={tryAgain}
loading={loading()}
>
{i18n.t(
"settings.gift.receive_try_again"
)}
</Button>
</Match>
<Match when={claimSuccess()}>
<InfoBox accent="green">

View File

@@ -55,7 +55,13 @@ export function SingleGift(props: {
const i18n = useI18n();
const [state, _actions] = useMegaStore();
const baseUrl = window.location.origin;
const network = state.mutiny_wallet?.get_network();
const baseUrl =
network === "bitcoin"
? "https://app.mutinywallet.com"
: "https://signet-app.mutinywallet.com";
const sharableUrl = () => baseUrl.concat(props.profile.url_suffix || "");
const amount = () => props.profile.budget_amount?.toString() || "0";
@@ -198,12 +204,15 @@ export default function GiftPage() {
return Number(getValue(giftForm, "amount")) < 50000;
};
const selfHosted = state.mutiny_wallet?.get_network() === "signet";
const canGift = state.mutiny_plus || selfHosted;
return (
<MutinyWalletGuard>
<SafeArea>
<DefaultMain>
<BackPop />
<Show when={!state.mutiny_plus}>
<Show when={!canGift}>
<VStack>
<LargeHeader>
{i18n.t("settings.gift.send_header")}
@@ -236,6 +245,9 @@ export default function GiftPage() {
"settings.gift.send_instructions"
)}
</NiceP>
<InfoBox accent="green">
{i18n.t("settings.gift.send_tip")}
</InfoBox>
<SingleGift
profile={freshProfile()!}
onDelete={resetGifting}
@@ -247,7 +259,7 @@ export default function GiftPage() {
</Button>
</VStack>
</Show>
<Show when={!giftResult() && state.mutiny_plus}>
<Show when={!giftResult() && canGift}>
<LargeHeader>
{i18n.t("settings.gift.send_header")}
</LargeHeader>

View File

@@ -72,13 +72,15 @@ export default function Settings() {
// @ts-ignore
const COMMIT_HASH = import.meta.env.__COMMIT_HASH__;
const selfHosted = state.settings?.selfhosted === "true";
return (
<SafeArea>
<DefaultMain>
<BackLink />
<LargeHeader>{i18n.t("settings.header")}</LargeHeader>
<VStack biggap>
<Show when={state.settings?.selfhosted !== "true"}>
<Show when={!selfHosted}>
<MutinyPlusCta />
</Show>
<SettingsLinkList
@@ -127,10 +129,9 @@ export default function Settings() {
},
{
href: "/settings/gift",
disabled: !state.mutiny_plus,
disabled: !(state.mutiny_plus || selfHosted),
text: i18n.t("settings.gift.title"),
caption: !state.mutiny_plus
caption: !(state.mutiny_plus || selfHosted)
? "Upgrade to Mutiny+ to enabled gifting"
: undefined
},