Fix sats out
This commit is contained in:
BIN
Electrum.sqlite-journal
Normal file
BIN
Electrum.sqlite-journal
Normal file
Binary file not shown.
@@ -189,11 +189,22 @@ export function TransactionScreen(): React.ReactElement {
|
|||||||
|
|
||||||
// Extract transaction data from invitation
|
// Extract transaction data from invitation
|
||||||
const commits = invitation?.commits ?? [];
|
const commits = invitation?.commits ?? [];
|
||||||
const inputs: Array<{ txid: string; index: number; value?: bigint }> = [];
|
const inputs: Array<{ txid: string; index: number; value?: bigint; inputIdentifier?: string }> = [];
|
||||||
const outputs: Array<{ value: bigint; lockingBytecode: string }> = [];
|
const outputs: Array<{ value?: bigint; lockingBytecode: string; outputIdentifier?: string; isTemplate: boolean }> = [];
|
||||||
|
const variables: Array<{ id: string; value: string }> = [];
|
||||||
|
|
||||||
// Parse commits for inputs and outputs
|
// Parse commits for inputs, outputs, and variables
|
||||||
for (const commit of commits) {
|
for (const commit of commits) {
|
||||||
|
// Extract variables (to help understand output values)
|
||||||
|
if (commit.data?.variables) {
|
||||||
|
for (const variable of commit.data.variables) {
|
||||||
|
variables.push({
|
||||||
|
id: variable.variableIdentifier,
|
||||||
|
value: String(variable.value),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (commit.data?.inputs) {
|
if (commit.data?.inputs) {
|
||||||
for (const input of commit.data.inputs) {
|
for (const input of commit.data.inputs) {
|
||||||
// Convert Uint8Array to hex string if needed
|
// Convert Uint8Array to hex string if needed
|
||||||
@@ -201,13 +212,17 @@ export function TransactionScreen(): React.ReactElement {
|
|||||||
? typeof input.outpointTransactionHash === 'string'
|
? typeof input.outpointTransactionHash === 'string'
|
||||||
? input.outpointTransactionHash
|
? input.outpointTransactionHash
|
||||||
: Buffer.from(input.outpointTransactionHash).toString('hex')
|
: Buffer.from(input.outpointTransactionHash).toString('hex')
|
||||||
: 'unknown';
|
: undefined;
|
||||||
|
|
||||||
inputs.push({
|
// Skip inputs that are just placeholders (no txid)
|
||||||
txid: txidHex,
|
if (txidHex) {
|
||||||
index: input.outpointIndex ?? 0,
|
inputs.push({
|
||||||
value: undefined, // libauth Input doesn't have valueSatoshis directly
|
txid: txidHex,
|
||||||
});
|
index: input.outpointIndex ?? 0,
|
||||||
|
value: undefined, // Will be looked up from UTXO data
|
||||||
|
inputIdentifier: (input as any).inputIdentifier,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (commit.data?.outputs) {
|
if (commit.data?.outputs) {
|
||||||
@@ -217,20 +232,45 @@ export function TransactionScreen(): React.ReactElement {
|
|||||||
? typeof output.lockingBytecode === 'string'
|
? typeof output.lockingBytecode === 'string'
|
||||||
? output.lockingBytecode
|
? output.lockingBytecode
|
||||||
: Buffer.from(output.lockingBytecode).toString('hex')
|
: Buffer.from(output.lockingBytecode).toString('hex')
|
||||||
: 'unknown';
|
: undefined;
|
||||||
|
|
||||||
|
// Check if this is a template-defined output (has outputIdentifier but no direct value)
|
||||||
|
const isTemplateOutput = !!(output as any).outputIdentifier && !output.valueSatoshis;
|
||||||
|
|
||||||
outputs.push({
|
outputs.push({
|
||||||
value: output.valueSatoshis ?? 0n,
|
value: output.valueSatoshis,
|
||||||
lockingBytecode: lockingBytecodeHex,
|
lockingBytecode: lockingBytecodeHex ?? '(pending)',
|
||||||
|
outputIdentifier: (output as any).outputIdentifier,
|
||||||
|
isTemplate: isTemplateOutput,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate totals
|
// Try to resolve template output values from variables
|
||||||
const totalIn = inputs.reduce((sum, i) => sum + (i.value ?? 0n), 0n);
|
const resolvedOutputs = outputs.map(output => {
|
||||||
const totalOut = outputs.reduce((sum, o) => sum + o.value, 0n);
|
if (output.isTemplate && output.outputIdentifier) {
|
||||||
const fee = totalIn - totalOut;
|
// Look for a matching variable (e.g., requestSatoshisOutput -> requestedSatoshis)
|
||||||
|
const satoshiVar = variables.find(v =>
|
||||||
|
v.id.toLowerCase().includes('satoshi') ||
|
||||||
|
v.id.toLowerCase().includes('amount')
|
||||||
|
);
|
||||||
|
if (satoshiVar) {
|
||||||
|
return {
|
||||||
|
...output,
|
||||||
|
value: BigInt(satoshiVar.value),
|
||||||
|
resolvedFrom: satoshiVar.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Calculate totals (only for resolved values)
|
||||||
|
const totalOut = resolvedOutputs.reduce((sum, o) => sum + (o.value ?? 0n), 0n);
|
||||||
|
// Note: We can't calculate totalIn without UTXO lookup, so fee is unknown
|
||||||
|
const hasUnresolvedOutputs = resolvedOutputs.some(o => o.value === undefined);
|
||||||
|
const hasUnresolvedInputs = inputs.length > 0; // Input values are always unknown from commit data
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box flexDirection="column" flexGrow={1}>
|
<Box flexDirection="column" flexGrow={1}>
|
||||||
@@ -251,10 +291,16 @@ export function TransactionScreen(): React.ReactElement {
|
|||||||
<Text color={colors.primary} bold> Transaction Summary </Text>
|
<Text color={colors.primary} bold> Transaction Summary </Text>
|
||||||
{invitation ? (
|
{invitation ? (
|
||||||
<Box flexDirection="column" marginTop={1}>
|
<Box flexDirection="column" marginTop={1}>
|
||||||
<Text color={colors.text}>Inputs: {inputs.length} | Outputs: {outputs.length} | Commits: {commits.length}</Text>
|
<Text color={colors.text}>Inputs: {inputs.length} | Outputs: {resolvedOutputs.length} | Commits: {commits.length}</Text>
|
||||||
<Text color={colors.success}>Total In: {formatSatoshis(totalIn)}</Text>
|
{hasUnresolvedInputs && (
|
||||||
<Text color={colors.warning}>Total Out: {formatSatoshis(totalOut)}</Text>
|
<Text color={colors.textMuted}>Total In: (requires UTXO lookup)</Text>
|
||||||
<Text color={colors.info}>Fee: {formatSatoshis(fee)}</Text>
|
)}
|
||||||
|
<Text color={colors.warning}>Total Out: {formatSatoshis(totalOut)}{hasUnresolvedOutputs ? ' (partial)' : ''}</Text>
|
||||||
|
{hasUnresolvedInputs ? (
|
||||||
|
<Text color={colors.textMuted}>Fee: (calculated at broadcast)</Text>
|
||||||
|
) : (
|
||||||
|
<Text color={colors.info}>Fee: {formatSatoshis(0n)}</Text>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Text color={colors.textMuted}>Loading...</Text>
|
<Text color={colors.textMuted}>Loading...</Text>
|
||||||
@@ -301,15 +347,21 @@ export function TransactionScreen(): React.ReactElement {
|
|||||||
>
|
>
|
||||||
<Text color={colors.primary} bold> Outputs </Text>
|
<Text color={colors.primary} bold> Outputs </Text>
|
||||||
<Box flexDirection="column" marginTop={1}>
|
<Box flexDirection="column" marginTop={1}>
|
||||||
{outputs.length === 0 ? (
|
{resolvedOutputs.length === 0 ? (
|
||||||
<Text color={colors.textMuted}>No outputs</Text>
|
<Text color={colors.textMuted}>No outputs</Text>
|
||||||
) : (
|
) : (
|
||||||
outputs.map((output, index) => (
|
resolvedOutputs.map((output, index) => (
|
||||||
<Box key={index} flexDirection="column" marginBottom={1}>
|
<Box key={index} flexDirection="column" marginBottom={1}>
|
||||||
<Text color={colors.text}>
|
<Text color={colors.text}>
|
||||||
{index + 1}. {formatSatoshis(output.value)}
|
{index + 1}. {output.value !== undefined ? formatSatoshis(output.value) : '(pending)'}
|
||||||
|
{output.outputIdentifier && (
|
||||||
|
<Text color={colors.info}> [{output.outputIdentifier}]</Text>
|
||||||
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text color={colors.textMuted}> {formatHex(output.lockingBytecode, 20)}</Text>
|
<Text color={colors.textMuted}> {output.lockingBytecode !== '(pending)' ? formatHex(output.lockingBytecode, 20) : '(pending)'}</Text>
|
||||||
|
{(output as any).resolvedFrom && (
|
||||||
|
<Text color={colors.textMuted} dimColor> (from ${(output as any).resolvedFrom})</Text>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user