Massive changes. I dont know what happens. Rewrote the action wizard again. Fixed several bugs related to the utxo selection. QR codes were added for address. Add support for data results. Experiment with other methods of role extraction

This commit is contained in:
2026-03-22 13:20:46 +00:00
parent be52f73e64
commit a28d43a68b
35 changed files with 2226 additions and 1169 deletions

View File

@@ -11,6 +11,7 @@ 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';
import type { UnspentOutputData } from '@xo-cash/state';
/** Default fee estimate in satoshis. */
const DEFAULT_FEE = 500n;
@@ -60,12 +61,54 @@ export function InputsSelectStep({
const required = await computeRequiredAmount();
setRequiredAmount(required);
const unspentOutputs = await invitation.findSuitableResources({
templateIdentifier: invitation.data.templateIdentifier,
outputIdentifier: 'receiveOutput',
});
const template = await appService.engine.getTemplate(invitation.data.templateIdentifier);
if (!template) {
throw new Error('Template not found');
}
const selectable = mapUnspentOutputsToSelectable(unspentOutputs);
// Get the action that we are calling from the template
const action = template.actions[invitation.data.actionIdentifier];
if (!action) {
throw new Error('Action not found');
}
if (!action.transaction) {
throw new Error('Action does not have a transaction');
}
// Get the transaction that the action is creating
const transaction = template.transactions?.[action.transaction];
if (!transaction) {
throw new Error(`Transaction not found for action: ${action.transaction}`);
}
if (!transaction.outputs) {
throw new Error(`Transaction does not have outputs`);
}
// Create a set to store all the output identifiers
const outputIdentifiers = new Set<string>();
for (const output of transaction.outputs) {
outputIdentifiers.add(output.output);
}
console.log('outputIdentifiers', Array.from(outputIdentifiers));
// Create a map of the utxoID to suitable resource
const utxoIdToSuitableResource = new Map<string, UnspentOutputData>();
for (const outputIdentifier of outputIdentifiers) {
const suitableResources = await invitation.findSuitableResources({
outputIdentifier,
});
console.log('suitableResources', outputIdentifier, JSON.stringify(suitableResources, null, 2));
for (const suitableResource of suitableResources) {
utxoIdToSuitableResource.set(suitableResource.outpointTransactionHash + ':' + suitableResource.outpointIndex, suitableResource);
}
}
console.log('utxoIdToSuitableResource', JSON.stringify(utxoIdToSuitableResource, null, 2));
const selectable = mapUnspentOutputsToSelectable(Array.from(utxoIdToSuitableResource.values()));
const autoSelected = autoSelectGreedyUtxos(selectable, required + fee);
setUtxos(autoSelected as SelectableUTXO[]);
} catch (err) {