diff --git a/src/utils/resolve-invitation-data.ts b/src/utils/resolve-invitation-data.ts index 5927ea4..949fd4d 100644 --- a/src/utils/resolve-invitation-data.ts +++ b/src/utils/resolve-invitation-data.ts @@ -25,7 +25,7 @@ import type { /** * View metadata copied from a template definition onto a resolved invitation item. */ -interface TemplateViewMetadata { +export interface TemplateViewMetadata { name?: string; description?: string; icon?: string; @@ -90,12 +90,25 @@ export interface ResolvedInvitationData { outputs: ResolvedInvitationOutput[]; } +/** + * Template display metadata layered onto a committed output. + */ +export interface TemplateOutputMetadata { + name?: string; + description?: string; + icon?: string; + roles?: Record; + lockingScript?: string; + valueSatoshis?: bigint | string; + token?: XOTemplateOutput["token"]; +} + /** * Picks human-readable view fields from a template definition. */ -function pickTemplateViewMetadata( +export const pickTemplateViewMetadata = ( definition: TemplateViewMetadata | undefined, -): TemplateViewMetadata { +): TemplateViewMetadata => { if (!definition) return {}; return { @@ -105,14 +118,14 @@ function pickTemplateViewMetadata( }), ...(definition.icon !== undefined && { icon: definition.icon }), }; -} +}; /** * Picks variable metadata from a template variable definition. */ -function pickTemplateVariableMetadata( +export const pickTemplateVariableMetadata = ( definition: XOTemplateVariable | undefined, -): Pick { +): Pick => { if (!definition) return {}; return { @@ -120,17 +133,17 @@ function pickTemplateVariableMetadata( ...(definition.type !== undefined && { type: definition.type }), ...(definition.hint !== undefined && { hint: definition.hint }), }; -} +}; /** * Picks input metadata from a template input definition. */ -function pickTemplateInputMetadata( +export const pickTemplateInputMetadata = ( definition: XOTemplateInput | undefined, ): Pick< ResolvedInvitationInput, "name" | "description" | "icon" | "unlockingScript" | "omitChangeAmounts" -> { +> => { if (!definition) return {}; return { @@ -142,20 +155,7 @@ function pickTemplateInputMetadata( omitChangeAmounts: definition.omitChangeAmounts, }), }; -} - -/** - * Template display metadata layered onto a committed output. - */ -interface TemplateOutputMetadata { - name?: string; - description?: string; - icon?: string; - roles?: Record; - lockingScript?: string; - valueSatoshis?: bigint | string; - token?: XOTemplateOutput["token"]; -} +}; /** * Picks output metadata from a template output definition. @@ -164,9 +164,9 @@ interface TemplateOutputMetadata { * defaults; display-oriented fields like name, description, and template * valueSatoshis expressions are layered on for UI rendering. */ -function pickTemplateOutputMetadata( +export const pickTemplateOutputMetadata = ( definition: XOTemplateOutput | undefined, -): TemplateOutputMetadata { +): TemplateOutputMetadata => { if (!definition) return {}; const roles = definition.roles @@ -189,16 +189,16 @@ function pickTemplateOutputMetadata( }), ...(definition.token !== undefined && { token: definition.token }), }; -} +}; /** * Enriches a committed variable with its template definition. */ -function resolveVariable( +export const resolveVariable = ( variable: XOInvitationVariable, entityIdentifier: string, template: XOTemplate, -): ResolvedInvitationVariable { +): ResolvedInvitationVariable => { const definition = template.variables?.[variable.variableIdentifier]; return { @@ -210,16 +210,16 @@ function resolveVariable( value: variable.value, ...pickTemplateVariableMetadata(definition), }; -} +}; /** * Enriches a committed input with its template definition when an identifier is present. */ -function resolveInput( +export const resolveInput = ( input: XOInvitationInput, entityIdentifier: string, template: XOTemplate, -): ResolvedInvitationInput { +): ResolvedInvitationInput => { const definition = input.inputIdentifier ? template.inputs?.[input.inputIdentifier] : undefined; @@ -229,16 +229,16 @@ function resolveInput( ...input, ...pickTemplateInputMetadata(definition), }; -} +}; /** * Enriches a committed output with its template definition when an identifier is present. */ -function resolveOutput( +export const resolveOutput = ( output: XOInvitationOutput, entityIdentifier: string, template: XOTemplate, -): ResolvedInvitationOutput { +): ResolvedInvitationOutput => { const definition = output.outputIdentifier ? template.outputs?.[output.outputIdentifier] : undefined; @@ -249,25 +249,27 @@ function resolveOutput( ...output, ...templateMetadata, } as ResolvedInvitationOutput; -} +}; /** * Converts hex or binary invitation bytecode fields to hex strings for display. */ -function hexOrBinToHex( +export const hexOrBinToHex = ( value: string | Uint8Array | undefined, -): string | undefined { +): string | undefined => { if (value === undefined) { return undefined; } return typeof value === "string" ? value : binToHex(value); -} +}; /** * Normalizes a merged input row for UI display (hex strings, no encoding placeholders). */ -function normalizeMergedInputForDisplay(input: XOInvitationInput): XOInvitationInput { +export const normalizeMergedInputForDisplay = ( + input: XOInvitationInput, +): XOInvitationInput => { const normalized: XOInvitationInput = { ...input }; if (input.outpointTransactionHash !== undefined) { @@ -295,14 +297,14 @@ function normalizeMergedInputForDisplay(input: XOInvitationInput): XOInvitationI } return normalized; -} +}; /** * Normalizes a merged output row for UI display (hex strings). */ -function normalizeMergedOutputForDisplay( +export const normalizeMergedOutputForDisplay = ( output: XOInvitationOutput, -): XOInvitationOutput { +): XOInvitationOutput => { const normalized: XOInvitationOutput = { ...output }; if (output.lockingBytecode !== undefined) { @@ -312,16 +314,16 @@ function normalizeMergedOutputForDisplay( } return normalized; -} +}; /** * Recovers `outputIdentifier` from the source commit because the merger strips it * after template resolution. */ -function findOutputIdentifierForMergedOutput( +export const findOutputIdentifierForMergedOutput = ( commit: XOInvitationCommit | undefined, mergedOutput: XOInvitationOutput, -): string | undefined { +): string | undefined => { const outputs = commit?.data?.outputs ?? []; const mergedBytecodeHex = hexOrBinToHex(mergedOutput.lockingBytecode); @@ -351,30 +353,30 @@ function findOutputIdentifierForMergedOutput( } return undefined; -} +}; /** * Whether two invitation variable rows refer to the same template variable slot. */ -function matchesInvitationVariable( +export const matchesInvitationVariable = ( left: XOInvitationVariable, right: XOInvitationVariable, -): boolean { +): boolean => { return ( left.variableIdentifier === right.variableIdentifier && left.roleIdentifier === right.roleIdentifier ); -} +}; /** * Finds the entity that authored a merged variable by scanning invitation commits. * Last matching commit in array order wins. Best-effort until the engine orders * commits internally or exposes source attribution on merged variables. */ -function findVariableEntityIdentifier( +export const findVariableEntityIdentifier = ( variable: XOInvitationVariable, commits: XOInvitationCommit[], -): string { +): string => { let entityIdentifier = ""; for (const commit of commits) { @@ -386,7 +388,7 @@ function findVariableEntityIdentifier( } return entityIdentifier; -} +}; /** * Returns template-enriched invitation data for UI display. @@ -400,10 +402,10 @@ function findVariableEntityIdentifier( * @param template - The template referenced by the invitation. * @returns Resolved invitation data ready for display. */ -export function resolveCommitReferences( +export const resolveCommitReferences = ( invitation: XOInvitation, template: XOTemplate, -): ResolvedInvitationData { +): ResolvedInvitationData => { const commits = invitation.commits ?? []; const commitsMap = new Map( commits.map((commit) => [commit.commitIdentifier, commit]), @@ -473,4 +475,4 @@ export function resolveCommitReferences( inputs, outputs, }; -} +};