Bypass nudge for encrypt and decrypt, remove phase-transition toast
Encrypt and decrypt operations now call the signer directly without nudge/timeout/retry wrapping. The sign operation already provides the user-facing nudge when approval is needed, so the encrypt nudge was redundant noise. Phase-transition toast and related constants removed as dead code.
This commit is contained in:
@@ -2,7 +2,7 @@ import type { NostrEvent, NostrSigner } from '@nostrify/types';
|
||||
import { createElement } from 'react';
|
||||
import { toast } from '@/hooks/useToast';
|
||||
import { androidResume } from '@/lib/androidResume';
|
||||
import { NudgeToastContent, PhaseToastContent } from '@/components/SignerToastContent';
|
||||
import { NudgeToastContent } from '@/components/SignerToastContent';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Constants
|
||||
@@ -11,28 +11,10 @@ import { NudgeToastContent, PhaseToastContent } from '@/components/SignerToastCo
|
||||
/** Show the nudge toast after this delay if a signer op is still pending. */
|
||||
const NUDGE_DELAY_MS = 4_000;
|
||||
|
||||
/** Longer delay for decrypt operations — auto-approve is common and nudging
|
||||
* too early sends the user to the signer with nothing to approve. */
|
||||
const NUDGE_DELAY_DECRYPT_MS = 10_000;
|
||||
|
||||
/** Hard timeout — reject the op entirely after this long with no response. */
|
||||
const HARD_TIMEOUT_MS = 45_000;
|
||||
|
||||
/**
|
||||
* Event kinds whose content is encrypted by the user's signer before signing.
|
||||
* A signEvent for one of these kinds immediately after a nip44 encrypt is
|
||||
* treated as the second phase of the same operation (encrypt-then-sign), and
|
||||
* a phase-transition toast is shown so the user knows a second approval is
|
||||
* coming.
|
||||
*
|
||||
* Only kinds where Ditto calls `user.signer.nip44.encrypt()` then immediately
|
||||
* `createEvent()` qualify — DM gift-wraps use ephemeral random signers and
|
||||
* are excluded.
|
||||
*/
|
||||
const ENCRYPTED_CONTENT_KINDS = new Set([
|
||||
10000, // Mute list (NIP-51, private items encrypted to self)
|
||||
30078, // App settings (NIP-78, content encrypted to self)
|
||||
]);
|
||||
|
||||
/** Max number of automatic retries on Android foreground resume. */
|
||||
const MAX_RETRIES = 2;
|
||||
@@ -174,16 +156,6 @@ function showSuccessToast(opType: OpType): void {
|
||||
toast({ title: `${verb} approved`, duration: 3000, variant: 'success' });
|
||||
}
|
||||
|
||||
function showPhaseTransitionToast(signKind: number | undefined): void {
|
||||
const android = isAndroid();
|
||||
const label = signKind !== undefined ? KIND_LABELS[signKind] : undefined;
|
||||
const signDesc = label ? `approve ${label} signing` : 'approve signing';
|
||||
const message = `Encryption approved — now ${signDesc} in your signer app.`;
|
||||
|
||||
const description = createElement(PhaseToastContent, { message, android });
|
||||
|
||||
toast({ title: 'Step 1 complete', description, duration: 8000 });
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Core: run a signer operation with nudge + retry logic
|
||||
@@ -244,7 +216,7 @@ async function runWithNudge<T>(op: () => Promise<T>, opts: RunOpts): Promise<Run
|
||||
|
||||
// --- Nudge timer ---
|
||||
let dismissNudge: (() => void) | undefined;
|
||||
const delay = opType === 'decrypt' ? NUDGE_DELAY_DECRYPT_MS : NUDGE_DELAY_MS;
|
||||
const delay = NUDGE_DELAY_MS;
|
||||
const nudgeTimer = setTimeout(() => {
|
||||
nudgeFired = true;
|
||||
const handle = showNudgeToast({
|
||||
@@ -344,11 +316,6 @@ export function signerWithNudge(
|
||||
signer: NostrSigner,
|
||||
isBunkerConnected?: () => boolean,
|
||||
): NostrSigner {
|
||||
// Multi-phase state: set to true when a nip44 encrypt completes with the
|
||||
// nudge shown. Cleared on the next signEvent. Used to detect encrypt-then-sign
|
||||
// flows for kinds whose content is encrypted by the user's signer.
|
||||
let pendingEncryptNudge = false;
|
||||
|
||||
/** Run an op and return just the value (discarding nudge metadata). */
|
||||
function run<T>(op: () => Promise<T>, kind: number | undefined, opType: OpType): Promise<T> {
|
||||
return runWithNudge(op, { kind, opType, isBunkerConnected }).then((r) => r.value);
|
||||
@@ -358,13 +325,6 @@ export function signerWithNudge(
|
||||
getPublicKey: () => run(() => signer.getPublicKey(), undefined, 'sign'),
|
||||
|
||||
signEvent: (event: NostrEvent) => {
|
||||
// Show a phase-transition toast when signing an event whose content was
|
||||
// just encrypted by the user's signer and the nudge was shown for that
|
||||
// encrypt. Only fires for kinds we know use encrypt-then-sign.
|
||||
if (pendingEncryptNudge && ENCRYPTED_CONTENT_KINDS.has(event.kind)) {
|
||||
showPhaseTransitionToast(event.kind);
|
||||
}
|
||||
pendingEncryptNudge = false;
|
||||
return run(() => signer.signEvent(event), event.kind, 'sign');
|
||||
},
|
||||
};
|
||||
@@ -381,11 +341,7 @@ export function signerWithNudge(
|
||||
}) {
|
||||
return {
|
||||
encrypt: (pubkey: string, plaintext: string) =>
|
||||
runWithNudge(() => crypto.encrypt(pubkey, plaintext), { kind: undefined, opType: 'encrypt', isBunkerConnected })
|
||||
.then(({ value, nudgeFired }) => {
|
||||
pendingEncryptNudge = nudgeFired;
|
||||
return value;
|
||||
}),
|
||||
crypto.encrypt(pubkey, plaintext),
|
||||
decrypt: (pubkey: string, ciphertext: string) =>
|
||||
crypto.decrypt(pubkey, ciphertext),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user