xytara 1.4.0 → 1.5.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 +23 -0
- package/index.js +10 -2
- package/integrations/registry.js +264 -0
- package/lib/catalog_contract.js +86 -1
- package/lib/commerce_client.js +164 -0
- package/package.json +1 -1
- package/server.js +55 -1
package/README.md
CHANGED
|
@@ -66,6 +66,15 @@ The economic artifact posture is also now more explicit across the default machi
|
|
|
66
66
|
|
|
67
67
|
The same artifacts now also expose a normalized `default_path` object so the bundled economic center of gravity is visible as data instead of being inferred indirectly.
|
|
68
68
|
|
|
69
|
+
The package and service also expose a default transaction center surface so the out-of-the-box path is easier to inspect directly:
|
|
70
|
+
|
|
71
|
+
- default protocol lane: `mcp`
|
|
72
|
+
- default payment protocol: `x402`
|
|
73
|
+
- default settlement center: built-in chain settlement across the canonical bundled settlement modes
|
|
74
|
+
- default treasury landing posture: account treasury destination by settlement mode
|
|
75
|
+
|
|
76
|
+
That same default center is also reflected in direct helper paths for default MCP usage, so the default path can be previewed or quoted without repeating the full integration-selection story each time.
|
|
77
|
+
|
|
69
78
|
## Package Surface
|
|
70
79
|
|
|
71
80
|
The SDK is broad, but it stays organized into a few repeatable families instead of one-off surfaces.
|
|
@@ -195,6 +204,14 @@ The promotion-readiness layer now makes that posture explicit as review data:
|
|
|
195
204
|
|
|
196
205
|
That distinction matters as the registry grows.
|
|
197
206
|
|
|
207
|
+
The promotion-action preview layer now builds on top of that readiness data without introducing mutation:
|
|
208
|
+
|
|
209
|
+
- action previews stay read-only
|
|
210
|
+
- current posture and resulting posture are both visible
|
|
211
|
+
- requested action validity is explicit
|
|
212
|
+
- blockers and blocker categories remain inspectable as data
|
|
213
|
+
- the preview layer explains what would change before any future control-plane work exists
|
|
214
|
+
|
|
198
215
|
There is also a small repo-local registry CLI for reviewer/operator use when working from a cloned `xytara` repository:
|
|
199
216
|
|
|
200
217
|
- `node scripts/registry_cli.js validate-bundle --example protocol`
|
|
@@ -207,6 +224,9 @@ There is also a small repo-local registry CLI for reviewer/operator use when wor
|
|
|
207
224
|
- `node scripts/registry_cli.js review-bundle-set`
|
|
208
225
|
- `node scripts/registry_cli.js review-snapshot`
|
|
209
226
|
- `node scripts/registry_cli.js promotion-readiness --integration partner.protocol.acme_mcp`
|
|
227
|
+
- `node scripts/registry_cli.js promotion-action-preview --integration partner.protocol.acme_mcp --action complete_certification`
|
|
228
|
+
- `node scripts/registry_cli.js promotion-action-set --integration partner.protocol.acme_mcp`
|
|
229
|
+
- `node scripts/registry_cli.js promotion-action-set-summary --source third_party_example --bundled false`
|
|
210
230
|
|
|
211
231
|
## Integration Selection
|
|
212
232
|
|
|
@@ -340,6 +360,9 @@ Primary service routes:
|
|
|
340
360
|
- `GET /v1/integrations/settlement-modes`
|
|
341
361
|
- `GET /v1/integrations/promotion-readiness`
|
|
342
362
|
- `GET /v1/integrations/:integration_id/promotion-readiness`
|
|
363
|
+
- `GET /v1/integrations/promotion-actions`
|
|
364
|
+
- `GET /v1/integrations/:integration_id/promotion-actions`
|
|
365
|
+
- `POST /v1/integrations/promotion-actions/preview`
|
|
343
366
|
- `POST /v1/integrations/review/submission-bundle`
|
|
344
367
|
- `POST /v1/integrations/review/submission-bundle-set`
|
|
345
368
|
- `POST /v1/integrations/review/registry-snapshot`
|
package/index.js
CHANGED
|
@@ -32,11 +32,15 @@ const {
|
|
|
32
32
|
summarizeIntegrationRegistrySnapshotReview,
|
|
33
33
|
summarizeIntegrationPromotionReadiness,
|
|
34
34
|
summarizeIntegrationPromotionWorkflow,
|
|
35
|
-
summarizeIntegrationPromotionWorkflowList
|
|
35
|
+
summarizeIntegrationPromotionWorkflowList,
|
|
36
|
+
validatePromotionActionRequest,
|
|
37
|
+
summarizeIntegrationPromotionActionPreview,
|
|
38
|
+
summarizeIntegrationPromotionActionSet,
|
|
39
|
+
summarizeIntegrationPromotionActionSetList
|
|
36
40
|
} = require("./integrations/registry");
|
|
37
41
|
|
|
38
42
|
const COMMERCE_SDK_NAME = "xytara";
|
|
39
|
-
const COMMERCE_SDK_VERSION = "1.
|
|
43
|
+
const COMMERCE_SDK_VERSION = "1.5.0";
|
|
40
44
|
const COMMERCE_API_VERSION = "v1";
|
|
41
45
|
|
|
42
46
|
function createClient(options) {
|
|
@@ -77,5 +81,9 @@ module.exports = {
|
|
|
77
81
|
summarizeIntegrationPromotionReadiness,
|
|
78
82
|
summarizeIntegrationPromotionWorkflow,
|
|
79
83
|
summarizeIntegrationPromotionWorkflowList,
|
|
84
|
+
validatePromotionActionRequest,
|
|
85
|
+
summarizeIntegrationPromotionActionPreview,
|
|
86
|
+
summarizeIntegrationPromotionActionSet,
|
|
87
|
+
summarizeIntegrationPromotionActionSetList,
|
|
80
88
|
validateAdapterImplementation
|
|
81
89
|
};
|
package/integrations/registry.js
CHANGED
|
@@ -681,6 +681,266 @@ function buildPromotionRecommendationSummary(readiness = {}) {
|
|
|
681
681
|
};
|
|
682
682
|
}
|
|
683
683
|
|
|
684
|
+
const PROMOTION_ACTION_DEFINITIONS = {
|
|
685
|
+
register_integration: {
|
|
686
|
+
action: "register_integration",
|
|
687
|
+
title: "Register Integration",
|
|
688
|
+
stage: "registration",
|
|
689
|
+
description: "Move an integration into an explicit staged registration posture."
|
|
690
|
+
},
|
|
691
|
+
complete_certification: {
|
|
692
|
+
action: "complete_certification",
|
|
693
|
+
title: "Complete Certification",
|
|
694
|
+
stage: "certification",
|
|
695
|
+
description: "Mark the integration as certified for the current public contract."
|
|
696
|
+
},
|
|
697
|
+
promote_maturity: {
|
|
698
|
+
action: "promote_maturity",
|
|
699
|
+
title: "Promote Maturity",
|
|
700
|
+
stage: "maturity",
|
|
701
|
+
description: "Align integration maturity with production-default rollout posture."
|
|
702
|
+
},
|
|
703
|
+
enable_default_selection: {
|
|
704
|
+
action: "enable_default_selection",
|
|
705
|
+
title: "Enable Default Selection",
|
|
706
|
+
stage: "selection",
|
|
707
|
+
description: "Allow the integration to participate in default selection instead of explicit-only use."
|
|
708
|
+
},
|
|
709
|
+
bundle_for_default_rollout: {
|
|
710
|
+
action: "bundle_for_default_rollout",
|
|
711
|
+
title: "Bundle For Default Rollout",
|
|
712
|
+
stage: "rollout",
|
|
713
|
+
description: "Mark the integration as bundled for production-default rollout."
|
|
714
|
+
},
|
|
715
|
+
maintain_production_default: {
|
|
716
|
+
action: "maintain_production_default",
|
|
717
|
+
title: "Maintain Production Default",
|
|
718
|
+
stage: "steady_state",
|
|
719
|
+
description: "Confirm the integration already satisfies production-default posture."
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
function getPromotionActionDefinition(action) {
|
|
724
|
+
const lookup = String(action || "").trim();
|
|
725
|
+
return PROMOTION_ACTION_DEFINITIONS[lookup] || null;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
function clonePromotionSubject(summary = {}) {
|
|
729
|
+
return {
|
|
730
|
+
registration: clone(summary.registration || {}),
|
|
731
|
+
certification_state: summary.certification_state || null,
|
|
732
|
+
integration_maturity: summary.integration_maturity || null
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
function simulatePromotionActionSubject(summary = {}, action) {
|
|
737
|
+
const subject = clonePromotionSubject(summary);
|
|
738
|
+
switch (action) {
|
|
739
|
+
case "register_integration":
|
|
740
|
+
subject.registration.registration_state = "staging_registered";
|
|
741
|
+
if (subject.registration.default_selection_enabled !== true) {
|
|
742
|
+
subject.registration.default_selection_enabled = false;
|
|
743
|
+
}
|
|
744
|
+
if (subject.registration.requires_explicit_selection !== false) {
|
|
745
|
+
subject.registration.requires_explicit_selection = true;
|
|
746
|
+
}
|
|
747
|
+
break;
|
|
748
|
+
case "complete_certification":
|
|
749
|
+
subject.certification_state = "certified";
|
|
750
|
+
break;
|
|
751
|
+
case "promote_maturity":
|
|
752
|
+
subject.integration_maturity = "production_default";
|
|
753
|
+
break;
|
|
754
|
+
case "enable_default_selection":
|
|
755
|
+
subject.registration.default_selection_enabled = true;
|
|
756
|
+
subject.registration.requires_explicit_selection = false;
|
|
757
|
+
break;
|
|
758
|
+
case "bundle_for_default_rollout":
|
|
759
|
+
subject.registration.bundled = true;
|
|
760
|
+
break;
|
|
761
|
+
case "maintain_production_default":
|
|
762
|
+
break;
|
|
763
|
+
default:
|
|
764
|
+
break;
|
|
765
|
+
}
|
|
766
|
+
return subject;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
function buildPromotionActionResultingReadiness(summary = {}, subject = {}) {
|
|
770
|
+
return buildPromotionReadinessSummary({
|
|
771
|
+
registration: subject.registration,
|
|
772
|
+
certification: {
|
|
773
|
+
certification_state: subject.certification_state || summary.certification_state || null
|
|
774
|
+
},
|
|
775
|
+
integration: {
|
|
776
|
+
integration_maturity: subject.integration_maturity || summary.integration_maturity || null
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
function buildPromotionActionStateChanges(current = {}, simulated = {}) {
|
|
782
|
+
const changes = [];
|
|
783
|
+
const currentRegistration = current.registration || {};
|
|
784
|
+
const simulatedRegistration = simulated.registration || {};
|
|
785
|
+
const fieldPairs = [
|
|
786
|
+
["registration.registration_state", currentRegistration.registration_state, simulatedRegistration.registration_state],
|
|
787
|
+
["registration.default_selection_enabled", currentRegistration.default_selection_enabled, simulatedRegistration.default_selection_enabled],
|
|
788
|
+
["registration.requires_explicit_selection", currentRegistration.requires_explicit_selection, simulatedRegistration.requires_explicit_selection],
|
|
789
|
+
["registration.bundled", currentRegistration.bundled, simulatedRegistration.bundled],
|
|
790
|
+
["certification_state", current.certification_state, simulated.certification_state],
|
|
791
|
+
["integration_maturity", current.integration_maturity, simulated.integration_maturity]
|
|
792
|
+
];
|
|
793
|
+
fieldPairs.forEach(([field, fromValue, toValue]) => {
|
|
794
|
+
if (fromValue !== toValue) {
|
|
795
|
+
changes.push({
|
|
796
|
+
field,
|
|
797
|
+
from: fromValue === undefined ? null : fromValue,
|
|
798
|
+
to: toValue === undefined ? null : toValue
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
return changes;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
function validatePromotionActionRequest(request = {}) {
|
|
806
|
+
const entry = request && typeof request === "object" && !Array.isArray(request) ? request : {};
|
|
807
|
+
const errors = [];
|
|
808
|
+
const integrationId = String(entry.integration_id || "").trim();
|
|
809
|
+
const action = String(entry.action || "").trim();
|
|
810
|
+
if (!integrationId) {
|
|
811
|
+
errors.push("promotion_action_request.integration_id is required");
|
|
812
|
+
}
|
|
813
|
+
if (!action) {
|
|
814
|
+
errors.push("promotion_action_request.action is required");
|
|
815
|
+
} else if (!getPromotionActionDefinition(action)) {
|
|
816
|
+
errors.push("promotion_action_request.action must be a supported promotion action");
|
|
817
|
+
}
|
|
818
|
+
return {
|
|
819
|
+
ok: errors.length === 0,
|
|
820
|
+
errors,
|
|
821
|
+
request: {
|
|
822
|
+
integration_id: integrationId || null,
|
|
823
|
+
action: action || null
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
function summarizeIntegrationPromotionActionPreview(request = {}) {
|
|
829
|
+
const validation = validatePromotionActionRequest(request);
|
|
830
|
+
if (!validation.ok) {
|
|
831
|
+
return {
|
|
832
|
+
ok: false,
|
|
833
|
+
reason: "invalid_promotion_action_request",
|
|
834
|
+
errors: validation.errors
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
const workflow = summarizeIntegrationPromotionWorkflow(validation.request.integration_id);
|
|
838
|
+
if (!workflow.ok) {
|
|
839
|
+
return workflow;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
const action = validation.request.action;
|
|
843
|
+
const definition = getPromotionActionDefinition(action);
|
|
844
|
+
const currentSubject = clonePromotionSubject(workflow);
|
|
845
|
+
const simulatedSubject = simulatePromotionActionSubject(workflow, action);
|
|
846
|
+
const resultingReadiness = buildPromotionActionResultingReadiness(workflow, simulatedSubject);
|
|
847
|
+
const stateChanges = buildPromotionActionStateChanges(currentSubject, simulatedSubject);
|
|
848
|
+
const currentNextAction = workflow.next_transition && workflow.next_transition.action
|
|
849
|
+
? workflow.next_transition.action
|
|
850
|
+
: null;
|
|
851
|
+
const currentLaterActions = Array.isArray(workflow.next_transition && workflow.next_transition.later_actions)
|
|
852
|
+
? workflow.next_transition.later_actions
|
|
853
|
+
: [];
|
|
854
|
+
const validNow = currentNextAction === action || currentLaterActions.includes(action);
|
|
855
|
+
const invalidReasons = [];
|
|
856
|
+
if (!validNow) {
|
|
857
|
+
invalidReasons.push(action === "maintain_production_default"
|
|
858
|
+
? "integration_is_not_yet_production_default_ready"
|
|
859
|
+
: "action_is_not_currently_recommended_from_present_posture");
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
return {
|
|
863
|
+
ok: true,
|
|
864
|
+
integration_id: workflow.integration_id,
|
|
865
|
+
display_name: workflow.display_name,
|
|
866
|
+
adapter_class: workflow.adapter_class,
|
|
867
|
+
source: workflow.source,
|
|
868
|
+
request: clone(validation.request),
|
|
869
|
+
action: clone(definition),
|
|
870
|
+
current_posture: {
|
|
871
|
+
registration_state: workflow.registration.registration_state || null,
|
|
872
|
+
certification_state: workflow.certification_state || null,
|
|
873
|
+
integration_maturity: workflow.integration_maturity || null,
|
|
874
|
+
promotion_readiness: clone(workflow.promotion_readiness || {})
|
|
875
|
+
},
|
|
876
|
+
valid_now: validNow,
|
|
877
|
+
is_recommended_next: currentNextAction === action,
|
|
878
|
+
invalid_reasons: invalidReasons,
|
|
879
|
+
requirements: currentNextAction === action
|
|
880
|
+
? clone(workflow.next_transition.requirements || [])
|
|
881
|
+
: clone(buildNextTransitionSummary(resultingReadiness).requirements || []),
|
|
882
|
+
blockers: clone(workflow.promotion_readiness.blockers || []),
|
|
883
|
+
blocker_categories: clone(workflow.blocker_categories || []),
|
|
884
|
+
resulting_posture: {
|
|
885
|
+
registration_state: simulatedSubject.registration.registration_state || null,
|
|
886
|
+
certification_state: simulatedSubject.certification_state || null,
|
|
887
|
+
integration_maturity: simulatedSubject.integration_maturity || null,
|
|
888
|
+
promotion_readiness: clone(resultingReadiness)
|
|
889
|
+
},
|
|
890
|
+
state_changes: stateChanges,
|
|
891
|
+
current_transition: clone(workflow.next_transition || {}),
|
|
892
|
+
resulting_transition: buildNextTransitionSummary(resultingReadiness)
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
function summarizeIntegrationPromotionActionSet(integrationOrId) {
|
|
897
|
+
const workflow = summarizeIntegrationPromotionWorkflow(integrationOrId);
|
|
898
|
+
if (!workflow.ok) {
|
|
899
|
+
return workflow;
|
|
900
|
+
}
|
|
901
|
+
const actionOrder = [
|
|
902
|
+
workflow.next_transition && workflow.next_transition.action ? workflow.next_transition.action : null,
|
|
903
|
+
...(Array.isArray(workflow.next_transition && workflow.next_transition.later_actions)
|
|
904
|
+
? workflow.next_transition.later_actions
|
|
905
|
+
: []),
|
|
906
|
+
"maintain_production_default"
|
|
907
|
+
].filter(Boolean);
|
|
908
|
+
const actions = sortStrings(actionOrder).map((action) => summarizeIntegrationPromotionActionPreview({
|
|
909
|
+
integration_id: workflow.integration_id,
|
|
910
|
+
action
|
|
911
|
+
}));
|
|
912
|
+
return {
|
|
913
|
+
...workflow,
|
|
914
|
+
action_count: actions.length,
|
|
915
|
+
valid_now_count: actions.filter((entry) => entry.valid_now === true).length,
|
|
916
|
+
actions
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
function summarizeIntegrationPromotionActionSetList(filters = {}) {
|
|
921
|
+
const integrations = listIntegrations(filters).map((integration) => summarizeIntegrationPromotionActionSet(integration));
|
|
922
|
+
return {
|
|
923
|
+
ok: true,
|
|
924
|
+
integration_count: integrations.length,
|
|
925
|
+
valid_now_count: integrations.reduce((total, entry) => total + Number(entry.valid_now_count || 0), 0),
|
|
926
|
+
recommended_actions: summarizeCounts(
|
|
927
|
+
integrations
|
|
928
|
+
.map((entry) => entry.next_transition && entry.next_transition.action)
|
|
929
|
+
.filter(Boolean),
|
|
930
|
+
"action"
|
|
931
|
+
),
|
|
932
|
+
valid_actions: summarizeCounts(
|
|
933
|
+
integrations
|
|
934
|
+
.flatMap((entry) => Array.isArray(entry.actions) ? entry.actions : [])
|
|
935
|
+
.filter((entry) => entry.valid_now === true)
|
|
936
|
+
.map((entry) => entry.request && entry.request.action)
|
|
937
|
+
.filter(Boolean),
|
|
938
|
+
"action"
|
|
939
|
+
),
|
|
940
|
+
integrations
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
|
|
684
944
|
function buildPromotionActionQueues(integrations = []) {
|
|
685
945
|
const rows = Array.isArray(integrations) ? integrations.filter((entry) => entry && entry.next_transition) : [];
|
|
686
946
|
const groups = new Map();
|
|
@@ -1631,6 +1891,10 @@ module.exports = {
|
|
|
1631
1891
|
summarizeIntegrationPromotionReadiness,
|
|
1632
1892
|
summarizeIntegrationPromotionWorkflow,
|
|
1633
1893
|
summarizeIntegrationPromotionWorkflowList,
|
|
1894
|
+
validatePromotionActionRequest,
|
|
1895
|
+
summarizeIntegrationPromotionActionPreview,
|
|
1896
|
+
summarizeIntegrationPromotionActionSet,
|
|
1897
|
+
summarizeIntegrationPromotionActionSetList,
|
|
1634
1898
|
createRegisteredIntegrationFromManifest,
|
|
1635
1899
|
buildIntegrationRegistrationView,
|
|
1636
1900
|
buildIntegrationView
|
package/lib/catalog_contract.js
CHANGED
|
@@ -2,6 +2,89 @@
|
|
|
2
2
|
|
|
3
3
|
const { catalog, findTask, findWorkflow } = require("../fixtures/catalog");
|
|
4
4
|
|
|
5
|
+
function buildDefaultTransactionCenter() {
|
|
6
|
+
const settlementProfiles = Array.isArray(catalog.settlement_profiles) ? catalog.settlement_profiles : [];
|
|
7
|
+
const defaultSettlementProfile = settlementProfiles[0] || null;
|
|
8
|
+
const settlementModes = settlementProfiles
|
|
9
|
+
.map((profile) => profile && profile.mode)
|
|
10
|
+
.filter(Boolean);
|
|
11
|
+
return {
|
|
12
|
+
ok: true,
|
|
13
|
+
brand: "xytara",
|
|
14
|
+
product: "default transaction center",
|
|
15
|
+
payment_scheme: catalog.payment_scheme,
|
|
16
|
+
default_protocol: {
|
|
17
|
+
protocol: "mcp",
|
|
18
|
+
integration_id: "builtin.protocol.mcp",
|
|
19
|
+
task_ref: "adapter.mcp.invoke",
|
|
20
|
+
workflow_refs: ["a2c.tooling.flow"],
|
|
21
|
+
selection_reason: "production_default_protocol_lane"
|
|
22
|
+
},
|
|
23
|
+
default_payment: {
|
|
24
|
+
protocol: "x402",
|
|
25
|
+
integration_id: "builtin.payment.x402",
|
|
26
|
+
payment_scheme: catalog.payment_scheme,
|
|
27
|
+
supported_settlement_modes: settlementModes,
|
|
28
|
+
selection_reason: "production_default_payment_lane"
|
|
29
|
+
},
|
|
30
|
+
default_settlement: {
|
|
31
|
+
integration_id: "builtin.settlement.chain",
|
|
32
|
+
settlement_mode: defaultSettlementProfile && defaultSettlementProfile.mode ? defaultSettlementProfile.mode : null,
|
|
33
|
+
adapter: defaultSettlementProfile && defaultSettlementProfile.adapter ? defaultSettlementProfile.adapter : null,
|
|
34
|
+
asset: defaultSettlementProfile && defaultSettlementProfile.asset ? defaultSettlementProfile.asset : null,
|
|
35
|
+
payee_agent_id: defaultSettlementProfile && defaultSettlementProfile.payee_agent_id ? defaultSettlementProfile.payee_agent_id : null,
|
|
36
|
+
payee_label: defaultSettlementProfile && defaultSettlementProfile.payee_label ? defaultSettlementProfile.payee_label : null,
|
|
37
|
+
supported_modes: settlementModes,
|
|
38
|
+
profile_count: settlementProfiles.length
|
|
39
|
+
},
|
|
40
|
+
default_treasury: {
|
|
41
|
+
destination_kind: "account_treasury",
|
|
42
|
+
destination_template: "treasury_{account_id}",
|
|
43
|
+
settlement_mode: defaultSettlementProfile && defaultSettlementProfile.mode ? defaultSettlementProfile.mode : null,
|
|
44
|
+
payee_agent_id: defaultSettlementProfile && defaultSettlementProfile.payee_agent_id ? defaultSettlementProfile.payee_agent_id : null,
|
|
45
|
+
payee_label: defaultSettlementProfile && defaultSettlementProfile.payee_label ? defaultSettlementProfile.payee_label : null
|
|
46
|
+
},
|
|
47
|
+
suggested_paths: [
|
|
48
|
+
{
|
|
49
|
+
path_id: "default_mcp_x402_path",
|
|
50
|
+
path_kind: "first_party_default",
|
|
51
|
+
protocol: "mcp",
|
|
52
|
+
payment_protocol: "x402",
|
|
53
|
+
settlement_mode: defaultSettlementProfile && defaultSettlementProfile.mode ? defaultSettlementProfile.mode : null,
|
|
54
|
+
task_ref: "adapter.mcp.invoke",
|
|
55
|
+
integration_ids: ["builtin.protocol.mcp", "builtin.payment.x402", "builtin.settlement.chain"]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
path_id: "default_a2c_tooling_flow",
|
|
59
|
+
path_kind: "first_party_default",
|
|
60
|
+
protocol: "mcp",
|
|
61
|
+
payment_protocol: "x402",
|
|
62
|
+
settlement_mode: defaultSettlementProfile && defaultSettlementProfile.mode ? defaultSettlementProfile.mode : null,
|
|
63
|
+
workflow_ref: "a2c.tooling.flow",
|
|
64
|
+
integration_ids: ["builtin.protocol.mcp", "builtin.payment.x402", "builtin.settlement.chain"]
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function summarizeDefaultTransactionCenter() {
|
|
71
|
+
const center = buildDefaultTransactionCenter();
|
|
72
|
+
return {
|
|
73
|
+
ok: true,
|
|
74
|
+
brand: center.brand,
|
|
75
|
+
product: center.product,
|
|
76
|
+
payment_scheme: center.payment_scheme,
|
|
77
|
+
default_protocol: center.default_protocol.protocol,
|
|
78
|
+
default_payment_protocol: center.default_payment.protocol,
|
|
79
|
+
default_settlement_mode: center.default_settlement.settlement_mode,
|
|
80
|
+
default_treasury_kind: center.default_treasury.destination_kind,
|
|
81
|
+
settlement_mode_count: Array.isArray(center.default_settlement.supported_modes) ? center.default_settlement.supported_modes.length : 0,
|
|
82
|
+
settlement_modes: center.default_settlement.supported_modes,
|
|
83
|
+
suggested_path_count: Array.isArray(center.suggested_paths) ? center.suggested_paths.length : 0,
|
|
84
|
+
suggested_paths: center.suggested_paths
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
5
88
|
function buildCatalogResponse() {
|
|
6
89
|
return {
|
|
7
90
|
ok: true,
|
|
@@ -133,9 +216,11 @@ function getWorkflowDetail(ref) {
|
|
|
133
216
|
|
|
134
217
|
module.exports = {
|
|
135
218
|
buildCatalogResponse,
|
|
219
|
+
buildDefaultTransactionCenter,
|
|
136
220
|
getCatalog,
|
|
137
221
|
getTaskDetail,
|
|
138
222
|
getWorkflowDetail,
|
|
139
223
|
getWorkflowList,
|
|
140
|
-
summarizeCatalog
|
|
224
|
+
summarizeCatalog,
|
|
225
|
+
summarizeDefaultTransactionCenter
|
|
141
226
|
};
|
package/lib/commerce_client.js
CHANGED
|
@@ -866,6 +866,34 @@ function summarizeCatalogPayload(payload) {
|
|
|
866
866
|
};
|
|
867
867
|
}
|
|
868
868
|
|
|
869
|
+
function summarizeDefaultTransactionCenterPayload(payload) {
|
|
870
|
+
const center = payload && typeof payload === "object" ? payload : {};
|
|
871
|
+
return {
|
|
872
|
+
ok: center.ok === true,
|
|
873
|
+
brand: center.brand || null,
|
|
874
|
+
product: center.product || null,
|
|
875
|
+
default_protocol: center.default_protocol && center.default_protocol.protocol
|
|
876
|
+
? center.default_protocol.protocol
|
|
877
|
+
: center.default_protocol || null,
|
|
878
|
+
default_payment_protocol: center.default_payment && center.default_payment.protocol
|
|
879
|
+
? center.default_payment.protocol
|
|
880
|
+
: center.default_payment_protocol || null,
|
|
881
|
+
default_settlement_mode: center.default_settlement && center.default_settlement.settlement_mode
|
|
882
|
+
? center.default_settlement.settlement_mode
|
|
883
|
+
: center.default_settlement_mode || null,
|
|
884
|
+
default_treasury_kind: center.default_treasury && center.default_treasury.destination_kind
|
|
885
|
+
? center.default_treasury.destination_kind
|
|
886
|
+
: center.default_treasury_kind || null,
|
|
887
|
+
settlement_mode_count: Array.isArray(center.default_settlement && center.default_settlement.supported_modes)
|
|
888
|
+
? center.default_settlement.supported_modes.length
|
|
889
|
+
: Number(center.settlement_mode_count || 0),
|
|
890
|
+
suggested_path_count: Array.isArray(center.suggested_paths)
|
|
891
|
+
? center.suggested_paths.length
|
|
892
|
+
: Number(center.suggested_path_count || 0),
|
|
893
|
+
suggested_paths: Array.isArray(center.suggested_paths) ? center.suggested_paths : []
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
|
|
869
897
|
function buildCatalogSummarySource(client) {
|
|
870
898
|
const baseCatalog = client && client.catalogCache && typeof client.catalogCache === "object"
|
|
871
899
|
? client.catalogCache
|
|
@@ -1601,6 +1629,45 @@ class CommerceClient {
|
|
|
1601
1629
|
return result && result.data && Array.isArray(result.data.settlement_modes) ? result.data.settlement_modes : [];
|
|
1602
1630
|
}
|
|
1603
1631
|
|
|
1632
|
+
async getIntegrationPromotionReadiness(integrationId) {
|
|
1633
|
+
const result = await this.getJson(`/v1/integrations/${encodeURIComponent(integrationId)}/promotion-readiness`);
|
|
1634
|
+
return result && result.data ? result.data : { ok: false, reason: "integration_not_found" };
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
async listIntegrationPromotionReadiness(filters) {
|
|
1638
|
+
const suffix = buildQueryString(filters || {});
|
|
1639
|
+
const result = await this.getJson(`/v1/integrations/promotion-readiness${suffix}`);
|
|
1640
|
+
return result && result.data && Array.isArray(result.data.integrations) ? result.data.integrations : [];
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
async getIntegrationPromotionWorkflow(integrationId) {
|
|
1644
|
+
const result = await this.getJson(`/v1/integrations/${encodeURIComponent(integrationId)}/promotion-workflow`);
|
|
1645
|
+
return result && result.data ? result.data : { ok: false, reason: "integration_not_found" };
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
async listIntegrationPromotionWorkflows(filters) {
|
|
1649
|
+
const suffix = buildQueryString(filters || {});
|
|
1650
|
+
const result = await this.getJson(`/v1/integrations/promotion-workflow${suffix}`);
|
|
1651
|
+
return result && result.data ? result.data : { ok: true, integration_count: 0, integrations: [] };
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
async getIntegrationPromotionActionSet(integrationId) {
|
|
1655
|
+
const result = await this.getJson(`/v1/integrations/${encodeURIComponent(integrationId)}/promotion-actions`);
|
|
1656
|
+
return result && result.data ? result.data : { ok: false, reason: "integration_not_found" };
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
async listIntegrationPromotionActionSets(filters) {
|
|
1660
|
+
const suffix = buildQueryString(filters || {});
|
|
1661
|
+
const result = await this.getJson(`/v1/integrations/promotion-actions${suffix}`);
|
|
1662
|
+
return result && result.data ? result.data : { ok: true, integration_count: 0, integrations: [] };
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
async previewIntegrationPromotionAction(request) {
|
|
1666
|
+
const payload = request && typeof request === "object" && !Array.isArray(request) ? request : {};
|
|
1667
|
+
const result = await this.postJson("/v1/integrations/promotion-actions/preview", {}, payload);
|
|
1668
|
+
return result && result.data ? result.data : { ok: false, reason: "invalid_promotion_action_request" };
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1604
1671
|
async getTaskExecutionModeSummaries(forceRefresh) {
|
|
1605
1672
|
const tasks = await this.listTasks(forceRefresh);
|
|
1606
1673
|
return summarizeFacetCounts(
|
|
@@ -2259,6 +2326,23 @@ class CommerceClient {
|
|
|
2259
2326
|
return summarizeSettlementPayees(profiles);
|
|
2260
2327
|
}
|
|
2261
2328
|
|
|
2329
|
+
async getDefaultTransactionCenter(forceRefresh) {
|
|
2330
|
+
if (!forceRefresh && this.catalogSummaryCache && this.catalogSummaryCache.defaultTransactionCenter) {
|
|
2331
|
+
return this.catalogSummaryCache.defaultTransactionCenter;
|
|
2332
|
+
}
|
|
2333
|
+
const result = await this.getJson("/v1/transaction-center");
|
|
2334
|
+
if (!forceRefresh) {
|
|
2335
|
+
this.catalogSummaryCache = this.catalogSummaryCache || {};
|
|
2336
|
+
this.catalogSummaryCache.defaultTransactionCenter = result.data;
|
|
2337
|
+
}
|
|
2338
|
+
return result.data;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
async getDefaultTransactionCenterSummary(forceRefresh) {
|
|
2342
|
+
const center = await this.getDefaultTransactionCenter(forceRefresh);
|
|
2343
|
+
return this.summarizeDefaultTransactionCenter(center);
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2262
2346
|
async listSettlementPayees(forceRefresh) {
|
|
2263
2347
|
const summary = await this.getSettlementPayeeSummaries(forceRefresh);
|
|
2264
2348
|
return extractSummaryValues(summary, "settlement_payees", "payee_agent_id");
|
|
@@ -3341,6 +3425,81 @@ class CommerceClient {
|
|
|
3341
3425
|
return this.summarizeCommandResult(result);
|
|
3342
3426
|
}
|
|
3343
3427
|
|
|
3428
|
+
async previewDefaultMcpToolQuote(toolName, args, options) {
|
|
3429
|
+
const opts = options || {};
|
|
3430
|
+
return this.previewTaskSetQuote([
|
|
3431
|
+
{
|
|
3432
|
+
task_ref: "adapter.mcp.invoke",
|
|
3433
|
+
body: {
|
|
3434
|
+
tool_name: String(toolName || "").trim(),
|
|
3435
|
+
arguments: args && typeof args === "object" && !Array.isArray(args) ? args : {}
|
|
3436
|
+
}
|
|
3437
|
+
}
|
|
3438
|
+
], {
|
|
3439
|
+
...opts,
|
|
3440
|
+
command: opts.command || `default.mcp.preview:${String(toolName || "").trim() || "tool"}`,
|
|
3441
|
+
protocol: opts.protocol || "mcp",
|
|
3442
|
+
paymentProtocol: opts.paymentProtocol || "x402",
|
|
3443
|
+
integrationId: opts.integrationId || "builtin.protocol.mcp",
|
|
3444
|
+
integrationIds: Array.isArray(opts.integrationIds) && opts.integrationIds.length > 0
|
|
3445
|
+
? opts.integrationIds
|
|
3446
|
+
: ["builtin.protocol.mcp", "builtin.payment.x402", "builtin.settlement.chain"],
|
|
3447
|
+
settlementMode: opts.settlementMode || "evm_payment"
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
|
|
3451
|
+
async previewDefaultMcpToolQuoteSummary(toolName, args, options) {
|
|
3452
|
+
const preview = await this.previewDefaultMcpToolQuote(toolName, args, options);
|
|
3453
|
+
return this.summarizeQuotePreview(preview);
|
|
3454
|
+
}
|
|
3455
|
+
|
|
3456
|
+
async createDefaultMcpToolQuote(toolName, args, options) {
|
|
3457
|
+
const opts = options || {};
|
|
3458
|
+
return this.createTaskSetQuote([
|
|
3459
|
+
{
|
|
3460
|
+
task_ref: "adapter.mcp.invoke",
|
|
3461
|
+
body: {
|
|
3462
|
+
tool_name: String(toolName || "").trim(),
|
|
3463
|
+
arguments: args && typeof args === "object" && !Array.isArray(args) ? args : {}
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3466
|
+
], {
|
|
3467
|
+
...opts,
|
|
3468
|
+
command: opts.command || `default.mcp.quote:${String(toolName || "").trim() || "tool"}`,
|
|
3469
|
+
protocol: opts.protocol || "mcp",
|
|
3470
|
+
paymentProtocol: opts.paymentProtocol || "x402",
|
|
3471
|
+
integrationId: opts.integrationId || "builtin.protocol.mcp",
|
|
3472
|
+
integrationIds: Array.isArray(opts.integrationIds) && opts.integrationIds.length > 0
|
|
3473
|
+
? opts.integrationIds
|
|
3474
|
+
: ["builtin.protocol.mcp", "builtin.payment.x402", "builtin.settlement.chain"],
|
|
3475
|
+
settlementMode: opts.settlementMode || "evm_payment"
|
|
3476
|
+
});
|
|
3477
|
+
}
|
|
3478
|
+
|
|
3479
|
+
async createDefaultMcpToolQuoteSummary(toolName, args, options) {
|
|
3480
|
+
const quote = await this.createDefaultMcpToolQuote(toolName, args, options);
|
|
3481
|
+
return this.summarizeQuote(quote);
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
async invokeDefaultMcpTool(toolName, args, options) {
|
|
3485
|
+
const opts = options || {};
|
|
3486
|
+
return this.invokeMcpTool(toolName, args, {
|
|
3487
|
+
...opts,
|
|
3488
|
+
protocol: opts.protocol || "mcp",
|
|
3489
|
+
paymentProtocol: opts.paymentProtocol || "x402",
|
|
3490
|
+
integrationId: opts.integrationId || "builtin.protocol.mcp",
|
|
3491
|
+
integrationIds: Array.isArray(opts.integrationIds) && opts.integrationIds.length > 0
|
|
3492
|
+
? opts.integrationIds
|
|
3493
|
+
: ["builtin.protocol.mcp", "builtin.payment.x402", "builtin.settlement.chain"],
|
|
3494
|
+
settlementMode: opts.settlementMode || "evm_payment"
|
|
3495
|
+
});
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3498
|
+
async invokeDefaultMcpToolSummary(toolName, args, options) {
|
|
3499
|
+
const result = await this.invokeDefaultMcpTool(toolName, args, options);
|
|
3500
|
+
return this.summarizeCommandResult(result);
|
|
3501
|
+
}
|
|
3502
|
+
|
|
3344
3503
|
async runNamedTaskRoute(path, payload) {
|
|
3345
3504
|
if (!this.apiKey || !this.walletId || !this.walletSecret) {
|
|
3346
3505
|
throw new Error("named task routes require apiKey, walletId, and walletSecret");
|
|
@@ -4820,6 +4979,10 @@ class CommerceClient {
|
|
|
4820
4979
|
return summarizeCatalogPayload(payload);
|
|
4821
4980
|
}
|
|
4822
4981
|
|
|
4982
|
+
summarizeDefaultTransactionCenter(payload) {
|
|
4983
|
+
return summarizeDefaultTransactionCenterPayload(payload);
|
|
4984
|
+
}
|
|
4985
|
+
|
|
4823
4986
|
summarizeTask(task) {
|
|
4824
4987
|
return summarizeCatalogTask(task);
|
|
4825
4988
|
}
|
|
@@ -5571,6 +5734,7 @@ module.exports = {
|
|
|
5571
5734
|
extractTrailingIdFromUrl,
|
|
5572
5735
|
summarizeQuotePayload,
|
|
5573
5736
|
summarizeQuotePreviewPayload,
|
|
5737
|
+
summarizeDefaultTransactionCenterPayload,
|
|
5574
5738
|
summarizeActivitySnapshotPayload,
|
|
5575
5739
|
summarizeOpenIssuesPayload,
|
|
5576
5740
|
summarizeExecutionExceptionsPayload,
|
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -4,11 +4,13 @@ const http = require("http");
|
|
|
4
4
|
const { URL } = require("url");
|
|
5
5
|
const { readJsonBody, sendJson } = require("./lib/http_transport");
|
|
6
6
|
const {
|
|
7
|
+
buildDefaultTransactionCenter,
|
|
7
8
|
getCatalog,
|
|
8
9
|
getTaskDetail,
|
|
9
10
|
getWorkflowDetail,
|
|
10
11
|
getWorkflowList,
|
|
11
|
-
summarizeCatalog
|
|
12
|
+
summarizeCatalog,
|
|
13
|
+
summarizeDefaultTransactionCenter
|
|
12
14
|
} = require("./lib/catalog_contract");
|
|
13
15
|
const {
|
|
14
16
|
createCommandResult,
|
|
@@ -55,6 +57,9 @@ const {
|
|
|
55
57
|
summarizeIntegrationPromotionReadiness,
|
|
56
58
|
summarizeIntegrationPromotionWorkflow,
|
|
57
59
|
summarizeIntegrationPromotionWorkflowList,
|
|
60
|
+
summarizeIntegrationPromotionActionPreview,
|
|
61
|
+
summarizeIntegrationPromotionActionSet,
|
|
62
|
+
summarizeIntegrationPromotionActionSetList,
|
|
58
63
|
summarizeIntegrationRegistrySnapshotReview,
|
|
59
64
|
summarizeIntegrationSubmissionBundleReview,
|
|
60
65
|
summarizeIntegrationSubmissionBundleSetReview,
|
|
@@ -373,6 +378,16 @@ async function routeRequest(req, res) {
|
|
|
373
378
|
return;
|
|
374
379
|
}
|
|
375
380
|
|
|
381
|
+
if (req.method === "GET" && url.pathname === "/v1/transaction-center") {
|
|
382
|
+
sendJson(res, 200, buildDefaultTransactionCenter());
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (req.method === "GET" && url.pathname === "/v1/transaction-center/summary") {
|
|
387
|
+
sendJson(res, 200, summarizeDefaultTransactionCenter());
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
|
|
376
391
|
if (req.method === "GET" && url.pathname === "/v1/catalog/task") {
|
|
377
392
|
const response = buildTaskDetailResponse(getTaskDetail(url.searchParams.get("ref")));
|
|
378
393
|
sendJson(res, response.status, response.payload);
|
|
@@ -508,6 +523,33 @@ async function routeRequest(req, res) {
|
|
|
508
523
|
return;
|
|
509
524
|
}
|
|
510
525
|
|
|
526
|
+
if (req.method === "GET" && url.pathname === "/v1/integrations/promotion-actions") {
|
|
527
|
+
const response = buildIntegrationListResponse({
|
|
528
|
+
...summarizeIntegrationPromotionActionSetList({
|
|
529
|
+
adapter_class: url.searchParams.get("class"),
|
|
530
|
+
protocol: url.searchParams.get("protocol"),
|
|
531
|
+
settlement_mode: url.searchParams.get("settlement_mode"),
|
|
532
|
+
capability: url.searchParams.get("capability"),
|
|
533
|
+
task_ref: url.searchParams.get("task_ref"),
|
|
534
|
+
source: url.searchParams.get("source"),
|
|
535
|
+
certification_state: url.searchParams.get("certification_state"),
|
|
536
|
+
integration_maturity: url.searchParams.get("integration_maturity"),
|
|
537
|
+
bundled: url.searchParams.get("bundled")
|
|
538
|
+
})
|
|
539
|
+
});
|
|
540
|
+
sendJson(res, response.status, response.payload);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (req.method === "POST" && url.pathname === "/v1/integrations/promotion-actions/preview") {
|
|
545
|
+
const body = await readJsonBody(req);
|
|
546
|
+
const response = buildIntegrationListResponse(
|
|
547
|
+
summarizeIntegrationPromotionActionPreview(body)
|
|
548
|
+
);
|
|
549
|
+
sendJson(res, response.status, response.payload);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
|
|
511
553
|
if (req.method === "GET" && url.pathname.startsWith("/v1/integrations/") && url.pathname.endsWith("/promotion-readiness")) {
|
|
512
554
|
const integrationId = getDecodedSuffixId(
|
|
513
555
|
url.pathname.slice(0, -"/promotion-readiness".length),
|
|
@@ -520,6 +562,18 @@ async function routeRequest(req, res) {
|
|
|
520
562
|
return;
|
|
521
563
|
}
|
|
522
564
|
|
|
565
|
+
if (req.method === "GET" && url.pathname.startsWith("/v1/integrations/") && url.pathname.endsWith("/promotion-actions")) {
|
|
566
|
+
const integrationId = getDecodedSuffixId(
|
|
567
|
+
url.pathname.slice(0, -"/promotion-actions".length),
|
|
568
|
+
"/v1/integrations/"
|
|
569
|
+
);
|
|
570
|
+
const response = buildIntegrationListResponse(
|
|
571
|
+
summarizeIntegrationPromotionActionSet(integrationId)
|
|
572
|
+
);
|
|
573
|
+
sendJson(res, response.status || 200, response.payload || response);
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
523
577
|
if (req.method === "GET" && url.pathname.startsWith("/v1/integrations/") && url.pathname.endsWith("/promotion-workflow")) {
|
|
524
578
|
const integrationId = getDecodedSuffixId(
|
|
525
579
|
url.pathname.slice(0, -"/promotion-workflow".length),
|