@atbas/m-mcp 0.1.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/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/builder/transaction-builder.d.ts +53 -0
- package/dist/builder/transaction-builder.d.ts.map +1 -0
- package/dist/builder/transaction-builder.js +159 -0
- package/dist/builder/transaction-builder.js.map +1 -0
- package/dist/catalogue/default-catalogue.d.ts +18 -0
- package/dist/catalogue/default-catalogue.d.ts.map +1 -0
- package/dist/catalogue/default-catalogue.js +21 -0
- package/dist/catalogue/default-catalogue.js.map +1 -0
- package/dist/catalogue/endpoints.d.ts +22 -0
- package/dist/catalogue/endpoints.d.ts.map +1 -0
- package/dist/catalogue/endpoints.js +24 -0
- package/dist/catalogue/endpoints.js.map +1 -0
- package/dist/catalogue/flows.d.ts +32 -0
- package/dist/catalogue/flows.d.ts.map +1 -0
- package/dist/catalogue/flows.js +64 -0
- package/dist/catalogue/flows.js.map +1 -0
- package/dist/catalogue/hash-options.d.ts +112 -0
- package/dist/catalogue/hash-options.d.ts.map +1 -0
- package/dist/catalogue/hash-options.js +151 -0
- package/dist/catalogue/hash-options.js.map +1 -0
- package/dist/catalogue/types.d.ts +279 -0
- package/dist/catalogue/types.d.ts.map +1 -0
- package/dist/catalogue/types.js +360 -0
- package/dist/catalogue/types.js.map +1 -0
- package/dist/codegen/generate.d.ts +14 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/generate.js +490 -0
- package/dist/codegen/generate.js.map +1 -0
- package/dist/codegen/languages/node.d.ts +3 -0
- package/dist/codegen/languages/node.d.ts.map +1 -0
- package/dist/codegen/languages/node.js +32 -0
- package/dist/codegen/languages/node.js.map +1 -0
- package/dist/codegen/languages/php.d.ts +3 -0
- package/dist/codegen/languages/php.d.ts.map +1 -0
- package/dist/codegen/languages/php.js +27 -0
- package/dist/codegen/languages/php.js.map +1 -0
- package/dist/codegen/languages/python.d.ts +3 -0
- package/dist/codegen/languages/python.d.ts.map +1 -0
- package/dist/codegen/languages/python.js +27 -0
- package/dist/codegen/languages/python.js.map +1 -0
- package/dist/codegen/renderer.d.ts +24 -0
- package/dist/codegen/renderer.d.ts.map +1 -0
- package/dist/codegen/renderer.js +59 -0
- package/dist/codegen/renderer.js.map +1 -0
- package/dist/codegen/types.d.ts +50 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/codegen/types.js +5 -0
- package/dist/codegen/types.js.map +1 -0
- package/dist/config/credentials.d.ts +64 -0
- package/dist/config/credentials.d.ts.map +1 -0
- package/dist/config/credentials.js +216 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/environment.d.ts +23 -0
- package/dist/config/environment.d.ts.map +1 -0
- package/dist/config/environment.js +54 -0
- package/dist/config/environment.js.map +1 -0
- package/dist/core/dependencies.d.ts +43 -0
- package/dist/core/dependencies.d.ts.map +1 -0
- package/dist/core/dependencies.js +2 -0
- package/dist/core/dependencies.js.map +1 -0
- package/dist/core/registry.d.ts +33 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +13 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/server.d.ts +61 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +90 -0
- package/dist/core/server.js.map +1 -0
- package/dist/dependencies.d.ts +28 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +2 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/diagnostics/diagnose.d.ts +43 -0
- package/dist/diagnostics/diagnose.d.ts.map +1 -0
- package/dist/diagnostics/diagnose.js +121 -0
- package/dist/diagnostics/diagnose.js.map +1 -0
- package/dist/domain/amount.d.ts +157 -0
- package/dist/domain/amount.d.ts.map +1 -0
- package/dist/domain/amount.js +275 -0
- package/dist/domain/amount.js.map +1 -0
- package/dist/domain/datetime.d.ts +95 -0
- package/dist/domain/datetime.d.ts.map +1 -0
- package/dist/domain/datetime.js +211 -0
- package/dist/domain/datetime.js.map +1 -0
- package/dist/domain/response-codes.d.ts +116 -0
- package/dist/domain/response-codes.d.ts.map +1 -0
- package/dist/domain/response-codes.js +380 -0
- package/dist/domain/response-codes.js.map +1 -0
- package/dist/domain/secure-hash.d.ts +78 -0
- package/dist/domain/secure-hash.d.ts.map +1 -0
- package/dist/domain/secure-hash.js +69 -0
- package/dist/domain/secure-hash.js.map +1 -0
- package/dist/domain/signature/jazzcash.d.ts +56 -0
- package/dist/domain/signature/jazzcash.d.ts.map +1 -0
- package/dist/domain/signature/jazzcash.js +214 -0
- package/dist/domain/signature/jazzcash.js.map +1 -0
- package/dist/domain/signature/registry.d.ts +69 -0
- package/dist/domain/signature/registry.d.ts.map +1 -0
- package/dist/domain/signature/registry.js +92 -0
- package/dist/domain/signature/registry.js.map +1 -0
- package/dist/domain/signature/scheme.d.ts +349 -0
- package/dist/domain/signature/scheme.d.ts.map +1 -0
- package/dist/domain/signature/scheme.js +398 -0
- package/dist/domain/signature/scheme.js.map +1 -0
- package/dist/domain/txn-ref.d.ts +76 -0
- package/dist/domain/txn-ref.d.ts.map +1 -0
- package/dist/domain/txn-ref.js +126 -0
- package/dist/domain/txn-ref.js.map +1 -0
- package/dist/domain/types.d.ts +45 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +70 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/errors.d.ts +84 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +87 -0
- package/dist/errors.js.map +1 -0
- package/dist/gateway/checkout-form.d.ts +16 -0
- package/dist/gateway/checkout-form.d.ts.map +1 -0
- package/dist/gateway/checkout-form.js +103 -0
- package/dist/gateway/checkout-form.js.map +1 -0
- package/dist/gateway/checkout-output.d.ts +70 -0
- package/dist/gateway/checkout-output.d.ts.map +1 -0
- package/dist/gateway/checkout-output.js +199 -0
- package/dist/gateway/checkout-output.js.map +1 -0
- package/dist/gateway/guards.d.ts +37 -0
- package/dist/gateway/guards.d.ts.map +1 -0
- package/dist/gateway/guards.js +44 -0
- package/dist/gateway/guards.js.map +1 -0
- package/dist/gateway/http-client.d.ts +42 -0
- package/dist/gateway/http-client.d.ts.map +1 -0
- package/dist/gateway/http-client.js +153 -0
- package/dist/gateway/http-client.js.map +1 -0
- package/dist/gateway/rest-client.d.ts +42 -0
- package/dist/gateway/rest-client.d.ts.map +1 -0
- package/dist/gateway/rest-client.js +241 -0
- package/dist/gateway/rest-client.js.map +1 -0
- package/dist/gateway/transport.d.ts +31 -0
- package/dist/gateway/transport.d.ts.map +1 -0
- package/dist/gateway/transport.js +73 -0
- package/dist/gateway/transport.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +38 -0
- package/dist/install/cli.d.ts.map +1 -0
- package/dist/install/cli.js +274 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/harnesses.d.ts +74 -0
- package/dist/install/harnesses.d.ts.map +1 -0
- package/dist/install/harnesses.js +263 -0
- package/dist/install/harnesses.js.map +1 -0
- package/dist/knowledge/corpus.d.ts +15 -0
- package/dist/knowledge/corpus.d.ts.map +1 -0
- package/dist/knowledge/corpus.js +129 -0
- package/dist/knowledge/corpus.js.map +1 -0
- package/dist/knowledge/search.d.ts +29 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +181 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/source.d.ts +60 -0
- package/dist/knowledge/source.d.ts.map +1 -0
- package/dist/knowledge/source.js +91 -0
- package/dist/knowledge/source.js.map +1 -0
- package/dist/knowledge/types.d.ts +40 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +19 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/paths.d.ts +26 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +106 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompts/integration-walkthrough.d.ts +11 -0
- package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
- package/dist/prompts/integration-walkthrough.js +52 -0
- package/dist/prompts/integration-walkthrough.js.map +1 -0
- package/dist/prompts/register.d.ts +4 -0
- package/dist/prompts/register.d.ts.map +1 -0
- package/dist/prompts/register.js +4 -0
- package/dist/prompts/register.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -0
- package/dist/resources/knowledge-resources.d.ts +5 -0
- package/dist/resources/knowledge-resources.d.ts.map +1 -0
- package/dist/resources/knowledge-resources.js +121 -0
- package/dist/resources/knowledge-resources.js.map +1 -0
- package/dist/resources/register.d.ts +4 -0
- package/dist/resources/register.d.ts.map +1 -0
- package/dist/resources/register.js +8 -0
- package/dist/resources/register.js.map +1 -0
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +56 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry/logger.d.ts +31 -0
- package/dist/telemetry/logger.d.ts.map +1 -0
- package/dist/telemetry/logger.js +67 -0
- package/dist/telemetry/logger.js.map +1 -0
- package/dist/telemetry/redaction.d.ts +88 -0
- package/dist/telemetry/redaction.d.ts.map +1 -0
- package/dist/telemetry/redaction.js +238 -0
- package/dist/telemetry/redaction.js.map +1 -0
- package/dist/tools/build-transaction-parameters.d.ts +10 -0
- package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
- package/dist/tools/build-transaction-parameters.js +154 -0
- package/dist/tools/build-transaction-parameters.js.map +1 -0
- package/dist/tools/call-context.d.ts +47 -0
- package/dist/tools/call-context.d.ts.map +1 -0
- package/dist/tools/call-context.js +15 -0
- package/dist/tools/call-context.js.map +1 -0
- package/dist/tools/codegen-tools.d.ts +4 -0
- package/dist/tools/codegen-tools.d.ts.map +1 -0
- package/dist/tools/codegen-tools.js +131 -0
- package/dist/tools/codegen-tools.js.map +1 -0
- package/dist/tools/credential-tools.d.ts +32 -0
- package/dist/tools/credential-tools.d.ts.map +1 -0
- package/dist/tools/credential-tools.js +65 -0
- package/dist/tools/credential-tools.js.map +1 -0
- package/dist/tools/descriptor.d.ts +52 -0
- package/dist/tools/descriptor.d.ts.map +1 -0
- package/dist/tools/descriptor.js +2 -0
- package/dist/tools/descriptor.js.map +1 -0
- package/dist/tools/diagnostic-tools.d.ts +3 -0
- package/dist/tools/diagnostic-tools.d.ts.map +1 -0
- package/dist/tools/diagnostic-tools.js +128 -0
- package/dist/tools/diagnostic-tools.js.map +1 -0
- package/dist/tools/gateway-tools.d.ts +6 -0
- package/dist/tools/gateway-tools.d.ts.map +1 -0
- package/dist/tools/gateway-tools.js +381 -0
- package/dist/tools/gateway-tools.js.map +1 -0
- package/dist/tools/hash-tools.d.ts +5 -0
- package/dist/tools/hash-tools.d.ts.map +1 -0
- package/dist/tools/hash-tools.js +238 -0
- package/dist/tools/hash-tools.js.map +1 -0
- package/dist/tools/knowledge-tools.d.ts +7 -0
- package/dist/tools/knowledge-tools.d.ts.map +1 -0
- package/dist/tools/knowledge-tools.js +247 -0
- package/dist/tools/knowledge-tools.js.map +1 -0
- package/dist/tools/onboarding-checklist.d.ts +3 -0
- package/dist/tools/onboarding-checklist.d.ts.map +1 -0
- package/dist/tools/onboarding-checklist.js +141 -0
- package/dist/tools/onboarding-checklist.js.map +1 -0
- package/dist/tools/register.d.ts +60 -0
- package/dist/tools/register.d.ts.map +1 -0
- package/dist/tools/register.js +145 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/tools/tool-kit.d.ts +88 -0
- package/dist/tools/tool-kit.d.ts.map +1 -0
- package/dist/tools/tool-kit.js +297 -0
- package/dist/tools/tool-kit.js.map +1 -0
- package/dist/validation/payload-validator.d.ts +29 -0
- package/dist/validation/payload-validator.d.ts.map +1 -0
- package/dist/validation/payload-validator.js +79 -0
- package/dist/validation/payload-validator.js.map +1 -0
- package/dist/validation/rules/amount.d.ts +3 -0
- package/dist/validation/rules/amount.d.ts.map +1 -0
- package/dist/validation/rules/amount.js +77 -0
- package/dist/validation/rules/amount.js.map +1 -0
- package/dist/validation/rules/bill-reference.d.ts +10 -0
- package/dist/validation/rules/bill-reference.d.ts.map +1 -0
- package/dist/validation/rules/bill-reference.js +34 -0
- package/dist/validation/rules/bill-reference.js.map +1 -0
- package/dist/validation/rules/cnic.d.ts +3 -0
- package/dist/validation/rules/cnic.d.ts.map +1 -0
- package/dist/validation/rules/cnic.js +42 -0
- package/dist/validation/rules/cnic.js.map +1 -0
- package/dist/validation/rules/constants.d.ts +9 -0
- package/dist/validation/rules/constants.d.ts.map +1 -0
- package/dist/validation/rules/constants.js +28 -0
- package/dist/validation/rules/constants.js.map +1 -0
- package/dist/validation/rules/constraints.d.ts +3 -0
- package/dist/validation/rules/constraints.d.ts.map +1 -0
- package/dist/validation/rules/constraints.js +113 -0
- package/dist/validation/rules/constraints.js.map +1 -0
- package/dist/validation/rules/datetime.d.ts +3 -0
- package/dist/validation/rules/datetime.d.ts.map +1 -0
- package/dist/validation/rules/datetime.js +49 -0
- package/dist/validation/rules/datetime.js.map +1 -0
- package/dist/validation/rules/empty-string.d.ts +13 -0
- package/dist/validation/rules/empty-string.d.ts.map +1 -0
- package/dist/validation/rules/empty-string.js +32 -0
- package/dist/validation/rules/empty-string.js.map +1 -0
- package/dist/validation/rules/expiry.d.ts +3 -0
- package/dist/validation/rules/expiry.d.ts.map +1 -0
- package/dist/validation/rules/expiry.js +52 -0
- package/dist/validation/rules/expiry.js.map +1 -0
- package/dist/validation/rules/msisdn.d.ts +3 -0
- package/dist/validation/rules/msisdn.d.ts.map +1 -0
- package/dist/validation/rules/msisdn.js +45 -0
- package/dist/validation/rules/msisdn.js.map +1 -0
- package/dist/validation/rules/presence.d.ts +3 -0
- package/dist/validation/rules/presence.d.ts.map +1 -0
- package/dist/validation/rules/presence.js +90 -0
- package/dist/validation/rules/presence.js.map +1 -0
- package/dist/validation/rules/return-url.d.ts +14 -0
- package/dist/validation/rules/return-url.d.ts.map +1 -0
- package/dist/validation/rules/return-url.js +58 -0
- package/dist/validation/rules/return-url.js.map +1 -0
- package/dist/validation/rules/tool-argument.d.ts +16 -0
- package/dist/validation/rules/tool-argument.d.ts.map +1 -0
- package/dist/validation/rules/tool-argument.js +38 -0
- package/dist/validation/rules/tool-argument.js.map +1 -0
- package/dist/validation/rules/txn-ref.d.ts +3 -0
- package/dist/validation/rules/txn-ref.d.ts.map +1 -0
- package/dist/validation/rules/txn-ref.js +47 -0
- package/dist/validation/rules/txn-ref.js.map +1 -0
- package/dist/validation/rules/unknown-fields.d.ts +10 -0
- package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
- package/dist/validation/rules/unknown-fields.js +29 -0
- package/dist/validation/rules/unknown-fields.js.map +1 -0
- package/dist/validation/types.d.ts +36 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +12 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/version.d.ts +23 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/knowledge/diagnostics/symptoms.json +321 -0
- package/knowledge/docs/bnpl-guide.md +77 -0
- package/knowledge/docs/card-page-redirection.md +67 -0
- package/knowledge/docs/card-refund.md +91 -0
- package/knowledge/docs/hmac-sha256-calculation.md +72 -0
- package/knowledge/docs/index.json +189 -0
- package/knowledge/docs/ipn-implementation.md +89 -0
- package/knowledge/docs/mwallet-recurring.md +117 -0
- package/knowledge/docs/mwallet-refund.md +65 -0
- package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
- package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
- package/knowledge/docs/portal-guide.md +45 -0
- package/knowledge/docs/shopify-guide.md +74 -0
- package/knowledge/docs/status-inquiry-2025-26.md +32 -0
- package/knowledge/docs/status-inquiry.md +111 -0
- package/knowledge/docs/wordpress-guide.md +49 -0
- package/knowledge/flow.schema.json +390 -0
- package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
- package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
- package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
- package/knowledge/flows/refund-bnpl.json +105 -0
- package/knowledge/flows/refund-card-v1.1.json +112 -0
- package/knowledge/flows/refund-card-v2.0.json +121 -0
- package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
- package/knowledge/flows/status-inquiry-v1.1.json +102 -0
- package/knowledge/flows/status-inquiry-v2.0.json +103 -0
- package/knowledge/flows/token-delete-v1.json +85 -0
- package/knowledge/flows/token-inquiry-v1.json +85 -0
- package/knowledge/flows/wallet-linking-portal.json +103 -0
- package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
- package/knowledge/templates/node/ipn-handler.tmpl +108 -0
- package/knowledge/templates/node/rest-client.tmpl +197 -0
- package/knowledge/templates/node/wallet-linking.tmpl +147 -0
- package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
- package/knowledge/templates/php/ipn-handler.tmpl +105 -0
- package/knowledge/templates/php/rest-client.tmpl +191 -0
- package/knowledge/templates/php/wallet-linking.tmpl +137 -0
- package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
- package/knowledge/templates/python/ipn-handler.tmpl +110 -0
- package/knowledge/templates/python/rest-client.tmpl +179 -0
- package/knowledge/templates/python/wallet-linking.tmpl +133 -0
- package/package.json +84 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redaction helpers.
|
|
3
|
+
*
|
|
4
|
+
* Merchant credentials must never reach a log file, an AI transcript, or a
|
|
5
|
+
* generated source file. Two distinct policies exist:
|
|
6
|
+
*
|
|
7
|
+
* - {@link redactForLog} is aggressive and is applied to everything the logger
|
|
8
|
+
* writes. It also masks `pp_SecureHash`, which is not itself a secret but is
|
|
9
|
+
* derived from the Integrity Salt; logging hash and payload together would
|
|
10
|
+
* hand an attacker an offline verification oracle.
|
|
11
|
+
* - The transcript policy is narrow and is applied where a tool must
|
|
12
|
+
* legitimately return a payload to the caller. It has two layers, and both
|
|
13
|
+
* are needed: {@link maskSecrets} removes known credential literals, and the
|
|
14
|
+
* {@link CREDENTIAL_PARAMETER_NAMES} layer removes the credentials that are
|
|
15
|
+
* too short to match literally. {@link scrubTextForTranscript} applies both
|
|
16
|
+
* to a text block and {@link maskSecretsDeep} applies both to a structured
|
|
17
|
+
* value, so the two transcript surfaces cannot disagree about a credential.
|
|
18
|
+
*/
|
|
19
|
+
export declare const REDACTED = "[redacted]";
|
|
20
|
+
/** True when a parameter name indicates a value that must not be logged. */
|
|
21
|
+
export declare function isSensitiveKey(key: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Recursively redact sensitive values for logging.
|
|
24
|
+
*
|
|
25
|
+
* Depth is bounded so a cyclic or pathological structure cannot hang the logger.
|
|
26
|
+
*/
|
|
27
|
+
export declare function redactForLog(value: unknown, depth?: number): unknown;
|
|
28
|
+
/**
|
|
29
|
+
* Parameter names whose values are credentials and are redacted by name.
|
|
30
|
+
*
|
|
31
|
+
* Deliberately narrow. `pp_SecureHash` is not included because returning it is
|
|
32
|
+
* the entire purpose of several tools, and `pp_CNIC` is not included because the
|
|
33
|
+
* caller supplied it and needs to see it echoed back to check it.
|
|
34
|
+
*/
|
|
35
|
+
export declare const CREDENTIAL_PARAMETER_NAMES: readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* Replace every occurrence of a known secret literal in free text.
|
|
38
|
+
*
|
|
39
|
+
* Used for error messages and generated output, where a credential may have been
|
|
40
|
+
* interpolated into a string rather than held in a named field.
|
|
41
|
+
*/
|
|
42
|
+
export declare function maskSecrets(text: string, secrets: readonly string[]): string;
|
|
43
|
+
/**
|
|
44
|
+
* Replace the value of every JSON-encoded credential field in free text.
|
|
45
|
+
*
|
|
46
|
+
* A text block routinely embeds a payload as a JSON code fence, so the
|
|
47
|
+
* name-based layer that protects `structuredContent` has to reach into text as
|
|
48
|
+
* well: a four-digit MPIN is below {@link MINIMUM_LITERAL_SECRET_LENGTH} and
|
|
49
|
+
* {@link maskSecrets} alone would print it verbatim.
|
|
50
|
+
*
|
|
51
|
+
* Only a quoted credential key followed by a quoted value is rewritten, so prose
|
|
52
|
+
* is untouched and the `pp_SecureHash` and `pp_CNIC` fields that several tools
|
|
53
|
+
* exist to return survive intact.
|
|
54
|
+
*/
|
|
55
|
+
export declare function maskCredentialFields(text: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Scrub one text block on its way into the transcript.
|
|
58
|
+
*
|
|
59
|
+
* Text and `structuredContent` are the same disclosure surface, so both get both
|
|
60
|
+
* masking layers. Applying only {@link maskSecrets} here — as this server once
|
|
61
|
+
* did — disclosed every credential shorter than
|
|
62
|
+
* {@link MINIMUM_LITERAL_SECRET_LENGTH}, the Merchant MPIN among them.
|
|
63
|
+
*/
|
|
64
|
+
export declare function scrubTextForTranscript(text: string, secrets: readonly string[]): string;
|
|
65
|
+
/**
|
|
66
|
+
* Recursively replace known secret literals inside a structured value.
|
|
67
|
+
*
|
|
68
|
+
* Applied to every tool result's `structuredContent`. Literal replacement is
|
|
69
|
+
* used rather than key-based redaction so that fields a tool legitimately
|
|
70
|
+
* returns — `pp_SecureHash`, a generated reference — survive intact, while a
|
|
71
|
+
* password or Integrity Salt is removed wherever it sits. Credentials too short
|
|
72
|
+
* to match literally are removed by name instead; see
|
|
73
|
+
* {@link CREDENTIAL_PARAMETER_NAMES}.
|
|
74
|
+
*
|
|
75
|
+
* Recursion is bounded and the bound fails closed: a subtree deeper than
|
|
76
|
+
* {@link MAXIMUM_REDACTION_DEPTH} is replaced by {@link TRUNCATED} rather than
|
|
77
|
+
* returned unmasked, because a deeply nested gateway response would otherwise
|
|
78
|
+
* be a route past every layer above.
|
|
79
|
+
*/
|
|
80
|
+
export declare function maskSecretsDeep<T>(value: T, secrets: readonly string[], depth?: number): T;
|
|
81
|
+
/**
|
|
82
|
+
* Mask all but the final `visible` characters of a value.
|
|
83
|
+
*
|
|
84
|
+
* Used where a caller needs to confirm *which* credential is in play without
|
|
85
|
+
* being shown it, for example when reporting the resolved profile.
|
|
86
|
+
*/
|
|
87
|
+
export declare function maskTail(value: string, visible?: number): string;
|
|
88
|
+
//# sourceMappingURL=redaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../src/telemetry/redaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,QAAQ,eAAe,CAAC;AAqDrC,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAMnD;AAeD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAsB/D;AAaD;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAAuC,CAAC;AAEhG;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAS5E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAazD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAEvF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAI,GAAG,CAAC,CAuBrF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,GAAG,MAAM,CAK3D"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redaction helpers.
|
|
3
|
+
*
|
|
4
|
+
* Merchant credentials must never reach a log file, an AI transcript, or a
|
|
5
|
+
* generated source file. Two distinct policies exist:
|
|
6
|
+
*
|
|
7
|
+
* - {@link redactForLog} is aggressive and is applied to everything the logger
|
|
8
|
+
* writes. It also masks `pp_SecureHash`, which is not itself a secret but is
|
|
9
|
+
* derived from the Integrity Salt; logging hash and payload together would
|
|
10
|
+
* hand an attacker an offline verification oracle.
|
|
11
|
+
* - The transcript policy is narrow and is applied where a tool must
|
|
12
|
+
* legitimately return a payload to the caller. It has two layers, and both
|
|
13
|
+
* are needed: {@link maskSecrets} removes known credential literals, and the
|
|
14
|
+
* {@link CREDENTIAL_PARAMETER_NAMES} layer removes the credentials that are
|
|
15
|
+
* too short to match literally. {@link scrubTextForTranscript} applies both
|
|
16
|
+
* to a text block and {@link maskSecretsDeep} applies both to a structured
|
|
17
|
+
* value, so the two transcript surfaces cannot disagree about a credential.
|
|
18
|
+
*/
|
|
19
|
+
export const REDACTED = '[redacted]';
|
|
20
|
+
/**
|
|
21
|
+
* Parameter names whose values must never be logged.
|
|
22
|
+
*
|
|
23
|
+
* Matched case-insensitively as substrings so that both `pp_Password` and a
|
|
24
|
+
* merchant's own `password` field are covered.
|
|
25
|
+
*
|
|
26
|
+
* The card-data fragments are the second line behind the tool boundary, not the
|
|
27
|
+
* first: `refuseForbiddenArguments` stops a flagged field being processed at
|
|
28
|
+
* all. They are here because the boundary refuses by flow-declared name, so a
|
|
29
|
+
* card number arriving under a name no flow declares — a merchant's own
|
|
30
|
+
* `cardNumber`, a gateway echoing `Pan` in a response body — would otherwise be
|
|
31
|
+
* written to a log file in clear, and a log file outlives the conversation it
|
|
32
|
+
* came from. Over-redaction is the cheap direction here — a masked `cardType`
|
|
33
|
+
* costs a line of debugging, a logged PAN costs a compliance incident — so the
|
|
34
|
+
* few names that must stay readable are named in {@link NON_SENSITIVE_KEYS}
|
|
35
|
+
* rather than paid for by narrowing a fragment.
|
|
36
|
+
*/
|
|
37
|
+
const SENSITIVE_KEY_FRAGMENTS = [
|
|
38
|
+
'password',
|
|
39
|
+
'mpin',
|
|
40
|
+
'salt',
|
|
41
|
+
'securehash',
|
|
42
|
+
'secure_hash',
|
|
43
|
+
'cnic',
|
|
44
|
+
'token',
|
|
45
|
+
'msisdn',
|
|
46
|
+
'mobilenumber',
|
|
47
|
+
'mobile_number',
|
|
48
|
+
'authorization',
|
|
49
|
+
'apikey',
|
|
50
|
+
'api_key',
|
|
51
|
+
'secret',
|
|
52
|
+
'pan',
|
|
53
|
+
'card',
|
|
54
|
+
'cvv',
|
|
55
|
+
'cvc',
|
|
56
|
+
'expiry',
|
|
57
|
+
];
|
|
58
|
+
/**
|
|
59
|
+
* Names that match a fragment above but carry nothing worth hiding.
|
|
60
|
+
*
|
|
61
|
+
* Exact spellings rather than fragments, and each needs a reason: an allowlist
|
|
62
|
+
* inside a denylist is a hole by construction, so it stays as short as the
|
|
63
|
+
* diagnostics require. `pp_TxnExpiryDateTime` is a transaction deadline, not a
|
|
64
|
+
* card expiry, and an elapsed one is a routine cause of a rejected request —
|
|
65
|
+
* masking it would remove from the request preview the very field a merchant
|
|
66
|
+
* needs in order to diagnose that.
|
|
67
|
+
*/
|
|
68
|
+
const NON_SENSITIVE_KEYS = ['pp_TxnExpiryDateTime'];
|
|
69
|
+
/** True when a parameter name indicates a value that must not be logged. */
|
|
70
|
+
export function isSensitiveKey(key) {
|
|
71
|
+
if (NON_SENSITIVE_KEYS.includes(key)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
const normalised = key.toLowerCase();
|
|
75
|
+
return SENSITIVE_KEY_FRAGMENTS.some((fragment) => normalised.includes(fragment));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Deepest level either recursive redactor descends to.
|
|
79
|
+
*
|
|
80
|
+
* Bounded so a cyclic or pathological structure cannot hang the server. Both
|
|
81
|
+
* redactors fail closed at the bound — an unexplored subtree is replaced by
|
|
82
|
+
* {@link TRUNCATED} rather than passed through — because a gateway response of
|
|
83
|
+
* arbitrary nesting would otherwise carry a secret past the bound untouched.
|
|
84
|
+
*/
|
|
85
|
+
const MAXIMUM_REDACTION_DEPTH = 8;
|
|
86
|
+
/** Stands in for a subtree deeper than {@link MAXIMUM_REDACTION_DEPTH}. */
|
|
87
|
+
const TRUNCATED = '[truncated]';
|
|
88
|
+
/**
|
|
89
|
+
* Recursively redact sensitive values for logging.
|
|
90
|
+
*
|
|
91
|
+
* Depth is bounded so a cyclic or pathological structure cannot hang the logger.
|
|
92
|
+
*/
|
|
93
|
+
export function redactForLog(value, depth = 0) {
|
|
94
|
+
if (depth > MAXIMUM_REDACTION_DEPTH) {
|
|
95
|
+
return TRUNCATED;
|
|
96
|
+
}
|
|
97
|
+
if (value === null || value === undefined) {
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
if (Array.isArray(value)) {
|
|
101
|
+
return value.map((entry) => redactForLog(entry, depth + 1));
|
|
102
|
+
}
|
|
103
|
+
if (value instanceof Error) {
|
|
104
|
+
return { name: value.name, message: value.message };
|
|
105
|
+
}
|
|
106
|
+
if (typeof value === 'object') {
|
|
107
|
+
const source = value;
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const key of Object.keys(source)) {
|
|
110
|
+
result[key] = isSensitiveKey(key) ? REDACTED : redactForLog(source[key], depth + 1);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Shortest secret worth replacing by literal substring match.
|
|
118
|
+
*
|
|
119
|
+
* A Merchant MPIN is four digits. Substring-replacing it would corrupt any
|
|
120
|
+
* unrelated value that happens to contain those digits — a CNIC fragment, an
|
|
121
|
+
* amount, a transaction reference — which is a worse failure than not masking a
|
|
122
|
+
* low-entropy value the merchant already knows. Short credentials are instead
|
|
123
|
+
* redacted by parameter name; see {@link CREDENTIAL_PARAMETER_NAMES}.
|
|
124
|
+
*/
|
|
125
|
+
const MINIMUM_LITERAL_SECRET_LENGTH = 8;
|
|
126
|
+
/**
|
|
127
|
+
* Parameter names whose values are credentials and are redacted by name.
|
|
128
|
+
*
|
|
129
|
+
* Deliberately narrow. `pp_SecureHash` is not included because returning it is
|
|
130
|
+
* the entire purpose of several tools, and `pp_CNIC` is not included because the
|
|
131
|
+
* caller supplied it and needs to see it echoed back to check it.
|
|
132
|
+
*/
|
|
133
|
+
export const CREDENTIAL_PARAMETER_NAMES = ['pp_Password', 'pp_MerchantMPIN'];
|
|
134
|
+
/**
|
|
135
|
+
* Replace every occurrence of a known secret literal in free text.
|
|
136
|
+
*
|
|
137
|
+
* Used for error messages and generated output, where a credential may have been
|
|
138
|
+
* interpolated into a string rather than held in a named field.
|
|
139
|
+
*/
|
|
140
|
+
export function maskSecrets(text, secrets) {
|
|
141
|
+
let result = text;
|
|
142
|
+
for (const secret of secrets) {
|
|
143
|
+
if (secret.length < MINIMUM_LITERAL_SECRET_LENGTH) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
result = result.split(secret).join(REDACTED);
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Replace the value of every JSON-encoded credential field in free text.
|
|
152
|
+
*
|
|
153
|
+
* A text block routinely embeds a payload as a JSON code fence, so the
|
|
154
|
+
* name-based layer that protects `structuredContent` has to reach into text as
|
|
155
|
+
* well: a four-digit MPIN is below {@link MINIMUM_LITERAL_SECRET_LENGTH} and
|
|
156
|
+
* {@link maskSecrets} alone would print it verbatim.
|
|
157
|
+
*
|
|
158
|
+
* Only a quoted credential key followed by a quoted value is rewritten, so prose
|
|
159
|
+
* is untouched and the `pp_SecureHash` and `pp_CNIC` fields that several tools
|
|
160
|
+
* exist to return survive intact.
|
|
161
|
+
*/
|
|
162
|
+
export function maskCredentialFields(text) {
|
|
163
|
+
let result = text;
|
|
164
|
+
for (const name of CREDENTIAL_PARAMETER_NAMES) {
|
|
165
|
+
// Built per call rather than once per module: a shared global-flag pattern
|
|
166
|
+
// carries `lastIndex` between calls, which is mutable state this module has
|
|
167
|
+
// no reason to hold. The names are plain identifiers, so they need no
|
|
168
|
+
// escaping. The value pattern spans escapes so an embedded quote cannot end
|
|
169
|
+
// the match early, and `\s*` covers the pretty-printed spacing JSON.stringify
|
|
170
|
+
// emits.
|
|
171
|
+
const field = new RegExp(`("${name}"\\s*:\\s*)"(?:\\\\.|[^"\\\\])*"`, 'g');
|
|
172
|
+
result = result.replace(field, `$1"${REDACTED}"`);
|
|
173
|
+
}
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Scrub one text block on its way into the transcript.
|
|
178
|
+
*
|
|
179
|
+
* Text and `structuredContent` are the same disclosure surface, so both get both
|
|
180
|
+
* masking layers. Applying only {@link maskSecrets} here — as this server once
|
|
181
|
+
* did — disclosed every credential shorter than
|
|
182
|
+
* {@link MINIMUM_LITERAL_SECRET_LENGTH}, the Merchant MPIN among them.
|
|
183
|
+
*/
|
|
184
|
+
export function scrubTextForTranscript(text, secrets) {
|
|
185
|
+
return maskCredentialFields(maskSecrets(text, secrets));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Recursively replace known secret literals inside a structured value.
|
|
189
|
+
*
|
|
190
|
+
* Applied to every tool result's `structuredContent`. Literal replacement is
|
|
191
|
+
* used rather than key-based redaction so that fields a tool legitimately
|
|
192
|
+
* returns — `pp_SecureHash`, a generated reference — survive intact, while a
|
|
193
|
+
* password or Integrity Salt is removed wherever it sits. Credentials too short
|
|
194
|
+
* to match literally are removed by name instead; see
|
|
195
|
+
* {@link CREDENTIAL_PARAMETER_NAMES}.
|
|
196
|
+
*
|
|
197
|
+
* Recursion is bounded and the bound fails closed: a subtree deeper than
|
|
198
|
+
* {@link MAXIMUM_REDACTION_DEPTH} is replaced by {@link TRUNCATED} rather than
|
|
199
|
+
* returned unmasked, because a deeply nested gateway response would otherwise
|
|
200
|
+
* be a route past every layer above.
|
|
201
|
+
*/
|
|
202
|
+
export function maskSecretsDeep(value, secrets, depth = 0) {
|
|
203
|
+
if (depth > MAXIMUM_REDACTION_DEPTH) {
|
|
204
|
+
return TRUNCATED;
|
|
205
|
+
}
|
|
206
|
+
if (typeof value === 'string') {
|
|
207
|
+
return maskSecrets(value, secrets);
|
|
208
|
+
}
|
|
209
|
+
if (Array.isArray(value)) {
|
|
210
|
+
return value.map((entry) => maskSecretsDeep(entry, secrets, depth + 1));
|
|
211
|
+
}
|
|
212
|
+
if (typeof value === 'object' && value !== null) {
|
|
213
|
+
const source = value;
|
|
214
|
+
const result = {};
|
|
215
|
+
for (const key of Object.keys(source)) {
|
|
216
|
+
// Short, low-entropy credentials cannot be masked by substring match
|
|
217
|
+
// without corrupting unrelated values, so they are masked by name.
|
|
218
|
+
result[key] = CREDENTIAL_PARAMETER_NAMES.includes(key)
|
|
219
|
+
? REDACTED
|
|
220
|
+
: maskSecretsDeep(source[key], secrets, depth + 1);
|
|
221
|
+
}
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
224
|
+
return value;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Mask all but the final `visible` characters of a value.
|
|
228
|
+
*
|
|
229
|
+
* Used where a caller needs to confirm *which* credential is in play without
|
|
230
|
+
* being shown it, for example when reporting the resolved profile.
|
|
231
|
+
*/
|
|
232
|
+
export function maskTail(value, visible = 4) {
|
|
233
|
+
if (value.length <= visible) {
|
|
234
|
+
return REDACTED;
|
|
235
|
+
}
|
|
236
|
+
return `${'*'.repeat(Math.min(value.length - visible, 12))}${value.slice(-visible)}`;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.js","sourceRoot":"","sources":["../../src/telemetry/redaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CoreRegistrar } from '../core/registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* The recommended entry point for building a request.
|
|
4
|
+
*
|
|
5
|
+
* Fills constants, formats Pakistan-time timestamps, converts the amount to
|
|
6
|
+
* minor units, generates unique references, validates, and signs — in that
|
|
7
|
+
* order, with the hash computed last from exactly the map that will be sent.
|
|
8
|
+
*/
|
|
9
|
+
export declare const registerBuildTransactionParameters: CoreRegistrar;
|
|
10
|
+
//# sourceMappingURL=build-transaction-parameters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-transaction-parameters.d.ts","sourceRoot":"","sources":["../../src/tools/build-transaction-parameters.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,EAAE,aAkKhD,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { buildTransaction } from '../builder/transaction-builder.js';
|
|
3
|
+
import { resolveEndpoint } from '../catalogue/endpoints.js';
|
|
4
|
+
import { JAZZCASH_ENVIRONMENTS } from '../config/environment.js';
|
|
5
|
+
import { fromMinorUnits } from '../domain/amount.js';
|
|
6
|
+
import { describeHowToSend } from '../gateway/transport.js';
|
|
7
|
+
import { maskSecretsDeep } from '../telemetry/redaction.js';
|
|
8
|
+
import { formatValidationResult } from '../validation/payload-validator.js';
|
|
9
|
+
import { citations, resolveEnvironment, safeHandler, toolResult } from './tool-kit.js';
|
|
10
|
+
/**
|
|
11
|
+
* The recommended entry point for building a request.
|
|
12
|
+
*
|
|
13
|
+
* Fills constants, formats Pakistan-time timestamps, converts the amount to
|
|
14
|
+
* minor units, generates unique references, validates, and signs — in that
|
|
15
|
+
* order, with the hash computed last from exactly the map that will be sent.
|
|
16
|
+
*/
|
|
17
|
+
export const registerBuildTransactionParameters = (server, deps) => {
|
|
18
|
+
server.registerTool('jazzcash_build_transaction_parameters', {
|
|
19
|
+
title: 'Build a complete, validated, signed JazzCash payload',
|
|
20
|
+
description: 'Assemble a ready-to-send payload for a flow. Fills constants and empty fields, formats timestamps in Pakistan Standard Time, converts the amount to minor units, generates a unique transaction reference, validates against the flow specification, and computes pp_SecureHash last. Prefer this over assembling a payload by hand.',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
flowId: z.string().describe('Flow to build for, e.g. "card-page-redirection-v1.1".'),
|
|
23
|
+
environment: z
|
|
24
|
+
.enum(JAZZCASH_ENVIRONMENTS)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Credential profile to use. Defaults to the configured environment. This does NOT change the endpoint.'),
|
|
27
|
+
amount: z
|
|
28
|
+
.union([z.string(), z.number()])
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Amount in major units, e.g. "100.00" or 100. Converted to minor units for you.'),
|
|
31
|
+
amountMinorUnits: z
|
|
32
|
+
.string()
|
|
33
|
+
.optional()
|
|
34
|
+
.describe('Amount already multiplied by 100, e.g. "10000". Takes precedence over `amount`.'),
|
|
35
|
+
billReference: z.string().optional().describe('Alphanumeric bill reference. Generated if omitted.'),
|
|
36
|
+
description: z.string().optional().describe('Order or product description.'),
|
|
37
|
+
txnRefNo: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Transaction reference. Generated as a timestamp plus random characters if omitted.'),
|
|
41
|
+
requestId: z
|
|
42
|
+
.string()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('Request identifier for linking and token flows. Generated if omitted.'),
|
|
45
|
+
referencePrefix: z
|
|
46
|
+
.string()
|
|
47
|
+
.optional()
|
|
48
|
+
.describe('Up to three alphanumeric characters for generated references, e.g. the first three letters of your domain.'),
|
|
49
|
+
expiryDays: z
|
|
50
|
+
.number()
|
|
51
|
+
.int()
|
|
52
|
+
.min(1)
|
|
53
|
+
.max(30)
|
|
54
|
+
.optional()
|
|
55
|
+
.describe('Expiry window in days. Defaults to the documented 1.'),
|
|
56
|
+
extras: z
|
|
57
|
+
.record(z.string(), z.string())
|
|
58
|
+
.optional()
|
|
59
|
+
.describe('Flow-specific fields you must supply, e.g. { "pp_MobileNumber": "03123456789", "pp_CNIC": "123456" } or { "ppmpf_1": "03123456789" }.'),
|
|
60
|
+
},
|
|
61
|
+
}, safeHandler(deps, 'jazzcash_build_transaction_parameters', (args) => {
|
|
62
|
+
const flow = deps.catalogue.get(args.flowId);
|
|
63
|
+
const environment = resolveEnvironment(deps, args.environment);
|
|
64
|
+
const profile = deps.credentials.get(environment);
|
|
65
|
+
const built = buildTransaction(flow, {
|
|
66
|
+
amount: args.amount,
|
|
67
|
+
amountMinorUnits: args.amountMinorUnits,
|
|
68
|
+
billReference: args.billReference,
|
|
69
|
+
description: args.description,
|
|
70
|
+
txnRefNo: args.txnRefNo,
|
|
71
|
+
requestId: args.requestId,
|
|
72
|
+
referencePrefix: args.referencePrefix,
|
|
73
|
+
expiryDays: args.expiryDays,
|
|
74
|
+
extras: args.extras,
|
|
75
|
+
}, profile);
|
|
76
|
+
if (!built.validation.valid) {
|
|
77
|
+
return toolResult([
|
|
78
|
+
`Could not build a ${flow.id} payload — the request is incomplete or invalid, so it has NOT been signed.`,
|
|
79
|
+
'',
|
|
80
|
+
formatValidationResult(built.validation),
|
|
81
|
+
'',
|
|
82
|
+
'Supply the missing values and call this tool again. Flow-specific fields go in `extras`.',
|
|
83
|
+
citations(flow.docRefs),
|
|
84
|
+
].join('\n'), {
|
|
85
|
+
isError: true,
|
|
86
|
+
structuredContent: {
|
|
87
|
+
flowId: flow.id,
|
|
88
|
+
valid: false,
|
|
89
|
+
errors: built.validation.errors,
|
|
90
|
+
warnings: built.validation.warnings,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const amountValue = built.parameters['pp_Amount'];
|
|
95
|
+
// The payload is rendered from a masked copy rather than relying on the
|
|
96
|
+
// scrub in safeHandler alone: this tool is the one that fills credentials
|
|
97
|
+
// in from the profile, so it must not hand a real MPIN or password to any
|
|
98
|
+
// downstream formatting in the first place.
|
|
99
|
+
const maskedParameters = maskSecretsDeep(built.parameters, deps.credentials.allSecrets());
|
|
100
|
+
const summary = [
|
|
101
|
+
`Built and signed a ${flow.title} payload for the **${environment}** environment.`,
|
|
102
|
+
'',
|
|
103
|
+
`Endpoint (${flow.transport}): ${resolveEndpoint(flow, environment)}`,
|
|
104
|
+
flow.sameEndpointForBothEnvironments
|
|
105
|
+
? 'Sandbox and production share this URL. The environment above refers to the credentials, not the endpoint.'
|
|
106
|
+
: '',
|
|
107
|
+
amountValue === undefined ? '' : `Amount: ${amountValue} minor units (PKR ${fromMinorUnits(amountValue)})`,
|
|
108
|
+
'',
|
|
109
|
+
'## Payload',
|
|
110
|
+
'```json',
|
|
111
|
+
JSON.stringify(maskedParameters, null, 2),
|
|
112
|
+
'```',
|
|
113
|
+
'',
|
|
114
|
+
'Credential fields show `[redacted]` above so they do not enter this transcript. `pp_SecureHash` was computed over the REAL values, so substitute your own credentials before sending by hand — or pass this payload to `jazzcash_send_gateway_request`, which restores the credential fields from the server configuration and re-signs before sending.',
|
|
115
|
+
'',
|
|
116
|
+
Object.keys(built.generated).length > 0
|
|
117
|
+
? `## Generated for you\n${Object.entries(built.generated)
|
|
118
|
+
.map(([name, value]) => `- ${name} = ${value}`)
|
|
119
|
+
.join('\n')}`
|
|
120
|
+
: '',
|
|
121
|
+
'',
|
|
122
|
+
built.validation.warnings.length > 0
|
|
123
|
+
? `## Warnings\n${built.validation.warnings.map((entry) => `- [${entry.code}] ${entry.message}\n Fix: ${entry.fix}`).join('\n')}`
|
|
124
|
+
: 'No warnings.',
|
|
125
|
+
'',
|
|
126
|
+
// Read from the transport rather than branched on `form-post` here:
|
|
127
|
+
// the else-half of that ternary told the caller to send any non-JSON
|
|
128
|
+
// transport as JSON, to an endpoint that does not parse it. See
|
|
129
|
+
// `describeHowToSend`.
|
|
130
|
+
describeHowToSend(flow),
|
|
131
|
+
citations(flow.docRefs),
|
|
132
|
+
]
|
|
133
|
+
.filter((line) => line !== '')
|
|
134
|
+
.join('\n');
|
|
135
|
+
return toolResult(summary, {
|
|
136
|
+
structuredContent: {
|
|
137
|
+
flowId: flow.id,
|
|
138
|
+
environment,
|
|
139
|
+
endpoint: resolveEndpoint(flow, environment),
|
|
140
|
+
transport: flow.transport,
|
|
141
|
+
parameters: built.parameters,
|
|
142
|
+
secureHash: built.secureHash,
|
|
143
|
+
generated: built.generated,
|
|
144
|
+
warnings: built.validation.warnings,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
// Declared here rather than branched on in the body: `extras` is the only
|
|
149
|
+
// argument that addresses a parameter by name, and the rest are typed
|
|
150
|
+
// business fields the builder routes by value type. `flowId` selects the
|
|
151
|
+
// explanatory sentence; the names refused are catalogue-wide regardless.
|
|
152
|
+
{ payloadArguments: ['extras'], flowFrom: 'flowId' }));
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=build-transaction-parameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-transaction-parameters.js","sourceRoot":"","sources":["../../src/tools/build-transaction-parameters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { CoreDependencies } from '../core/dependencies.js';
|
|
2
|
+
import type { Logger } from '../telemetry/logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Per-call identity for a tool invocation.
|
|
5
|
+
*
|
|
6
|
+
* One tool call is one unit of work, but until now nothing tied its log records
|
|
7
|
+
* to it: the logger's only binding is a static server name, so a merchant
|
|
8
|
+
* reporting "the refund tool failed" left an operator reading a stream of
|
|
9
|
+
* records that could not be separated from any other call in the session. A
|
|
10
|
+
* context created once per call, and carried into the handler, is what makes a
|
|
11
|
+
* failure attributable to the call that produced it.
|
|
12
|
+
*
|
|
13
|
+
* The context is derived from {@link CoreDependencies}, never from the SDK's
|
|
14
|
+
* `extra` argument; `safeHandler` in `tool-kit.ts` records why.
|
|
15
|
+
*/
|
|
16
|
+
export interface CallContext {
|
|
17
|
+
/** Registered tool name, e.g. `jazzcash_build_secure_hash`. */
|
|
18
|
+
readonly toolName: string;
|
|
19
|
+
/**
|
|
20
|
+
* Identifier for this call.
|
|
21
|
+
*
|
|
22
|
+
* A UUID rather than a per-process counter, because a counter restarts at 1
|
|
23
|
+
* every time the server is respawned — which an IDE does on every reload — so
|
|
24
|
+
* identifiers would repeat across runs and point an operator at the wrong call
|
|
25
|
+
* in an aggregated log.
|
|
26
|
+
*/
|
|
27
|
+
readonly requestId: string;
|
|
28
|
+
/**
|
|
29
|
+
* Wall-clock epoch milliseconds at which the call began.
|
|
30
|
+
*
|
|
31
|
+
* Wall clock rather than a monotonic reading: the logger stamps every record
|
|
32
|
+
* with an ISO wall-clock timestamp, and a monotonic value measured from an
|
|
33
|
+
* arbitrary process origin could not be lined up against those records, which
|
|
34
|
+
* is the only reason to record a start at all.
|
|
35
|
+
*/
|
|
36
|
+
readonly startedAt: number;
|
|
37
|
+
/**
|
|
38
|
+
* Logger bound to this call's identity.
|
|
39
|
+
*
|
|
40
|
+
* Handlers must log through this rather than through `deps.logger`, otherwise
|
|
41
|
+
* the record loses the `requestId` and becomes unattributable again.
|
|
42
|
+
*/
|
|
43
|
+
readonly logger: Logger;
|
|
44
|
+
}
|
|
45
|
+
/** Build the context for a single invocation of `toolName`. */
|
|
46
|
+
export declare function createCallContext(deps: CoreDependencies, toolName: string): CallContext;
|
|
47
|
+
//# sourceMappingURL=call-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-context.d.ts","sourceRoot":"","sources":["../../src/tools/call-context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAErD;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAWvF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
/** Build the context for a single invocation of `toolName`. */
|
|
3
|
+
export function createCallContext(deps, toolName) {
|
|
4
|
+
const requestId = randomUUID();
|
|
5
|
+
return {
|
|
6
|
+
toolName,
|
|
7
|
+
requestId,
|
|
8
|
+
startedAt: Date.now(),
|
|
9
|
+
// Bound here rather than at each log site so that every record a handler
|
|
10
|
+
// emits carries the identity, including ones added later by code that never
|
|
11
|
+
// read this module.
|
|
12
|
+
logger: deps.logger.child({ tool: toolName, requestId }),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=call-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-context.js","sourceRoot":"","sources":["../../src/tools/call-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAiDzC,+DAA+D;AAC/D,MAAM,UAAU,iBAAiB,CAAC,IAAsB,EAAE,QAAgB;IACxE,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,OAAO;QACL,QAAQ;QACR,SAAS;QACT,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,yEAAyE;QACzE,4EAA4E;QAC5E,oBAAoB;QACpB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen-tools.d.ts","sourceRoot":"","sources":["../../src/tools/codegen-tools.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA2ChD,eAAO,MAAM,+BAA+B,EAAE,SA6D7C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,SAwDxC,CAAC"}
|