Fix receive and send
This commit is contained in:
@@ -6,10 +6,11 @@
|
||||
* Shows required, selected, and change amounts.
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||
import { Box, Text, useInput } from 'ink';
|
||||
import { colors, formatSatoshis } from '../../../../theme.js';
|
||||
import type { InputsSelectStepProps, SelectableUTXO } from '../types.js';
|
||||
import { autoSelectGreedyUtxos, mapUnspentOutputsToSelectable } from '../../../../../utils/invitation-flow.js';
|
||||
|
||||
/** Default fee estimate in satoshis. */
|
||||
const DEFAULT_FEE = 500n;
|
||||
@@ -64,34 +65,9 @@ export function InputsSelectStep({
|
||||
outputIdentifier: 'receiveOutput',
|
||||
});
|
||||
|
||||
// Map to selectable UTXOs
|
||||
const selectable: SelectableUTXO[] = unspentOutputs.map((utxo: any) => ({
|
||||
outpointTransactionHash: utxo.outpointTransactionHash,
|
||||
outpointIndex: utxo.outpointIndex,
|
||||
valueSatoshis: BigInt(utxo.valueSatoshis),
|
||||
lockingBytecode: utxo.lockingBytecode
|
||||
? typeof utxo.lockingBytecode === 'string'
|
||||
? utxo.lockingBytecode
|
||||
: Buffer.from(utxo.lockingBytecode).toString('hex')
|
||||
: undefined,
|
||||
selected: false,
|
||||
}));
|
||||
|
||||
// Greedy auto-select, skipping duplicate locking bytecodes
|
||||
let accumulated = 0n;
|
||||
const seenBytecodes = new Set<string>();
|
||||
|
||||
for (const utxo of selectable) {
|
||||
if (utxo.lockingBytecode && seenBytecodes.has(utxo.lockingBytecode)) continue;
|
||||
if (utxo.lockingBytecode) seenBytecodes.add(utxo.lockingBytecode);
|
||||
|
||||
utxo.selected = true;
|
||||
accumulated += utxo.valueSatoshis;
|
||||
|
||||
if (accumulated >= required + fee) break;
|
||||
}
|
||||
|
||||
setUtxos(selectable);
|
||||
const selectable = mapUnspentOutputsToSelectable(unspentOutputs);
|
||||
const autoSelected = autoSelectGreedyUtxos(selectable, required + fee);
|
||||
setUtxos(autoSelected as SelectableUTXO[]);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : String(err));
|
||||
} finally {
|
||||
@@ -99,9 +75,15 @@ export function InputsSelectStep({
|
||||
}
|
||||
}, [invitation, computeRequiredAmount, fee]);
|
||||
|
||||
// Load UTXOs on mount
|
||||
// Load UTXOs once on mount. We use a ref guard to prevent re-firing when
|
||||
// `loadUtxos` identity changes due to parent re-renders — each re-fire
|
||||
// flashes the loading state, causing the visible flicker bug.
|
||||
const hasLoadedRef = useRef(false);
|
||||
useEffect(() => {
|
||||
if (isActive) loadUtxos();
|
||||
if (isActive && !hasLoadedRef.current) {
|
||||
hasLoadedRef.current = true;
|
||||
loadUtxos();
|
||||
}
|
||||
}, [isActive, loadUtxos]);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user