diff --git a/src/components/ImportNsecForm.tsx b/src/components/ImportNsecForm.tsx
index 45a60e1..e0041ae 100644
--- a/src/components/ImportNsecForm.tsx
+++ b/src/components/ImportNsecForm.tsx
@@ -1,4 +1,3 @@
-import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
import { useNavigate } from "@solidjs/router";
import { SecureStoragePlugin } from "capacitor-secure-storage-plugin";
import { createSignal, Show } from "solid-js";
@@ -7,7 +6,7 @@ import { Button, InfoBox, SimpleInput } from "~/components";
import { useMegaStore } from "~/state/megaStore";
export function ImportNsecForm(props: { setup?: boolean }) {
- const [state, _actions] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const navigate = useNavigate();
const [nsec, setNsec] = createSignal("");
const [saving, setSaving] = createSignal(false);
@@ -18,16 +17,13 @@ export function ImportNsecForm(props: { setup?: boolean }) {
setError(undefined);
const trimmedNsec = nsec().trim();
try {
- const npub = await MutinyWallet.nsec_to_npub(trimmedNsec);
+ const npub = await sw.nsec_to_npub(trimmedNsec);
if (!npub) {
throw new Error("Invalid nsec");
}
await SecureStoragePlugin.set({ key: "nsec", value: trimmedNsec });
- const new_npub = await state.mutiny_wallet?.change_nostr_keys(
- trimmedNsec,
- undefined
- );
+ const new_npub = await sw.change_nostr_keys(trimmedNsec, undefined);
console.log("Changed to new npub: ", new_npub);
if (props.setup) {
navigate("/addfederation");
diff --git a/src/components/KitchenSink.tsx b/src/components/KitchenSink.tsx
index 29ebe03..88833d6 100644
--- a/src/components/KitchenSink.tsx
+++ b/src/components/KitchenSink.tsx
@@ -43,13 +43,13 @@ type RefetchPeersType = (
function PeerItem(props: { peer: MutinyPeer; refetchPeers: RefetchPeersType }) {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const handleDisconnectPeer = async () => {
if (props.peer.is_connected) {
- await state.mutiny_wallet?.disconnect_peer(props.peer.pubkey);
+ await sw.disconnect_peer(props.peer.pubkey);
} else {
- await state.mutiny_wallet?.delete_peer(props.peer.pubkey);
+ await sw.delete_peer(props.peer.pubkey);
}
await props.refetchPeers();
};
@@ -82,12 +82,10 @@ function PeerItem(props: { peer: MutinyPeer; refetchPeers: RefetchPeersType }) {
function PeersList() {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const getPeers = async () => {
- return (await state.mutiny_wallet?.list_peers()) as Promise<
- MutinyPeer[]
- >;
+ return await sw.list_peers();
};
const [peers, { refetch }] = createResource(getPeers);
@@ -125,7 +123,7 @@ function PeersList() {
function ConnectPeer(props: { refetchPeers: RefetchPeersType }) {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const [value, setValue] = createSignal("");
@@ -134,7 +132,7 @@ function ConnectPeer(props: { refetchPeers: RefetchPeersType }) {
const peerConnectString = value().trim();
- await state.mutiny_wallet?.connect_to_peer(peerConnectString);
+ await sw.connect_to_peer(peerConnectString);
await props.refetchPeers();
@@ -176,7 +174,7 @@ type PendingChannelAction = "close" | "force_close" | "abandon";
function ChannelItem(props: { channel: MutinyChannel; network?: Network }) {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const [pendingChannelAction, setPendingChannelAction] =
createSignal
();
@@ -187,7 +185,7 @@ function ChannelItem(props: { channel: MutinyChannel; network?: Network }) {
if (!action) return;
setConfirmLoading(true);
try {
- await state.mutiny_wallet?.close_channel(
+ await sw.close_channel(
props.channel.outpoint as string,
action === "force_close",
action === "abandon"
@@ -279,17 +277,15 @@ function ChannelItem(props: { channel: MutinyChannel; network?: Network }) {
function ChannelsList() {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [state, _actions, sw] = useMegaStore();
const getChannels = async () => {
- return (await state.mutiny_wallet?.list_channels()) as Promise<
- MutinyChannel[]
- >;
+ return sw.list_channels();
};
const [channels, { refetch }] = createResource(getChannels);
- const network = state.mutiny_wallet?.get_network() as Network;
+ const network = state.network;
return (
<>
@@ -329,7 +325,7 @@ function ChannelsList() {
function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [state, _actions, sw] = useMegaStore();
const [creationError, setCreationError] = createSignal();
@@ -347,11 +343,11 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
try {
const pubkey = peerPubkey().trim();
const bigAmount = BigInt(amount());
+ console.log("pubkey", pubkey);
+ console.log("bigAmount", bigAmount);
- const new_channel = await state.mutiny_wallet?.open_channel(
- pubkey,
- bigAmount
- );
+ const new_channel = await sw.open_channel(pubkey, bigAmount);
+ console.log("new_channel", new_channel);
setNewChannel(new_channel);
@@ -364,7 +360,7 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
}
};
- const network = state.mutiny_wallet?.get_network() as Network;
+ const network = state.network;
return (
<>
@@ -421,10 +417,10 @@ function OpenChannel(props: { refetchChannels: RefetchChannelsListType }) {
function ListNodes() {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const getNodeIds = async () => {
- const nodes = await state.mutiny_wallet?.list_nodes();
+ const nodes = await sw.list_nodes();
return nodes as string[];
};
@@ -450,7 +446,7 @@ function ListNodes() {
function LSPS(props: { initialSettings: MutinyWalletSettingStrings }) {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const [lspSettingsForm, { Form, Field }] =
createForm({
validate: (values) => {
@@ -469,7 +465,7 @@ function LSPS(props: { initialSettings: MutinyWalletSettingStrings }) {
async function handleSubmit(values: MutinyWalletSettingStrings) {
console.log("values", values);
try {
- await state.mutiny_wallet?.change_lsp(
+ await sw.change_lsp(
values.lsp ? values.lsp : undefined,
values.lsps_connection_string
? values.lsps_connection_string
diff --git a/src/components/LoadingIndicator.tsx b/src/components/LoadingIndicator.tsx
index 214ec6b..8db4e57 100644
--- a/src/components/LoadingIndicator.tsx
+++ b/src/components/LoadingIndicator.tsx
@@ -43,7 +43,7 @@ function LoadingBar(props: { value: number; max: number }) {
}
export function LoadingIndicator() {
- const [state, _actions] = useMegaStore();
+ const [state] = useMegaStore();
const loadStageValue = () => {
switch (state.load_stage) {
diff --git a/src/components/Logs.tsx b/src/components/Logs.tsx
index bd53cee..9c7577a 100644
--- a/src/components/Logs.tsx
+++ b/src/components/Logs.tsx
@@ -1,12 +1,13 @@
-import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
import { createSignal, Show } from "solid-js";
import { Button, InfoBox, InnerCard, NiceP, VStack } from "~/components";
import { useI18n } from "~/i18n/context";
+import { useMegaStore } from "~/state/megaStore";
import { downloadTextFile, eify } from "~/utils";
export function Logs() {
const i18n = useI18n();
+ const [_state, _actions, sw] = useMegaStore();
// Create state for errors, password and dialog visibility
const [error, setError] = createSignal();
@@ -14,7 +15,7 @@ export function Logs() {
async function handleSave() {
try {
setError(undefined);
- const logs = await MutinyWallet.get_logs();
+ const logs = await sw.get_logs();
await downloadTextFile(
logs.join("") || "",
"mutiny-logs.txt",
diff --git a/src/components/NWCEditor.tsx b/src/components/NWCEditor.tsx
index e5579ec..df34a59 100644
--- a/src/components/NWCEditor.tsx
+++ b/src/components/NWCEditor.tsx
@@ -104,7 +104,7 @@ export function NWCEditor(props: {
initialNWA?: string;
onSave: (indexToOpen?: number, nwcUriForCallback?: string) => Promise;
}) {
- const [state] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const i18n = useI18n();
const nwa = createMemo(() => parseNWA(props.initialNWA));
@@ -152,7 +152,7 @@ export function NWCEditor(props: {
async function createNwa(f: BudgetForm) {
if (!f.nwaString) throw new Error("We lost the NWA string!");
try {
- await state.mutiny_wallet?.approve_nostr_wallet_auth(
+ await sw.approve_nostr_wallet_auth(
f.connection_name || "Nostr Wallet Auth",
// can we do better than ! here?
f.nwaString
@@ -177,7 +177,7 @@ export function NWCEditor(props: {
try {
const profile: NwcProfile | undefined =
- await state.mutiny_wallet?.get_nwc_profile(index);
+ await sw.get_nwc_profile(index);
console.log(profile);
return profile;
} catch (e) {
@@ -200,8 +200,7 @@ export function NWCEditor(props: {
if (!label) return undefined;
try {
- const contact: TagItem | undefined =
- await state.mutiny_wallet?.get_tag_item(label);
+ const contact: TagItem | undefined = await sw.get_tag_item(label);
return contact;
} catch (e) {
console.error(e);
@@ -215,12 +214,11 @@ export function NWCEditor(props: {
let newProfile: NwcProfile | undefined = undefined;
if (!f.profileIndex) throw new Error("No profile index!");
if (!f.auto_approve || f.budget_amount === "0") {
- newProfile =
- await state.mutiny_wallet?.set_nwc_profile_require_approval(
- f.profileIndex
- );
+ newProfile = await sw.set_nwc_profile_require_approval(
+ f.profileIndex
+ );
} else {
- newProfile = await state.mutiny_wallet?.set_nwc_profile_budget(
+ newProfile = await sw.set_nwc_profile_budget(
f.profileIndex,
BigInt(f.budget_amount),
mapIntervalToBudgetPeriod(f.interval)
@@ -240,11 +238,9 @@ export function NWCEditor(props: {
let newProfile: NwcProfile | undefined = undefined;
if (!f.auto_approve || f.budget_amount === "0") {
- newProfile = await state.mutiny_wallet?.create_nwc_profile(
- f.connection_name
- );
+ newProfile = await sw.create_nwc_profile(f.connection_name);
} else {
- newProfile = await state.mutiny_wallet?.create_budget_nwc_profile(
+ newProfile = await sw.create_budget_nwc_profile(
f.connection_name,
BigInt(f.budget_amount),
mapIntervalToBudgetPeriod(f.interval),
diff --git a/src/components/NostrActivity.tsx b/src/components/NostrActivity.tsx
index cf86e13..0880984 100644
--- a/src/components/NostrActivity.tsx
+++ b/src/components/NostrActivity.tsx
@@ -1,4 +1,3 @@
-import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
import { createAsync, useNavigate } from "@solidjs/router";
import { Search } from "lucide-solid";
import {
@@ -38,9 +37,9 @@ export function Avatar(props: { image_url?: string; large?: boolean }) {
export function NostrActivity() {
const i18n = useI18n();
- const [state, _actions] = useMegaStore();
+ const [state, _actions, sw] = useMegaStore();
- const npub = createAsync(async () => state.mutiny_wallet?.get_npub());
+ const npub = createAsync(async () => await sw.get_npub());
const [data, { refetch }] = createResource(npub, fetchZaps);
@@ -72,14 +71,14 @@ export function NostrActivity() {
// TODO: can this be part of mutiny wallet?
async function newContactFromHexpub(hexpub: string) {
try {
- const npub = await MutinyWallet.hexpub_to_npub(hexpub);
+ const npub = await sw.hexpub_to_npub(hexpub);
+ console.log("newContactFromHexpub", npub);
if (!npub) {
throw new Error("No npub for that hexpub");
}
- const existingContact =
- await state.mutiny_wallet?.get_contact_for_npub(npub);
+ const existingContact = await sw.get_contact_for_npub(npub);
if (existingContact) {
navigate(`/chat/${existingContact.id}`);
@@ -94,7 +93,7 @@ export function NostrActivity() {
const ln_address = parsed.lud16 || undefined;
const lnurl = parsed.lud06 || undefined;
- const contactId = await state.mutiny_wallet?.create_new_contact(
+ const contactId = await sw.create_new_contact(
name,
npub,
ln_address,
@@ -106,7 +105,7 @@ export function NostrActivity() {
throw new Error("no contact id returned");
}
- const tagItem = await state.mutiny_wallet?.get_tag_item(contactId);
+ const tagItem = await sw.get_tag_item(contactId);
if (!tagItem) {
throw new Error("no contact returned");
diff --git a/src/components/PendingNwc.tsx b/src/components/PendingNwc.tsx
index a595186..cc13421 100644
--- a/src/components/PendingNwc.tsx
+++ b/src/components/PendingNwc.tsx
@@ -31,21 +31,20 @@ type PendingItem = {
export function PendingNwc() {
const i18n = useI18n();
- const [state, _actions] = useMegaStore();
+ const [state, _actions, sw] = useMegaStore();
const [error, setError] = createSignal();
const navigate = useNavigate();
async function fetchPendingRequests() {
- const profiles = await state.mutiny_wallet?.get_nwc_profiles();
+ const profiles = await sw.get_nwc_profiles();
if (!profiles) return [];
- const contacts: TagItem[] | undefined =
- await state.mutiny_wallet?.get_contacts_sorted();
+ const contacts: TagItem[] | undefined = await sw.get_contacts_sorted();
if (!contacts) return [];
- const pending = await state.mutiny_wallet?.get_pending_nwc_invoices();
+ const pending = await sw.get_pending_nwc_invoices();
if (!pending) return [];
const pendingItems: PendingItem[] = [];
@@ -88,7 +87,7 @@ export function PendingNwc() {
try {
// setPaying(item.id);
setPayList([...payList(), item.id]);
- await state.mutiny_wallet?.approve_invoice(item.id);
+ await sw.approve_invoice(item.id);
await vibrateSuccess();
} catch (e) {
const err = eify(e);
@@ -97,7 +96,7 @@ export function PendingNwc() {
if (err.message === "An invoice must not get payed twice.") {
// wrap in try/catch so we don't crash if the invoice is already gone
try {
- await state.mutiny_wallet?.deny_invoice(item.id);
+ await sw.deny_invoice(item.id);
} catch (_e) {
// do nothing
}
@@ -121,7 +120,7 @@ export function PendingNwc() {
async function denyAll() {
try {
- await state.mutiny_wallet?.deny_all_pending_nwc();
+ await sw.deny_all_pending_nwc();
} catch (e) {
setError(eify(e));
console.error(e);
@@ -133,7 +132,7 @@ export function PendingNwc() {
async function rejectItem(item: PendingItem) {
try {
setPayList([...payList(), item.id]);
- await state.mutiny_wallet?.deny_invoice(item.id);
+ await sw.deny_invoice(item.id);
} catch (e) {
setError(eify(e));
console.error(e);
@@ -161,7 +160,11 @@ export function PendingNwc() {
return (
- 0}>
+ 0
+ }
+ >
navigate("/settings/connections")}>
@@ -197,7 +200,7 @@ export function PendingNwc() {
{error()?.message}
-
+
{(pendingItem) => (
{
try {
- const channels = await state.mutiny_wallet?.list_channels();
- let inbound = 0;
+ const channels = await sw.list_channels();
+ if (!channels) return 0n;
+ let inbound = 0n;
+
+ // PAIN: mutiny-wasm types say these are bigints, but they're actually numbers
for (const channel of channels) {
- inbound += channel.size - (channel.balance + channel.reserve);
+ inbound +=
+ BigInt(channel.size) -
+ BigInt(channel.balance + channel.reserve);
}
return inbound;
} catch (e) {
console.error(e);
- return 0;
+ return 0n;
}
});
@@ -41,12 +46,7 @@ export function ReceiveWarnings(props: {
});
}
- const parsed = Number(props.amountSats);
- if (isNaN(parsed)) {
- return undefined;
- }
-
- if (parsed > (inboundCapacity() || 0)) {
+ if (props.amountSats > (inboundCapacity() || 0n)) {
return i18n.t("receive.amount_editable.setup_fee_lightning");
}
diff --git a/src/components/Restart.tsx b/src/components/Restart.tsx
index f9f4b78..8d9564d 100644
--- a/src/components/Restart.tsx
+++ b/src/components/Restart.tsx
@@ -6,16 +6,16 @@ import { useMegaStore } from "~/state/megaStore";
export function Restart() {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const [hasStopped, setHasStopped] = createSignal(false);
async function toggle() {
try {
if (hasStopped()) {
- await state.mutiny_wallet?.start();
+ await sw.start();
setHasStopped(false);
} else {
- await state.mutiny_wallet?.stop();
+ await sw.stop();
setHasStopped(true);
}
} catch (e) {
diff --git a/src/components/ResyncOnchain.tsx b/src/components/ResyncOnchain.tsx
index 2a0d6e2..45559cd 100644
--- a/src/components/ResyncOnchain.tsx
+++ b/src/components/ResyncOnchain.tsx
@@ -4,11 +4,11 @@ import { useMegaStore } from "~/state/megaStore";
export function ResyncOnchain() {
const i18n = useI18n();
- const [state, _] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
async function reset() {
try {
- await state.mutiny_wallet?.reset_onchain_tracker();
+ await sw.reset_onchain_tracker();
} catch (e) {
console.error(e);
}
diff --git a/src/components/SetupErrorDisplay.tsx b/src/components/SetupErrorDisplay.tsx
index 29d0982..f00c737 100644
--- a/src/components/SetupErrorDisplay.tsx
+++ b/src/components/SetupErrorDisplay.tsx
@@ -1,4 +1,3 @@
-import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
import { Title } from "@solidjs/meta";
import { MonitorSmartphone } from "lucide-solid";
import { createResource, Match, Switch } from "solid-js";
@@ -21,6 +20,7 @@ import {
MutinyWalletSettingStrings
} from "~/logic/mutinyWalletSetup";
import { FeedbackLink } from "~/routes/Feedback";
+import { useMegaStore } from "~/state/megaStore";
function ErrorFooter() {
return (
@@ -38,6 +38,7 @@ export function SetupErrorDisplay(props: {
password?: string;
}) {
// Error shouldn't be reactive, so we assign to it so it just gets rendered with the first value
+ const [_state, _actions, sw] = useMegaStore();
const i18n = useI18n();
const error = props.initialError;
@@ -45,7 +46,7 @@ export function SetupErrorDisplay(props: {
if (error.message.startsWith("Mutiny is already running")) {
const settings: MutinyWalletSettingStrings = await getSettings();
try {
- const secs = await MutinyWallet.get_device_lock_remaining_secs(
+ const secs = await sw.get_device_lock_remaining_secs(
props.password,
settings.auth,
settings.storage
diff --git a/src/components/SocialActionRow.tsx b/src/components/SocialActionRow.tsx
index c7f1d41..5e323fa 100644
--- a/src/components/SocialActionRow.tsx
+++ b/src/components/SocialActionRow.tsx
@@ -1,7 +1,7 @@
import { TagItem } from "@mutinywallet/mutiny-wasm";
import { cache, createAsync, useNavigate } from "@solidjs/router";
import { Scan, Search } from "lucide-solid";
-import { createMemo, For, Suspense } from "solid-js";
+import { For, Suspense } from "solid-js";
import { Circle, LabelCircle, showToast } from "~/components";
import { useMegaStore } from "~/state/megaStore";
@@ -10,13 +10,12 @@ export function SocialActionRow(props: {
onSearch: () => void;
onScan: () => void;
}) {
- const [state, actions] = useMegaStore();
+ const [_state, actions, sw] = useMegaStore();
const navigate = useNavigate();
const getContacts = cache(async () => {
try {
- const contacts: TagItem[] =
- (await state.mutiny_wallet?.get_contacts_sorted()) || [];
+ const contacts: TagItem[] = (await sw.get_contacts_sorted()) || [];
// contact must have a npub, ln_address, or lnurl
return contacts.filter(
@@ -33,16 +32,17 @@ export function SocialActionRow(props: {
const contacts = createAsync(() => getContacts(), { initialValue: [] });
- const profileDeleted = createMemo(
- () => state.mutiny_wallet?.get_nostr_profile().deleted
- );
+ const profileDeleted = createAsync(async () => {
+ const profile = await sw.get_nostr_profile();
+ return profile?.deleted;
+ });
// TODO this is mostly copy pasted from chat, could be a shared util maybe
- function sendToContact(contact?: TagItem) {
+ async function sendToContact(contact?: TagItem) {
if (!contact) return;
const address = contact.ln_address || contact.lnurl;
if (address) {
- actions.handleIncomingString(
+ await actions.handleIncomingString(
(address || "").trim(),
(error) => {
showToast(error);
@@ -60,6 +60,14 @@ export function SocialActionRow(props: {
}
}
+ async function handleClick(contact: TagItem) {
+ if (profileDeleted() || !contact.npub) {
+ sendToContact(contact);
+ } else {
+ navigate(`/chat/${contact.id}`);
+ }
+ }
+
return (
-
+ }>
+
+
diff --git a/src/routes/Receive.tsx b/src/routes/Receive.tsx
index 13174b8..38c3579 100644
--- a/src/routes/Receive.tsx
+++ b/src/routes/Receive.tsx
@@ -47,7 +47,7 @@ import { useI18n } from "~/i18n/context";
import { useMegaStore } from "~/state/megaStore";
import { eify, objectToSearchParams, vibrateSuccess } from "~/utils";
-type OnChainTx = {
+export type OnChainTx = {
transaction: {
version: number;
lock_time: number;
@@ -123,7 +123,7 @@ function ReceiveMethodHelp() {
}
export function Receive() {
- const [state, actions] = useMegaStore();
+ const [state, actions, sw] = useMegaStore();
const navigate = useNavigate();
const i18n = useI18n();
@@ -242,10 +242,7 @@ export function Receive() {
// First we try to get both an invoice and an address
try {
console.log("big amount", bigAmount);
- const raw = await state.mutiny_wallet?.create_bip21(
- bigAmount,
- tags
- );
+ const raw = await sw.create_bip21(bigAmount, tags);
// Save the raw info so we can watch the address and invoice
setBip21Raw(raw);
@@ -270,7 +267,7 @@ export function Receive() {
// If we didn't return before this, that means create_bip21 failed
// So now we'll just try and get an address without the invoice
try {
- const raw = await state.mutiny_wallet?.get_new_address(tags);
+ const raw = await sw.get_new_address(tags);
// Save the raw info so we can watch the address
setBip21Raw(raw);
@@ -314,8 +311,7 @@ export function Receive() {
try {
// Lightning invoice might be blank
if (lightning) {
- const invoice =
- await state.mutiny_wallet?.get_invoice(lightning);
+ const invoice = await sw.get_invoice(lightning);
// If the invoice has a fees amount that's probably the LSP fee
if (invoice?.fees_paid) {
@@ -330,9 +326,9 @@ export function Receive() {
}
}
- const tx = (await state.mutiny_wallet?.check_address(
- address
- )) as OnChainTx | undefined;
+ const tx = (await sw.check_address(address)) as
+ | OnChainTx
+ | undefined;
if (tx) {
setReceiveState("paid");
@@ -396,7 +392,7 @@ export function Receive() {
onSubmit={getQr}
/>
diff --git a/src/routes/Redeem.tsx b/src/routes/Redeem.tsx
index 65c8872..d166499 100644
--- a/src/routes/Redeem.tsx
+++ b/src/routes/Redeem.tsx
@@ -36,7 +36,7 @@ import { eify, vibrateSuccess } from "~/utils";
type RedeemState = "edit" | "paid";
export function Redeem() {
- const [state, _actions] = useMegaStore();
+ const [state, _actions, sw] = useMegaStore();
const navigate = useNavigate();
const i18n = useI18n();
@@ -52,8 +52,9 @@ export function Redeem() {
const [loading, setLoading] = createSignal(false);
const [error, setError] = createSignal("");
- function mSatsToSats(mSats: bigint) {
- return mSats / 1000n;
+ function mSatsToSats(mSats: bigint | number) {
+ const bigMsats = BigInt(mSats);
+ return bigMsats / 1000n;
}
function clearAll() {
@@ -69,9 +70,7 @@ export function Redeem() {
const [decodedLnurl] = createResource(async () => {
if (state.scan_result) {
if (state.scan_result.lnurl) {
- const decoded = await state.mutiny_wallet?.decode_lnurl(
- state.scan_result.lnurl
- );
+ const decoded = await sw.decode_lnurl(state.scan_result.lnurl);
return decoded;
}
}
@@ -126,10 +125,7 @@ export function Redeem() {
setLoading(true);
try {
- const success = await state.mutiny_wallet?.lnurl_withdraw(
- lnurlString(),
- amount()
- );
+ const success = await sw.lnurl_withdraw(lnurlString(), amount());
if (!success) {
setError(i18n.t("redeem.lnurl_redeem_failed"));
} else {
@@ -170,7 +166,7 @@ export function Redeem() {
diff --git a/src/routes/Request.tsx b/src/routes/Request.tsx
index 8d101bc..e8654c6 100644
--- a/src/routes/Request.tsx
+++ b/src/routes/Request.tsx
@@ -22,7 +22,7 @@ import { eify } from "~/utils";
import { DestinationItem } from "./Send";
export function RequestRoute() {
- const [state, _actions] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
const navigate = useNavigate();
const i18n = useI18n();
@@ -46,12 +46,12 @@ export function RequestRoute() {
tags.push(whatForInput().trim());
}
- const raw = await state.mutiny_wallet?.create_bip21(amount(), tags);
+ const raw = await sw.create_bip21(amount(), tags);
if (!raw || !raw.invoice)
throw new Error("Invoice creation failed");
- await state.mutiny_wallet?.send_dm(npub, raw.invoice);
+ await sw.send_dm(npub, raw.invoice);
navigate("/chat/" + params.id);
} catch (e) {
@@ -64,7 +64,7 @@ export function RequestRoute() {
async function getContact(id: string) {
console.log("fetching contact", id);
try {
- const contact = state.mutiny_wallet?.get_tag_item(id);
+ const contact = await sw.get_tag_item(id);
console.log("fetching contact", contact);
// This shouldn't happen
if (!contact) throw new Error("Contact not found");
@@ -103,7 +103,7 @@ export function RequestRoute() {
setAmountSats={setAmount}
onSubmit={handleSubmit}
/>
-
+
diff --git a/src/routes/Search.tsx b/src/routes/Search.tsx
index 7810cfd..8003bed 100644
--- a/src/routes/Search.tsx
+++ b/src/routes/Search.tsx
@@ -74,7 +74,7 @@ export function Search() {
function ActualSearch(props: { initialValue?: string }) {
const [searchValue, setSearchValue] = createSignal("");
const [debouncedSearchValue, setDebouncedSearchValue] = createSignal("");
- const [state, actions] = useMegaStore();
+ const [_state, actions, sw] = useMegaStore();
const navigate = useNavigate();
const i18n = useI18n();
@@ -88,7 +88,7 @@ function ActualSearch(props: { initialValue?: string }) {
const getContacts = cache(async () => {
try {
- const contacts = await state.mutiny_wallet?.get_contacts_sorted();
+ const contacts = await sw.get_contacts_sorted();
return contacts || ([] as TagItem[]);
} catch (e) {
console.error(e);
@@ -124,7 +124,7 @@ function ActualSearch(props: { initialValue?: string }) {
type SearchState = "notsendable" | "sendable" | "sendableWithContact";
- const searchState = createMemo(() => {
+ const searchState = createAsync(async () => {
if (debouncedSearchValue() === "") {
return "notsendable";
}
@@ -134,7 +134,7 @@ function ActualSearch(props: { initialValue?: string }) {
return "notsendable";
}
let state: SearchState = "notsendable";
- actions.handleIncomingString(
+ await actions.handleIncomingString(
text,
(_error) => {
// noop
@@ -147,6 +147,7 @@ function ActualSearch(props: { initialValue?: string }) {
}
}
);
+ console.log("params searchState", state);
return state;
});
@@ -160,8 +161,8 @@ function ActualSearch(props: { initialValue?: string }) {
});
}
- function handleContinue() {
- actions.handleIncomingString(
+ async function handleContinue() {
+ await actions.handleIncomingString(
debouncedSearchValue().trim(),
(error) => {
showToast(error);
@@ -181,16 +182,17 @@ function ActualSearch(props: { initialValue?: string }) {
);
}
- const profileDeleted = createMemo(
- () => state.mutiny_wallet?.get_nostr_profile().deleted
- );
+ const profileDeleted = createAsync(async () => {
+ const profile = await sw.get_nostr_profile();
+ return profile?.deleted;
+ });
// TODO this is mostly copy pasted from chat, could be a shared util maybe
- function navToSend(contact?: TagItem) {
+ async function navToSend(contact?: TagItem) {
if (!contact) return;
const address = contact.ln_address || contact.lnurl;
if (address) {
- actions.handleIncomingString(
+ await actions.handleIncomingString(
(address || "").trim(),
(error) => {
showToast(error);
@@ -208,9 +210,9 @@ function ActualSearch(props: { initialValue?: string }) {
}
}
- function sendToContact(contact: TagItem) {
+ async function sendToContact(contact: TagItem) {
if (profileDeleted()) {
- navToSend(contact);
+ await navToSend(contact);
} else {
navWithSearchValue(`/chat/${contact.id}`);
}
@@ -224,11 +226,11 @@ function ActualSearch(props: { initialValue?: string }) {
);
if (existingContact) {
- sendToContact(existingContact);
+ await sendToContact(existingContact);
return;
}
- const contactId = await state.mutiny_wallet?.create_new_contact(
+ const contactId = await sw.create_new_contact(
contact.name,
contact.npub ? contact.npub.trim() : undefined,
contact.ln_address ? contact.ln_address.trim() : undefined,
@@ -240,7 +242,7 @@ function ActualSearch(props: { initialValue?: string }) {
throw new Error("no contact id returned");
}
- const tagItem = await state.mutiny_wallet?.get_tag_item(contactId);
+ const tagItem = await sw.get_tag_item(contactId);
if (!tagItem) {
throw new Error("no contact returned");
@@ -249,9 +251,9 @@ function ActualSearch(props: { initialValue?: string }) {
// if the new contact has an npub, send to chat
// otherwise, send to send page
if (tagItem.npub) {
- sendToContact(tagItem);
+ await sendToContact(tagItem);
} else if (tagItem.ln_address) {
- actions.handleIncomingString(
+ await actions.handleIncomingString(
tagItem.ln_address,
() => {},
() => {
@@ -259,7 +261,7 @@ function ActualSearch(props: { initialValue?: string }) {
}
);
} else if (tagItem.lnurl) {
- actions.handleIncomingString(
+ await actions.handleIncomingString(
tagItem.lnurl,
() => {},
() => {
@@ -293,14 +295,14 @@ function ActualSearch(props: { initialValue?: string }) {
const trimText = text.trim();
setSearchValue(trimText);
- parsePaste(trimText);
+ await parsePaste(trimText);
} catch (e) {
console.error(e);
}
}
- function parsePaste(text: string) {
- actions.handleIncomingString(
+ async function parsePaste(text: string) {
+ await actions.handleIncomingString(
text,
(error) => {
showToast(error);
@@ -354,45 +356,49 @@ function ActualSearch(props: { initialValue?: string }) {
-
-
-
-
-
-
-
-
- Contacts
- 0}>
-
- {(contact) => (
- sendToContact(contact)}
- />
- )}
-
-
-
-
+
+
+
+
+
+
+
+
+
+ Contacts
+ 0}>
+
+ {(contact) => (
+
+ sendToContact(contact)
+ }
+ />
+ )}
+
+
+
+
- }>
-
-
- Global Search
-
-
-
-
-
-
-
+ }>
+
+
+ Global Search
+
+
+
+
+
+
+
+
>
);
}
@@ -402,10 +408,11 @@ function GlobalSearch(props: {
sendToContact: (contact: TagItem) => void;
foundNpubs: (string | undefined)[];
}) {
+ const [_state, _actions, sw] = useMegaStore();
const hexpubs = createMemo(() => {
const hexpubs: Set = new Set();
for (const npub of props.foundNpubs) {
- hexpubFromNpub(npub)
+ hexpubFromNpub(sw, npub)
.then((h) => {
if (h) {
hexpubs.add(h);
@@ -425,7 +432,7 @@ function GlobalSearch(props: {
try {
// Handling case when value starts with "npub"
if (args.value?.toLowerCase().startsWith("npub")) {
- const hexpub = await hexpubFromNpub(args.value);
+ const hexpub = await hexpubFromNpub(sw, args.value);
if (!hexpub) return [];
const profile = await actuallyFetchNostrProfile(hexpub);
@@ -491,23 +498,25 @@ function SingleContact(props: {
contact: PseudoContact;
sendToContact: (contact: TagItem) => void;
}) {
- const [state, _actions] = useMegaStore();
+ const [_state, _actions, sw] = useMegaStore();
async function createContactFromSearchResult(contact: PseudoContact) {
try {
- const contactId = await state.mutiny_wallet?.create_new_contact(
+ const contactId = await sw.create_new_contact(
contact.name,
- contact.hexpub ? contact.hexpub : undefined,
+ contact.hexpub ? contact.hexpub : "",
contact.ln_address ? contact.ln_address : undefined,
undefined,
contact.image_url ? contact.image_url : undefined
);
+ console.log("contactId", contactId);
+
if (!contactId) {
throw new Error("no contact id returned");
}
- const tagItem = await state.mutiny_wallet?.get_tag_item(contactId);
+ const tagItem = await sw.get_tag_item(contactId);
if (!tagItem) {
throw new Error("no contact returned");
diff --git a/src/routes/Send.tsx b/src/routes/Send.tsx
index e73f4c4..efa7400 100644
--- a/src/routes/Send.tsx
+++ b/src/routes/Send.tsx
@@ -1,5 +1,10 @@
import { MutinyInvoice, TagItem } from "@mutinywallet/mutiny-wasm";
-import { useLocation, useNavigate, useSearchParams } from "@solidjs/router";
+import {
+ createAsync,
+ useLocation,
+ useNavigate,
+ useSearchParams
+} from "@solidjs/router";
import { Eye, EyeOff, Link, X, Zap } from "lucide-solid";
import {
createEffect,
@@ -158,7 +163,7 @@ export function DestinationItem(props: {
}
export function Send() {
- const [state, actions] = useMegaStore();
+ const [state, actions, sw] = useMegaStore();
const navigate = useNavigate();
const [params, setParams] = useSearchParams();
const i18n = useI18n();
@@ -220,8 +225,8 @@ export function Send() {
}
// TODO: can I dedupe this from the search page?
- function parsePaste(text: string) {
- actions.handleIncomingString(
+ async function parsePaste(text: string) {
+ await actions.handleIncomingString(
text,
(error) => {
showToast(error);
@@ -233,9 +238,10 @@ export function Send() {
);
}
+ // TODO: do we actually use this anywhere?
// send?invoice=... need to check for wallet because we can't parse until we have the wallet
createEffect(() => {
- if (params.invoice && state.mutiny_wallet) {
+ if (params.invoice && state.load_stage === "done") {
parsePaste(params.invoice);
setParams({ invoice: undefined });
}
@@ -300,7 +306,7 @@ export function Send() {
});
// Rerun every time the amount changes if we're onchain
- const feeEstimate = createMemo(() => {
+ const feeEstimate = createAsync(async () => {
if (
source() === "onchain" &&
amountSats() &&
@@ -310,16 +316,16 @@ export function Send() {
try {
// If max we want to use the sweep fee estimator
if (isMax()) {
- return state.mutiny_wallet?.estimate_sweep_tx_fee(
- address()!
- );
+ return await sw.estimate_sweep_tx_fee(address()!);
}
- return state.mutiny_wallet?.estimate_tx_fee(
+ const estimate = await sw.estimate_tx_fee(
address()!,
amountSats(),
undefined
);
+ console.log("estimate", estimate);
+ return estimate;
} catch (e) {
setError(eify(e).message);
}
@@ -367,15 +373,15 @@ export function Send() {
// A ParsedParams with an invoice in it
function processInvoice(source: ParsedParams & { invoice: string }) {
- state.mutiny_wallet
- ?.decode_invoice(source.invoice!)
+ sw.decode_invoice(source.invoice!)
.then((invoice) => {
+ if (!invoice) return;
if (invoice.expire <= Date.now() / 1000) {
navigate("/search");
throw new Error(i18n.t("send.error_expired"));
}
- if (invoice?.amount_sats) {
+ if (invoice.amount_sats) {
setAmountSats(invoice.amount_sats);
setIsAmtEditable(false);
}
@@ -396,8 +402,7 @@ export function Send() {
// A ParsedParams with an lnurl in it
function processLnurl(source: ParsedParams & { lnurl: string }) {
setDecodingLnUrl(true);
- state.mutiny_wallet
- ?.decode_lnurl(source.lnurl)
+ sw.decode_lnurl(source.lnurl)
.then((lnurlParams) => {
setDecodingLnUrl(false);
if (lnurlParams.tag === "payRequest") {
@@ -470,7 +475,7 @@ export function Send() {
sentDetails.destination = bolt11;
// If the invoice has sats use that, otherwise we pass the user-defined amount
if (invoice()?.amount_sats) {
- const payment = await state.mutiny_wallet?.pay_invoice(
+ const payment = await sw.pay_invoice(
bolt11,
undefined,
tags
@@ -479,7 +484,7 @@ export function Send() {
sentDetails.payment_hash = payment?.payment_hash;
sentDetails.fee_estimate = payment?.fees_paid || 0;
} else {
- const payment = await state.mutiny_wallet?.pay_invoice(
+ const payment = await sw.pay_invoice(
bolt11,
amountSats(),
tags
@@ -489,7 +494,7 @@ export function Send() {
sentDetails.fee_estimate = payment?.fees_paid || 0;
}
} else if (source() === "lightning" && nodePubkey()) {
- const payment = await state.mutiny_wallet?.keysend(
+ const payment = await sw.keysend(
nodePubkey()!,
amountSats(),
undefined, // todo add optional keysend message
@@ -509,7 +514,7 @@ export function Send() {
visibility() !== "Not Available" && contact()?.npub
? contact()?.npub
: undefined;
- const payment = await state.mutiny_wallet?.lnurl_pay(
+ const payment = await sw.lnurl_pay(
lnurlp()!,
amountSats(),
zapNpub, // zap_npub
@@ -530,17 +535,14 @@ export function Send() {
if (isMax()) {
// If we're trying to send the max amount, use the sweep method instead of regular send
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const txid = await state.mutiny_wallet?.sweep_wallet(
- address()!,
- tags
- );
+ const txid = await sw.sweep_wallet(address()!, tags);
sentDetails.amount = amountSats();
sentDetails.destination = address();
sentDetails.txid = txid;
sentDetails.fee_estimate = feeEstimate() ?? 0;
} else if (payjoinEnabled()) {
- const txid = await state.mutiny_wallet?.send_payjoin(
+ const txid = await sw.send_payjoin(
originalScan()!,
amountSats(),
tags
@@ -551,7 +553,7 @@ export function Send() {
sentDetails.fee_estimate = feeEstimate() ?? 0;
} else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const txid = await state.mutiny_wallet?.send_to_address(
+ const txid = await sw.send_to_address(
address()!,
amountSats(),
tags
@@ -665,7 +667,7 @@ export function Send() {
async function getContact(id: string) {
console.log("fetching contact", id);
try {
- const contact = state.mutiny_wallet?.get_tag_item(id);
+ const contact = await sw.get_tag_item(id);
console.log("fetching contact", contact);
// This shouldn't happen
if (!contact) throw new Error("Contact not found");
@@ -773,7 +775,6 @@ export function Send() {
sendButtonDisabled() ? undefined : handleSend()
}
@@ -791,7 +792,6 @@ export function Send() {
sendButtonDisabled() ? undefined : handleSend()
@@ -801,13 +801,15 @@ export function Send() {
setChosenMethod={setSourceFromMethod}
/>
-
-
-
+
+
+
+
+
{i18n.t("send.hodl_invoice_warning")}
diff --git a/src/routes/Swap.tsx b/src/routes/Swap.tsx
index a56a291..b38f876 100644
--- a/src/routes/Swap.tsx
+++ b/src/routes/Swap.tsx
@@ -1,6 +1,6 @@
import { createForm, required } from "@modular-forms/solid";
-import { MutinyChannel, MutinyPeer } from "@mutinywallet/mutiny-wasm";
-import { useNavigate } from "@solidjs/router";
+import { MutinyChannel } from "@mutinywallet/mutiny-wasm";
+import { createAsync, useNavigate } from "@solidjs/router";
import {
createMemo,
createResource,
@@ -8,6 +8,7 @@ import {
For,
Match,
Show,
+ Suspense,
Switch
} from "solid-js";
@@ -33,7 +34,6 @@ import {
VStack
} from "~/components";
import { useI18n } from "~/i18n/context";
-import { Network } from "~/logic/mutinyWalletSetup";
import { useMegaStore } from "~/state/megaStore";
import { eify, vibrateSuccess } from "~/utils";
@@ -50,7 +50,7 @@ type ChannelOpenDetails = {
};
export function Swap() {
- const [state, _actions] = useMegaStore();
+ const [state, _actions, sw] = useMegaStore();
const navigate = useNavigate();
const i18n = useI18n();
@@ -100,9 +100,7 @@ export function Swap() {
};
const getPeers = async () => {
- return (await state.mutiny_wallet?.list_peers()) as Promise<
- MutinyPeer[]
- >;
+ return await sw?.list_peers();
};
const [peers, { refetch }] = createResource(getPeers);
@@ -114,7 +112,7 @@ export function Swap() {
try {
const peerConnectString = values.peer.trim();
- await state.mutiny_wallet?.connect_to_peer(peerConnectString);
+ await sw.connect_to_peer(peerConnectString);
await refetch();
@@ -156,12 +154,11 @@ export function Swap() {
}
if (isMax()) {
- const new_channel =
- await state.mutiny_wallet?.sweep_all_to_channel(peer);
+ const new_channel = await sw.sweep_all_to_channel(peer);
setChannelOpenResult({ channel: new_channel });
} else {
- const new_channel = await state.mutiny_wallet?.open_channel(
+ const new_channel = await sw.open_channel(
peer,
amountSats()
);
@@ -182,7 +179,7 @@ export function Swap() {
const balance =
(state.balance?.confirmed || 0n) +
(state.balance?.unconfirmed || 0n);
- const network = state.mutiny_wallet?.get_network() as Network;
+ const network = state.network || "signet";
if (network === "bitcoin") {
return (
@@ -199,12 +196,12 @@ export function Swap() {
}
};
- const amountWarning = () => {
+ const amountWarning = createAsync(async () => {
if (amountSats() === 0n || !!channelOpenResult()) {
return undefined;
}
- const network = state.mutiny_wallet?.get_network() as Network;
+ const network = state.network || "signet";
if (network === "bitcoin" && amountSats() < 100000n) {
return i18n.t("swap.channel_too_small", { amount: "100,000" });
@@ -224,7 +221,7 @@ export function Swap() {
}
return undefined;
- };
+ });
function calculateMaxOnchain() {
return (
@@ -241,12 +238,12 @@ export function Swap() {
return amountSats() === calculateMaxOnchain();
});
- const feeEstimate = createMemo(() => {
- const max = calculateMaxOnchain();
+ const feeEstimate = createAsync(async () => {
+ const max = maxOnchain();
// If max we want to use the sweep fee estimator
if (amountSats() > 0n && amountSats() === max) {
try {
- return state.mutiny_wallet?.estimate_sweep_channel_open_fee();
+ return await sw.estimate_sweep_channel_open_fee();
} catch (e) {
console.error(e);
return undefined;
@@ -255,7 +252,7 @@ export function Swap() {
if (amountSats() > 0n) {
try {
- return state.mutiny_wallet?.estimate_tx_fee(
+ return await sw.estimate_tx_fee(
CHANNEL_FEE_ESTIMATE_ADDRESS,
amountSats(),
undefined
@@ -328,18 +325,20 @@ export function Swap() {
})}