xoonya 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/package.json +1 -1
- package/proof_sdk.js +133 -0
- package/server.js +21 -0
package/README.md
CHANGED
|
@@ -34,6 +34,12 @@ The current `1.7.0` companion slice adds a lightweight transaction proof-handoff
|
|
|
34
34
|
- a direct handoff run path that turns transaction-side proof handoff data into a proof-native bundle
|
|
35
35
|
- summary helpers that make the recommended proof follow-through explicit without widening proof scope
|
|
36
36
|
|
|
37
|
+
The current `1.8.0` companion slice extends that same proof-side carry to richer grouped interaction spine handoffs:
|
|
38
|
+
|
|
39
|
+
- an interaction-spine handoff center and summary surface
|
|
40
|
+
- a direct interaction-spine handoff run path for composed transaction spines
|
|
41
|
+
- proof-side summaries that preserve both pre-commit and committed-ref context without importing commerce logic
|
|
42
|
+
|
|
37
43
|
## Proof Model
|
|
38
44
|
|
|
39
45
|
The primary proof model is layered:
|
package/package.json
CHANGED
package/proof_sdk.js
CHANGED
|
@@ -895,6 +895,22 @@ function buildTransactionProofHandoffCenter() {
|
|
|
895
895
|
};
|
|
896
896
|
}
|
|
897
897
|
|
|
898
|
+
function buildInteractionSpineProofHandoffCenter() {
|
|
899
|
+
return {
|
|
900
|
+
ok: true,
|
|
901
|
+
brand: "xoonya",
|
|
902
|
+
product: "interaction spine proof handoff center",
|
|
903
|
+
supported_source_refs: [
|
|
904
|
+
"spine.a2a.settlement",
|
|
905
|
+
"spine.a2c.tooling",
|
|
906
|
+
"spine.job.commitment"
|
|
907
|
+
],
|
|
908
|
+
required_fields: ["transaction_id", "receipt_id", "proof_ref", "source_ref"],
|
|
909
|
+
optional_fields: ["task_refs", "delivery_count", "payment_ledger_count", "committed_ref", "precommit_pack_ref"],
|
|
910
|
+
recommended_loop: "default.proof.bundle.loop"
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
898
914
|
function summarizeTransactionProofHandoffCenter() {
|
|
899
915
|
const center = buildTransactionProofHandoffCenter();
|
|
900
916
|
return {
|
|
@@ -909,6 +925,20 @@ function summarizeTransactionProofHandoffCenter() {
|
|
|
909
925
|
};
|
|
910
926
|
}
|
|
911
927
|
|
|
928
|
+
function summarizeInteractionSpineProofHandoffCenter() {
|
|
929
|
+
const center = buildInteractionSpineProofHandoffCenter();
|
|
930
|
+
return {
|
|
931
|
+
ok: true,
|
|
932
|
+
brand: center.brand,
|
|
933
|
+
product: center.product,
|
|
934
|
+
source_ref_count: Array.isArray(center.supported_source_refs) ? center.supported_source_refs.length : 0,
|
|
935
|
+
supported_source_refs: center.supported_source_refs,
|
|
936
|
+
required_field_count: Array.isArray(center.required_fields) ? center.required_fields.length : 0,
|
|
937
|
+
required_fields: center.required_fields,
|
|
938
|
+
recommended_loop: center.recommended_loop
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
|
|
912
942
|
function canonicalizeTransactionProofHandoff(input) {
|
|
913
943
|
const body = input && typeof input === "object" && !Array.isArray(input) ? input : {};
|
|
914
944
|
const handoff = body.handoff_bundle && typeof body.handoff_bundle === "object" && !Array.isArray(body.handoff_bundle)
|
|
@@ -935,6 +965,26 @@ function canonicalizeTransactionProofHandoff(input) {
|
|
|
935
965
|
};
|
|
936
966
|
}
|
|
937
967
|
|
|
968
|
+
function canonicalizeInteractionSpineProofHandoff(input) {
|
|
969
|
+
const handoff = canonicalizeTransactionProofHandoff(input);
|
|
970
|
+
const body = input && typeof input === "object" && !Array.isArray(input) ? input : {};
|
|
971
|
+
const sourceRef = normalizeString(handoff.source_ref);
|
|
972
|
+
const center = buildInteractionSpineProofHandoffCenter();
|
|
973
|
+
if (!center.supported_source_refs.includes(sourceRef)) {
|
|
974
|
+
throw new Error("handoff_bundle.source_ref must be a supported interaction spine ref");
|
|
975
|
+
}
|
|
976
|
+
const raw = body.handoff_bundle && typeof body.handoff_bundle === "object" && !Array.isArray(body.handoff_bundle)
|
|
977
|
+
? body.handoff_bundle
|
|
978
|
+
: body;
|
|
979
|
+
const committedRef = normalizeString(raw.committed_ref);
|
|
980
|
+
const precommitPackRef = normalizeString(raw.precommit_pack_ref);
|
|
981
|
+
return {
|
|
982
|
+
...handoff,
|
|
983
|
+
committed_ref: committedRef || null,
|
|
984
|
+
precommit_pack_ref: precommitPackRef || null
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
|
|
938
988
|
function buildTransactionProofHandoffEvent(input) {
|
|
939
989
|
const handoff = canonicalizeTransactionProofHandoff(input);
|
|
940
990
|
const eventHash = canonicalJsonSha256Hex({
|
|
@@ -958,6 +1008,31 @@ function buildTransactionProofHandoffEvent(input) {
|
|
|
958
1008
|
});
|
|
959
1009
|
}
|
|
960
1010
|
|
|
1011
|
+
function buildInteractionSpineProofHandoffEvent(input) {
|
|
1012
|
+
const handoff = canonicalizeInteractionSpineProofHandoff(input);
|
|
1013
|
+
const eventHash = canonicalJsonSha256Hex({
|
|
1014
|
+
source_ref: handoff.source_ref,
|
|
1015
|
+
transaction_id: handoff.transaction_id,
|
|
1016
|
+
receipt_id: handoff.receipt_id,
|
|
1017
|
+
proof_ref: handoff.proof_ref,
|
|
1018
|
+
task_refs: handoff.task_refs,
|
|
1019
|
+
delivery_count: handoff.delivery_count,
|
|
1020
|
+
payment_ledger_count: handoff.payment_ledger_count,
|
|
1021
|
+
committed_ref: handoff.committed_ref,
|
|
1022
|
+
precommit_pack_ref: handoff.precommit_pack_ref
|
|
1023
|
+
});
|
|
1024
|
+
return canonicalizeEvent({
|
|
1025
|
+
version: CANONICAL_EVENT_BUNDLE_VERSION,
|
|
1026
|
+
domain_id: "xytara.interaction_spine_handoff",
|
|
1027
|
+
sequence: handoff.transaction_id,
|
|
1028
|
+
actor_id: "xytara.interaction_spine",
|
|
1029
|
+
adapter_source: "xytara.spine_handoff",
|
|
1030
|
+
event_type: `${handoff.source_ref}.proof_handoff`,
|
|
1031
|
+
event_hash: eventHash,
|
|
1032
|
+
semantic_slots: handoff
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
|
|
961
1036
|
function runTransactionProofHandoff(input) {
|
|
962
1037
|
const handoff = canonicalizeTransactionProofHandoff(input);
|
|
963
1038
|
const event = buildTransactionProofHandoffEvent(input);
|
|
@@ -986,6 +1061,36 @@ function runTransactionProofHandoff(input) {
|
|
|
986
1061
|
};
|
|
987
1062
|
}
|
|
988
1063
|
|
|
1064
|
+
function runInteractionSpineProofHandoff(input) {
|
|
1065
|
+
const handoff = canonicalizeInteractionSpineProofHandoff(input);
|
|
1066
|
+
const event = buildInteractionSpineProofHandoffEvent(input);
|
|
1067
|
+
const options = input && input.options && typeof input.options === "object" && !Array.isArray(input.options)
|
|
1068
|
+
? input.options
|
|
1069
|
+
: {};
|
|
1070
|
+
const receipt = emitReceipt(event, options);
|
|
1071
|
+
const proofBundle = buildProofBundle({
|
|
1072
|
+
ceb: event,
|
|
1073
|
+
receipt,
|
|
1074
|
+
evidence_refs: Array.isArray(input && input.evidence_refs) ? input.evidence_refs : [handoff.proof_ref],
|
|
1075
|
+
metadata: {
|
|
1076
|
+
handoff_kind: "interaction_spine_proof_handoff",
|
|
1077
|
+
source_ref: handoff.source_ref,
|
|
1078
|
+
committed_ref: handoff.committed_ref || null,
|
|
1079
|
+
precommit_pack_ref: handoff.precommit_pack_ref || null
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1082
|
+
return {
|
|
1083
|
+
ok: true,
|
|
1084
|
+
handoff,
|
|
1085
|
+
canonical_event: event,
|
|
1086
|
+
event_commitment: hashEvent(event),
|
|
1087
|
+
receipt,
|
|
1088
|
+
proof_bundle: proofBundle,
|
|
1089
|
+
bundle_verification: verifyProofBundle(proofBundle),
|
|
1090
|
+
recommended_loop: "default.proof.bundle.loop"
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
|
|
989
1094
|
function summarizeTransactionProofHandoff(bundle) {
|
|
990
1095
|
const item = bundle && typeof bundle === "object" ? bundle : {};
|
|
991
1096
|
const handoff = item.handoff && typeof item.handoff === "object" ? item.handoff : {};
|
|
@@ -1006,6 +1111,28 @@ function summarizeTransactionProofHandoff(bundle) {
|
|
|
1006
1111
|
};
|
|
1007
1112
|
}
|
|
1008
1113
|
|
|
1114
|
+
function summarizeInteractionSpineProofHandoff(bundle) {
|
|
1115
|
+
const item = bundle && typeof bundle === "object" ? bundle : {};
|
|
1116
|
+
const handoff = item.handoff && typeof item.handoff === "object" ? item.handoff : {};
|
|
1117
|
+
const receipt = item.receipt && typeof item.receipt === "object" ? item.receipt : {};
|
|
1118
|
+
const proofBundle = item.proof_bundle && typeof item.proof_bundle === "object" ? item.proof_bundle : {};
|
|
1119
|
+
const verification = item.bundle_verification && typeof item.bundle_verification === "object" ? item.bundle_verification : {};
|
|
1120
|
+
return {
|
|
1121
|
+
ok: item.ok === true,
|
|
1122
|
+
source_ref: handoff.source_ref || null,
|
|
1123
|
+
transaction_id: handoff.transaction_id || null,
|
|
1124
|
+
receipt_id: handoff.receipt_id || null,
|
|
1125
|
+
proof_ref: handoff.proof_ref || null,
|
|
1126
|
+
committed_ref: handoff.committed_ref || null,
|
|
1127
|
+
precommit_pack_ref: handoff.precommit_pack_ref || null,
|
|
1128
|
+
task_ref_count: Array.isArray(handoff.task_refs) ? handoff.task_refs.length : 0,
|
|
1129
|
+
proof_bundle_version: proofBundle.version || null,
|
|
1130
|
+
emitted_receipt_id: receipt.receipt_id || null,
|
|
1131
|
+
bundle_valid: verification.valid === true,
|
|
1132
|
+
recommended_loop: item.recommended_loop || null
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1009
1136
|
function runDefaultProofLoop(loopRef, input) {
|
|
1010
1137
|
const loop = getDefaultProofLoop(loopRef);
|
|
1011
1138
|
if (!loop) {
|
|
@@ -1049,15 +1176,21 @@ module.exports = {
|
|
|
1049
1176
|
buildDefaultProofCenter,
|
|
1050
1177
|
buildDefaultProofLoopCatalog,
|
|
1051
1178
|
buildDefaultProofLoops,
|
|
1179
|
+
buildInteractionSpineProofHandoffCenter,
|
|
1052
1180
|
buildTransactionProofHandoffCenter,
|
|
1181
|
+
buildInteractionSpineProofHandoffEvent,
|
|
1053
1182
|
buildTransactionProofHandoffEvent,
|
|
1183
|
+
canonicalizeInteractionSpineProofHandoff,
|
|
1054
1184
|
getDefaultProofLoop,
|
|
1055
1185
|
canonicalizeTransactionProofHandoff,
|
|
1056
1186
|
runDefaultProofLoop,
|
|
1187
|
+
runInteractionSpineProofHandoff,
|
|
1057
1188
|
runTransactionProofHandoff,
|
|
1058
1189
|
summarizeDefaultProofCenter,
|
|
1059
1190
|
summarizeDefaultProofLoops,
|
|
1060
1191
|
summarizeGuidedProofLoopBundle,
|
|
1192
|
+
summarizeInteractionSpineProofHandoff,
|
|
1193
|
+
summarizeInteractionSpineProofHandoffCenter,
|
|
1061
1194
|
summarizeTransactionProofHandoff,
|
|
1062
1195
|
summarizeTransactionProofHandoffCenter,
|
|
1063
1196
|
canonicalizeEvent,
|
package/server.js
CHANGED
|
@@ -107,6 +107,16 @@ async function routeRequest(req, res) {
|
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/interaction-spine-handoff') {
|
|
111
|
+
sendJson(res, 200, proofSdk.buildInteractionSpineProofHandoffCenter());
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (req.method === 'GET' && url.pathname === '/v1/proof-center/interaction-spine-handoff/summary') {
|
|
116
|
+
sendJson(res, 200, proofSdk.summarizeInteractionSpineProofHandoffCenter());
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
110
120
|
if (req.method === 'GET' && url.pathname === '/v1/proof-center/default-loop') {
|
|
111
121
|
const loop = proofSdk.getDefaultProofLoop(url.searchParams.get('ref'));
|
|
112
122
|
if (!loop) {
|
|
@@ -140,6 +150,17 @@ async function routeRequest(req, res) {
|
|
|
140
150
|
return;
|
|
141
151
|
}
|
|
142
152
|
|
|
153
|
+
if (req.method === 'POST' && url.pathname === '/v1/proof-center/interaction-spine-handoff/run') {
|
|
154
|
+
try {
|
|
155
|
+
const body = await readJsonBody(req);
|
|
156
|
+
const result = proofSdk.runInteractionSpineProofHandoff(body);
|
|
157
|
+
sendJson(res, 200, result);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
sendJson(res, 400, { ok: false, reason: error.message });
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
143
164
|
if (req.method === 'POST' && url.pathname === '/v1/receipts/verify') {
|
|
144
165
|
try {
|
|
145
166
|
const body = await readJsonBody(req);
|