Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Payjoin sends #608

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/i18n/en/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ export default {
error_keysend: "Keysend failed",
error_LNURL: "LNURL Pay failed",
error_expired: "Invoice is expired",
payjoin_send:
"This is a payjoin! The Mutiny will continue until privacy improves",
payment_pending: "Payment pending",
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.",
Expand Down
4 changes: 4 additions & 0 deletions src/logic/waila.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { Result } from "~/utils";
await initWaila();

export type ParsedParams = {
original: string;
address?: string;
payjoin_enabled?: boolean;
invoice?: string;
amount_sats?: bigint;
network?: string;
Expand Down Expand Up @@ -53,7 +55,9 @@ export function toParsedParams(
return {
ok: true,
value: {
original: str,
address: params.address,
payjoin_enabled: params.payjoin_supported,
invoice: params.invoice,
amount_sats: params.amount_sats,
network,
Expand Down
21 changes: 20 additions & 1 deletion src/routes/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,9 @@ export function Send() {
const [nodePubkey, setNodePubkey] = createSignal<string>();
const [lnurlp, setLnurlp] = createSignal<string>();
const [lnAddress, setLnAddress] = createSignal<string>();
const [originalScan, setOriginalScan] = createSignal<string>();
const [address, setAddress] = createSignal<string>();
const [payjoinEnabled, setPayjoinEnabled] = createSignal<boolean>();
const [description, setDescription] = createSignal<string>();
const [contactId, setContactId] = createSignal<string>();
const [isHodlInvoice, setIsHodlInvoice] = createSignal<boolean>(false);
Expand Down Expand Up @@ -414,9 +416,11 @@ export function Send() {
function handleDestination(source: ParsedParams | undefined) {
if (!source) return;
setParsingDestination(true);

setOriginalScan(source.original);
try {
if (source.address) setAddress(source.address);
if (source.payjoin_enabled)
setPayjoinEnabled(source.payjoin_enabled);
if (source.memo) setDescription(source.memo);
if (source.contact_id) setContactId(source.contact_id);

Expand Down Expand Up @@ -594,6 +598,16 @@ export function Send() {
tags
);

sentDetails.amount = amountSats();
sentDetails.destination = address();
sentDetails.txid = txid;
sentDetails.fee_estimate = feeEstimate() ?? 0;
} else if (payjoinEnabled()) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure a sweep should necessarily preclude payjoin on the isMax condition. A receiver offered a sweep could still take the opportunity to contribute an input or use transaction cut-through, and otherwise just broadcast the original psbt as a basic sweep. It doesn't break this PR but should be considered for incremental change later.

const txid = await state.mutiny_wallet?.send_payjoin(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a try-catch block to enable that fallback to normal send?

try {
const txid = await state.mutiny_wallet?.send_payjoin(
                        destination()!.original,
                        amountSats(),
                        tags
                    );
} catch {
const txid = await state.mutiny_wallet?.send_to_address(
                        address()!,
                        amountSats(),
                        tags
);
}

though this brings up the comment you made in the mutiny-node about where the waila should parse the receive string as some parsing would be needed between destination.original() and address()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

easy enough to just regex away the unimportant stuff, but still worth considering

Copy link
Author

@DanGould DanGould Nov 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should assume someone wants to spend as naive tx if they can avoid it. some automated payment processors will automatically spend the naive tx if payjoin fails but senders may want to try another utxo or choose something else like ln instead of immediately sending w/o a privacy preserving measure

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, that makes sense

originalScan()!,
amountSats(),
tags
);
sentDetails.amount = amountSats();
sentDetails.destination = address();
sentDetails.txid = txid;
Expand Down Expand Up @@ -789,6 +803,11 @@ export function Send() {
setChosenMethod={setSourceFromMethod}
/>
</Show>
<Show when={payjoinEnabled()}>
<InfoBox accent="green">
<p>{i18n.t("send.payjoin_send")}</p>
</InfoBox>
</Show>
<Show when={!isAmtEditable()}>
<AmountEditable
initialAmountSats={amountSats()}
Expand Down
1 change: 1 addition & 0 deletions src/state/megaStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ export const Provider: ParentComponent = (props) => {
} else {
if (
result.value?.address ||
result.value?.payjoin_enabled ||
result.value?.invoice ||
result.value?.node_pubkey ||
(result.value?.lnurl && !result.value.is_lnurl_auth)
Expand Down
Loading