diff --git a/__tests__/signerStore.cancelled.test.ts b/__tests__/signerStore.cancelled.test.ts new file mode 100644 index 0000000..1d5f1cb --- /dev/null +++ b/__tests__/signerStore.cancelled.test.ts @@ -0,0 +1,36 @@ +import { useSignerStore } from '../src/store/signerStore'; + +describe('signer store cancellation state', () => { + beforeEach(() => { + useSignerStore.getState().reset(); + }); + + it('keeps cancellation separate from failure and clears review state safely', () => { + const store = useSignerStore.getState(); + + store.startReview({ + requestId: 'req-1', + sourcePublicKey: 'GSOURCE', + destinationPublicKey: 'GDEST', + amount: '10', + assetCode: 'XLM', + network: 'Testnet', + createdAt: new Date().toISOString(), + timeoutSeconds: 30, + }); + + store.completeSigning({ + hash: 'abc123', + review: useSignerStore.getState().currentReview!, + signerType: 'local', + completedAt: new Date().toISOString(), + }); + + store.cancelSigning(); + + expect(useSignerStore.getState().phase).toBe('cancelled'); + expect(useSignerStore.getState().error).toBeNull(); + expect(useSignerStore.getState().currentReview).toBeNull(); + expect(useSignerStore.getState().lastResult).toBeNull(); + }); +}); diff --git a/src/hooks/useSignerHandoff.ts b/src/hooks/useSignerHandoff.ts index 13cd44e..97850d1 100644 --- a/src/hooks/useSignerHandoff.ts +++ b/src/hooks/useSignerHandoff.ts @@ -107,18 +107,16 @@ export function useSignerHandoff() { // Check cancellation before signing if (cancelledRef.current) { - const error = createSignerError('user_cancelled', 'Signing was cancelled.'); - store.failSigning(error); - return { success: false, error }; + store.cancelSigning(); + return { success: false, cancelled: true }; } const signedTx = await localSigner.sign(review, buildTransaction); // Check cancellation before submission if (cancelledRef.current) { - const error = createSignerError('user_cancelled', 'Signing was cancelled.'); - store.failSigning(error); - return { success: false, error }; + store.cancelSigning(); + return { success: false, cancelled: true }; } // Phase: submitting @@ -138,6 +136,11 @@ export function useSignerHandoff() { return { success: true, result }; } catch (err: any) { const error = classifySigningError(err); + if (error.type === 'user_cancelled') { + store.cancelSigning(); + return { success: false, cancelled: true, error }; + } + store.failSigning(error); return { success: false, error }; } diff --git a/src/store/signerStore.ts b/src/store/signerStore.ts index 95b290f..3383e09 100644 --- a/src/store/signerStore.ts +++ b/src/store/signerStore.ts @@ -81,15 +81,10 @@ export const useSignerStore = create((set, get) => ({ cancelSigning: () => set({ phase: 'cancelled', - error: createCancelledError(), + currentReview: null, + lastResult: null, + error: null, }), reset: () => set({ ...initialState }), })); - -function createCancelledError(): SignerError { - return { - type: 'user_cancelled', - message: 'Signing was cancelled.', - }; -}