Large amount of changes. Successfully broadcasts txs
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* ReviewStep — final step that summarizes the import and executes it.
|
||||
*
|
||||
* Displays the accumulated selections (role, inputs, amounts) and on confirmation:
|
||||
* 1. Adds inputs (with the selected role identifier) to the invitation.
|
||||
* 2. Optionally adds a change output if the change exceeds the dust threshold.
|
||||
* 3. Calls `onComplete()` to signal the flow is finished.
|
||||
*/
|
||||
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { Box, Text, useInput } from 'ink';
|
||||
import { colors, formatSatoshis } from '../../../../theme.js';
|
||||
import type { ReviewStepProps, SelectableUTXO } from '../types.js';
|
||||
|
||||
/** Default fee estimate in satoshis. */
|
||||
const DEFAULT_FEE = 500n;
|
||||
|
||||
/** Dust threshold — outputs below this are unspendable. */
|
||||
const DUST_THRESHOLD = 546n;
|
||||
|
||||
export function ReviewStep({
|
||||
invitation,
|
||||
template,
|
||||
selectedRole,
|
||||
selectedInputs,
|
||||
requiredAmount,
|
||||
changeAmount,
|
||||
appService,
|
||||
onComplete,
|
||||
onCancel,
|
||||
isActive,
|
||||
}: ReviewStepProps): React.ReactElement {
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const fee = DEFAULT_FEE;
|
||||
const action = template?.actions?.[invitation.data.actionIdentifier];
|
||||
|
||||
// Compute totals from selected inputs
|
||||
const totalSelected = selectedInputs.reduce((sum, u) => sum + u.valueSatoshis, 0n);
|
||||
|
||||
/**
|
||||
* Execute the import: add inputs (with role) and optional change output.
|
||||
*/
|
||||
const submit = useCallback(async () => {
|
||||
setIsSubmitting(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
onComplete();
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : String(err));
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}, [invitation, selectedRole, selectedInputs, onComplete]);
|
||||
|
||||
// Keyboard handling
|
||||
useInput((_input, key) => {
|
||||
if (!isActive || isSubmitting) return;
|
||||
|
||||
if (key.return) {
|
||||
submit();
|
||||
} else if (key.escape) {
|
||||
onCancel();
|
||||
}
|
||||
}, { isActive });
|
||||
|
||||
// Resolve role display name
|
||||
const roleInfoRaw = template?.roles?.[selectedRole];
|
||||
const roleInfo = roleInfoRaw && typeof roleInfoRaw === 'object' ? roleInfoRaw : null;
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text color={colors.primary} bold>Review Import</Text>
|
||||
|
||||
{/* Template & action */}
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
<Text color={colors.text}>Template: {template?.name ?? invitation.data.templateIdentifier}</Text>
|
||||
<Text color={colors.text}>Action: {action?.name ?? invitation.data.actionIdentifier}</Text>
|
||||
<Text color={colors.text}>Role: {roleInfo?.name ?? selectedRole}</Text>
|
||||
</Box>
|
||||
|
||||
{/* Funding summary */}
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
<Text color={colors.primary} bold>Funding:</Text>
|
||||
<Text color={colors.text}> • UTXOs: {selectedInputs.length}</Text>
|
||||
<Text color={colors.text}> • Total: {formatSatoshis(totalSelected)}</Text>
|
||||
<Text color={colors.text}> • Required: {formatSatoshis(requiredAmount)}</Text>
|
||||
<Text color={colors.text}> • Fee: {formatSatoshis(fee)}</Text>
|
||||
{changeAmount >= DUST_THRESHOLD && (
|
||||
<Text color={colors.text}> • Change: {formatSatoshis(changeAmount)}</Text>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* Error display */}
|
||||
{error && (
|
||||
<Box marginTop={1}>
|
||||
<Text color={colors.error} bold>Error: {error}</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Status / hint */}
|
||||
<Box marginTop={1}>
|
||||
{isSubmitting ? (
|
||||
<Text color={colors.info}>Submitting...</Text>
|
||||
) : (
|
||||
<Text color={colors.textMuted}>Enter: Confirm & Import • Esc: Cancel</Text>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user