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