@agent-cards/sdk 0.23.27 → 0.24.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/PREFLIGHT.md +7 -1
  3. package/README.md +137 -99
  4. package/dist/aci.d.ts +52 -22
  5. package/dist/aci.js +79 -15
  6. package/dist/adyen-merchant-hosted.generated.d.ts +1 -1
  7. package/dist/adyen-merchant-hosted.generated.js +459 -21
  8. package/dist/agent-amount.generated.js +1 -1
  9. package/dist/agentcard.d.ts +4 -5
  10. package/dist/agentcard.js +4 -5
  11. package/dist/amadeus.d.ts +9 -3
  12. package/dist/amadeus.js +33 -4
  13. package/dist/api-module.d.ts +1 -7
  14. package/dist/api-module.js +3 -5
  15. package/dist/{voice-retry.js → api-retry.js} +1 -1
  16. package/dist/api-types.d.ts +53 -0
  17. package/dist/{voice-types.js → api-types.js} +7 -2
  18. package/dist/approvals.d.ts +166 -0
  19. package/dist/approvals.js +213 -0
  20. package/dist/buy.d.ts +20 -101
  21. package/dist/buy.js +19 -74
  22. package/dist/capabilities.generated.js +1 -1
  23. package/dist/card-fields.generated.js +1398 -106
  24. package/dist/cdp.d.ts +3 -13
  25. package/dist/cdp.js +231 -175
  26. package/dist/client.d.ts +104 -22
  27. package/dist/client.js +215 -40
  28. package/dist/creditguard.generated.d.ts +4 -4
  29. package/dist/datatrans.generated.js +22 -1
  30. package/dist/elavon-converge.generated.js +5 -3
  31. package/dist/hold.d.ts +8 -0
  32. package/dist/hold.js +43 -2
  33. package/dist/hosted-entry.js +2 -0
  34. package/dist/index.d.ts +9 -15
  35. package/dist/index.js +6 -10
  36. package/dist/juspay-gate.js +2 -2
  37. package/dist/juspay.generated.d.ts +2 -2
  38. package/dist/juspay.generated.js +174 -4
  39. package/dist/lifecycle.d.ts +9 -61
  40. package/dist/lifecycle.js +24 -10
  41. package/dist/merchant-card-endpoints.generated.d.ts +6 -1
  42. package/dist/merchant-card-endpoints.generated.js +344 -19
  43. package/dist/merchant-hosted.d.ts +8 -1
  44. package/dist/nike-order.d.ts +51 -0
  45. package/dist/nike-order.js +81 -0
  46. package/dist/oceanpayment.d.ts +38 -0
  47. package/dist/oceanpayment.js +70 -0
  48. package/dist/paddle-tokenex.generated.js +105 -10
  49. package/dist/payplug.d.ts +41 -0
  50. package/dist/payplug.js +71 -0
  51. package/dist/payrails.generated.js +27 -7
  52. package/dist/payrexx.generated.js +176 -2
  53. package/dist/pre-claim.d.ts +9 -0
  54. package/dist/pre-claim.js +86 -7
  55. package/dist/preflight-capabilities.generated.d.ts +0 -4
  56. package/dist/preflight-capabilities.generated.js +0 -5
  57. package/dist/preflight-catalog.json +46 -5
  58. package/dist/preflight-playwright.d.ts +2 -2
  59. package/dist/preflight-playwright.js +63 -14
  60. package/dist/preflight-schemas.json +4 -0
  61. package/dist/preflight.generated.d.ts +0 -4
  62. package/dist/preflight.generated.js +24 -1
  63. package/dist/prepared-processor.d.ts +18 -5
  64. package/dist/prepared-processor.js +48 -8
  65. package/dist/primer.generated.js +1418 -120
  66. package/dist/processout.generated.d.ts +61 -0
  67. package/dist/processout.generated.js +577 -0
  68. package/dist/requests.js +1 -1
  69. package/dist/shiji-sts.generated.js +105 -10
  70. package/dist/stripe-checkout.generated.js +1405 -234
  71. package/dist/substitutions.generated.js +460 -26
  72. package/dist/tap-payments.generated.js +105 -10
  73. package/dist/twoc2p.generated.js +105 -10
  74. package/dist/url-masks/bluesnap.d.ts +2 -0
  75. package/dist/url-masks/bluesnap.js +15 -0
  76. package/dist/url-masks/oceanpayment.d.ts +2 -0
  77. package/dist/url-masks/oceanpayment.js +13 -0
  78. package/dist/url-masks/payplug.d.ts +2 -0
  79. package/dist/url-masks/payplug.js +13 -0
  80. package/dist/url-masks/vtex_payments.d.ts +2 -0
  81. package/dist/url-masks/vtex_payments.js +12 -0
  82. package/dist/url-masks.generated.d.ts +1 -1
  83. package/dist/url-masks.generated.js +6 -2
  84. package/dist/verifone.generated.js +42 -2
  85. package/dist/vtex-payments.generated.d.ts +127 -0
  86. package/dist/vtex-payments.generated.js +544 -0
  87. package/dist/webhooks.d.ts +2 -2
  88. package/dist/webhooks.js +2 -2
  89. package/dist/wspay.generated.d.ts +1 -1
  90. package/dist/wspay.generated.js +175 -3
  91. package/examples/preflight/kernel-native/inventory.json +1 -1
  92. package/package.json +6 -8
  93. package/dist/languages.d.ts +0 -23
  94. package/dist/languages.js +0 -76
  95. package/dist/voice-pkce.d.ts +0 -49
  96. package/dist/voice-pkce.js +0 -147
  97. package/dist/voice-stream.generated.d.ts +0 -118
  98. package/dist/voice-stream.generated.js +0 -170
  99. package/dist/voice-types.d.ts +0 -735
  100. package/dist/voice.d.ts +0 -373
  101. package/dist/voice.js +0 -815
  102. package/readme.test.mjs +0 -53
  103. /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
@@ -1,6 +1,174 @@
1
1
  // @ts-nocheck
2
2
  // Generated from @agent-cards/payment-core. Do not edit.
3
- // artifact-sha256: 9ba65916c5dc5ee3ca830d630cafbde62d537e61991c33c80f1520ac93ef0b0d
3
+ // artifact-sha256: f3d9221468606ad3d7512105a7eb6c2eef4b813d5772cb2a5c31042874cb4984
4
+ // src/three-ds-step.js
5
+ var RUN = /[A-Za-z0-9+/_-]{12,}/g;
6
+ var RUN_LENGTH = 12;
7
+ var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8
+ var LAYERS = 2;
9
+ var PAREQ = /pareq/i;
10
+ var PAGE_PAREQ = /\bname\s*=\s*["']?[^"'\s>]*pareq/i;
11
+ var THREE_DS_STEP_UNREADABLE = "unreadable_three_ds_step";
12
+ var THREE_DS_STEP_HOLDS_CARD = "card_in_three_ds_step";
13
+ var PERCENT_LAYERS = 8;
14
+ function percentDecoded(text2) {
15
+ let out = text2;
16
+ for (let layer = 0; layer < PERCENT_LAYERS; layer += 1) {
17
+ const next = out.replace(/%([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
18
+ if (next === out)
19
+ break;
20
+ out = next;
21
+ }
22
+ return out;
23
+ }
24
+ var NAMED = /* @__PURE__ */ Object.freeze({
25
+ amp: "&",
26
+ percnt: "%",
27
+ num: "#",
28
+ quest: "?",
29
+ semi: ";",
30
+ excl: "!",
31
+ dollar: "$",
32
+ lpar: "(",
33
+ rpar: ")",
34
+ ast: "*",
35
+ comma: ",",
36
+ commat: "@",
37
+ lsqb: "[",
38
+ rsqb: "]",
39
+ lcub: "{",
40
+ rcub: "}",
41
+ verbar: "|",
42
+ bsol: "\\",
43
+ hat: "^",
44
+ grave: "`",
45
+ plus: "+",
46
+ sol: "/",
47
+ equals: "=",
48
+ lowbar: "_",
49
+ period: ".",
50
+ colon: ":",
51
+ quot: '"',
52
+ apos: "'",
53
+ lt: "<",
54
+ gt: ">"
55
+ });
56
+ var NUMERIC = "#(?:[xX]([0-9a-fA-F]+)|([0-9]+));?";
57
+ var BARE_NAME = "(sup[123]|frac(?:12|14|34)|[A-Za-z]+);?";
58
+ var referenceText = (hex, decimal, name) => {
59
+ if (name !== void 0)
60
+ return Object.prototype.hasOwnProperty.call(NAMED, name.toLowerCase()) ? NAMED[name.toLowerCase()] : " ";
61
+ const point = hex === void 0 ? parseInt(decimal, 10) : parseInt(hex, 16);
62
+ return point <= 1114111 ? String.fromCodePoint(point) : "";
63
+ };
64
+ function referenceReadings(text2) {
65
+ const read = (pattern) => text2.replace(new RegExp(`&(?:${NUMERIC}|${pattern})`, "g"), (_, hex, decimal, name) => referenceText(hex, decimal, name));
66
+ return [read("([A-Za-z][A-Za-z0-9]*);"), read(BARE_NAME)];
67
+ }
68
+ function readings(text2) {
69
+ const out = /* @__PURE__ */ new Set([text2, percentDecoded(text2)]);
70
+ for (const reading of [...out])
71
+ for (const decoded of referenceReadings(reading))
72
+ out.add(decoded).add(percentDecoded(decoded));
73
+ return out;
74
+ }
75
+ function base64Bytes(run, skip) {
76
+ let bits = 0;
77
+ let value = 0;
78
+ let out = "";
79
+ for (let i = skip; i < run.length; i += 1) {
80
+ const char = run[i];
81
+ value = value << 6 | (char === "-" ? 62 : char === "_" ? 63 : ALPHABET.indexOf(char));
82
+ bits += 6;
83
+ if (bits >= 8) {
84
+ bits -= 8;
85
+ out += String.fromCharCode(value >> bits);
86
+ value &= (1 << bits) - 1;
87
+ }
88
+ }
89
+ return out;
90
+ }
91
+ var compressed = (bytes) => bytes.charCodeAt(0) === 31 && bytes.charCodeAt(1) === 139 || bytes.charCodeAt(0) === 120 && (30720 + bytes.charCodeAt(1)) % 31 === 0;
92
+ function holdsStream(text2, layers) {
93
+ for (const reading of readings(text2)) {
94
+ for (const [run] of reading.matchAll(RUN)) {
95
+ const starts = [0];
96
+ for (let slash = run.indexOf("/"); slash >= 0; slash = run.indexOf("/", slash + 1))
97
+ starts.push(slash + 1);
98
+ if (starts.some((start) => run.length - start >= RUN_LENGTH && compressed(base64Bytes(run.slice(start, start + 4), 0))))
99
+ return true;
100
+ for (let skip = 0; layers > 0 && skip < 4; skip += 1)
101
+ if (holdsStream(base64Bytes(run, skip), layers - 1))
102
+ return true;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+ function numberPattern(card) {
108
+ const number = card && (typeof card.number === "string" || typeof card.number === "number") ? String(card.number).replace(/[^0-9]/g, "") : "";
109
+ return number.length >= 12 && number.length <= 19 ? new RegExp(number.split("").join("[^0-9A-Za-z]{0,3}")) : null;
110
+ }
111
+ function holdsNumber(text2, pattern, layers) {
112
+ for (const reading of readings(text2)) {
113
+ if (pattern.test(reading))
114
+ return true;
115
+ if (layers === 0)
116
+ continue;
117
+ for (const [run] of reading.matchAll(RUN)) {
118
+ for (let skip = 0; skip < 4; skip += 1)
119
+ if (holdsNumber(base64Bytes(run, skip), pattern, layers - 1))
120
+ return true;
121
+ }
122
+ }
123
+ return false;
124
+ }
125
+ function addressTexts(value) {
126
+ if (typeof value !== "string")
127
+ return null;
128
+ let url;
129
+ try {
130
+ url = new URL(value);
131
+ }
132
+ catch {
133
+ return null;
134
+ }
135
+ const names = [];
136
+ const texts = [value, ...url.pathname.split("/")];
137
+ for (const pair of `${url.search.slice(1)}&${url.hash.slice(1)}`.split("&")) {
138
+ if (pair === "")
139
+ continue;
140
+ const at = pair.indexOf("=");
141
+ names.push(at < 0 ? pair : pair.slice(0, at));
142
+ if (at >= 0)
143
+ texts.push(pair.slice(at + 1));
144
+ }
145
+ return { names, texts: [...texts, ...names] };
146
+ }
147
+ var textOf = (value) => typeof value === "string" ? value : JSON.stringify(value) ?? "";
148
+ function threeDsStepLeak(card, step) {
149
+ const names = [];
150
+ const texts = [];
151
+ for (const url of step.urls ?? []) {
152
+ const address = addressTexts(url);
153
+ if (!address)
154
+ return THREE_DS_STEP_UNREADABLE;
155
+ names.push(...address.names);
156
+ texts.push(...address.texts);
157
+ }
158
+ for (const [name, value] of step.fields ?? []) {
159
+ names.push(textOf(name));
160
+ texts.push(textOf(name), textOf(value));
161
+ }
162
+ for (const page of step.pages ?? []) {
163
+ if ([...readings(textOf(page))].some((reading) => PAGE_PAREQ.test(reading)))
164
+ return THREE_DS_STEP_UNREADABLE;
165
+ texts.push(textOf(page));
166
+ }
167
+ if (names.some((name) => [...readings(name)].some((reading) => PAREQ.test(reading))) || texts.some((text2) => holdsStream(text2, LAYERS)))
168
+ return THREE_DS_STEP_UNREADABLE;
169
+ const pattern = numberPattern(card);
170
+ return pattern && texts.some((text2) => holdsNumber(text2, pattern, LAYERS)) ? THREE_DS_STEP_HOLDS_CARD : null;
171
+ }
4
172
  // src/wspay.js
5
173
  var WSPAY_CONFIRM_HOSTS = Object.freeze(["proxy.wspay.biz", "proxy-test.wspay.biz"]);
6
174
  var WSPAY_TEST_HOST = "proxy-test.wspay.biz";
@@ -303,7 +471,7 @@ function responseCode(result) {
303
471
  const code = record(trx) ? trx.response_code : null;
304
472
  return exact(/^[0-9]{4}$/, code) ? code : null;
305
473
  }
306
- function wspayResponseOutcome(status, text2) {
474
+ function wspayResponseOutcome(status, text2, card) {
307
475
  if (status !== 200)
308
476
  return { outcome: "unknown", reason: "wspay_status_unconfirmed" };
309
477
  const value = readJson(text2);
@@ -319,8 +487,12 @@ function wspayResponseOutcome(status, text2) {
319
487
  }
320
488
  if (value.status === "approved" && approvedResult(result))
321
489
  return { outcome: "approved" };
322
- if (value.status === "action_required" && (result === null || result === void 0) && keysWithin(value.action_required, ["acs_url", "redirect_to"]) && httpsUrl(value.action_required.acs_url) && httpsUrl(value.action_required.redirect_to))
490
+ if (value.status === "action_required" && (result === null || result === void 0) && keysWithin(value.action_required, ["acs_url", "redirect_to"]) && httpsUrl(value.action_required.acs_url) && httpsUrl(value.action_required.redirect_to)) {
491
+ const leak = threeDsStepLeak(card, { urls: [value.action_required.acs_url, value.action_required.redirect_to] });
492
+ if (leak)
493
+ return { outcome: "unknown", reason: leak === THREE_DS_STEP_UNREADABLE ? "wspay_three_ds_unreadable" : "wspay_answer_holds_card" };
323
494
  return { outcome: "approved", pending: "three_ds" };
495
+ }
324
496
  return { outcome: "unknown", reason: "wspay_unconfirmed" };
325
497
  }
326
498
  function sanitizeWspayResponse(text2, options) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "catalog_version": "2026-09-15.1",
4
- "catalog_sha256": "7f65e0f07138296b0cbff7dd1ed4331842b6dd45e2950f08273fcc772c7f63f6",
4
+ "catalog_sha256": "d27bf03744adafed6b1e6731f61439bb410e90ab4937dcb279d3e5db46784784",
5
5
  "baseline_version": "kernel-native-docs-2026-09-11.1",
6
6
  "baseline_sha256": "d86722f49633d8223fccae54cd3d485df4375aee06aa156a273cc689b7c8507c",
7
7
  "native_build": null,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agent-cards/sdk",
3
- "version": "0.23.27",
4
- "description": "Agentcard's SDK: one client, Agentcard, with two modules. checkout pauses a browser purchase and pays it with the person's own card; voice connects a person to your product once and approves a purchase by voice inside it. Card data never enters your process.",
3
+ "version": "0.24.0",
4
+ "description": "Agentcard's SDK: one client, Agentcard, with two modules. checkout pauses a browser purchase and pays it with the person's own card; buy asks the Purchase API for a cart and places it. Card data never enters your process.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -24,16 +24,15 @@
24
24
  "access": "public"
25
25
  },
26
26
  "scripts": {
27
- "_comment_build": "The public SDK keeps zero runtime dependencies. Its build vendors deterministic metadata and substitution artifacts from the internal payment core (src/*.generated.ts), the voice streaming door from packages/voice/src/core (the phone package, @agent-cards/voice, ships it to phones), and the Kernel kit's inventory from the built catalog; git ignores every file it writes. TypeScript remains pinned.",
28
- "build": "node ../payment-core/scripts/build.mjs && node scripts/generate-payment-core.mjs && node scripts/generate-voice-stream.mjs && node scripts/generate-url-masks.mjs && node scripts/generate-capabilities.mjs && node scripts/generate-agent-amount.mjs && npx -y -p typescript@5.9.3 tsc && node scripts/generate-preflight-contract.mjs && node scripts/generate-kernel-native-inventory.mjs",
27
+ "_comment_build": "The public SDK keeps zero runtime dependencies. Its build vendors deterministic metadata and substitution artifacts from the internal payment core (src/*.generated.ts) and the Kernel kit's inventory from the built catalog; git ignores every file it writes. TypeScript remains pinned. The build starts from an empty dist, so a module the source no longer has never reaches a packed tarball.",
28
+ "build": "node scripts/clean-dist.mjs && node ../payment-core/scripts/build.mjs && node scripts/generate-payment-core.mjs && node scripts/generate-url-masks.mjs && node scripts/generate-capabilities.mjs && node scripts/generate-agent-amount.mjs && npx -y -p typescript@5.9.3 tsc && node scripts/generate-preflight-contract.mjs && node scripts/generate-kernel-native-inventory.mjs",
29
29
  "prepublishOnly": "pnpm build",
30
30
  "_comment_test": "check:built runs first and names the command when a file the build generates (the copies in src/, the preflight contracts in dist/, the Kernel inventory) is missing or stale; verify:pack runs last, on the same dist.",
31
- "check:built": "node scripts/generate-payment-core.mjs --check && node scripts/generate-voice-stream.mjs --check && node scripts/generate-url-masks.mjs --check && node scripts/generate-capabilities.mjs --check && node scripts/generate-agent-amount.mjs --check && node scripts/generate-preflight-contract.mjs --check && node scripts/generate-kernel-native-inventory.mjs --check",
31
+ "check:built": "node scripts/generate-payment-core.mjs --check && node scripts/generate-url-masks.mjs --check && node scripts/generate-capabilities.mjs --check && node scripts/generate-agent-amount.mjs --check && node scripts/generate-preflight-contract.mjs --check && node scripts/generate-kernel-native-inventory.mjs --check",
32
32
  "verify:pack": "node scripts/verify-pack.mjs",
33
- "test": "npm run check:built && node test.mjs && node --test lifecycle.test.mjs merchant-abort.test.mjs preparation.test.mjs braintree.test.mjs pre-claim.test.mjs ekashu.test.mjs redsys.test.mjs quickpay.test.mjs paytrail.test.mjs paypal-hosted-fields.test.mjs paypal-card-forms.test.mjs cybersource-secure-acceptance.test.mjs ebanx.test.mjs payrexx.test.mjs payrexx-follow-ups.test.mjs payrexx-adapters.test.mjs autopilot.test.mjs stripe-checkout.test.mjs stripe-setup.test.mjs stripe-legacy-checkout.test.mjs payment-core.test.mjs prepared-processor.test.mjs merchant-hosted.test.mjs merchant-total.test.mjs sandbox-declaration.test.mjs minimum-delay.test.mjs paysafe.test.mjs wix-payments.test.mjs hipay.test.mjs openpay.test.mjs payu.test.mjs attachment.test.mjs worker-targets.test.mjs mercado-checkout.test.mjs mercado-polling.test.mjs amadeus.test.mjs pelecard.test.mjs aci.test.mjs primer.test.mjs payrails.test.mjs elavon-converge.test.mjs voice.test.mjs agentcard.test.mjs buy.test.mjs readme.test.mjs gmo.test.mjs cybersource-flex.test.mjs juspay-gate.test.mjs card-endpoint.test.mjs card-endpoint-fastspring.test.mjs card-endpoint-navigation.test.mjs merchant-session-probe.test.mjs datatrans.test.mjs authorize-net-dpm.test.mjs creditguard.test.mjs eprotect.test.mjs wspay.test.mjs shiji-sts.test.mjs worldline-mycheckout.test.mjs verifone.test.mjs gravy.test.mjs paddle-vgs.test.mjs sbps.test.mjs hold.test.mjs paddle-tokenex.test.mjs lyra.test.mjs gopay.test.mjs paygent.test.mjs twoc2p.test.mjs tap-payments.test.mjs pay-nl.test.mjs toast.test.mjs redact-url.test.mjs hosted-entry.test.mjs comgate.test.mjs przelewy24.test.mjs tokenex-iframe.test.mjs transbank.test.mjs sumup.test.mjs clover.test.mjs eximbay.test.mjs xendit.test.mjs omise.test.mjs fastspring.test.mjs amazon-payment-services.test.mjs barion.test.mjs paymob.test.mjs payu-latam.test.mjs nexi-checkout.test.mjs pin-payments.test.mjs && node --test preflight-package.test.mjs preflight-collector.test.mjs browser-tests.test.mjs && node --test kernel-native-qualification.test.mjs && node --test ../vault/scripts/recurly-validation/watch-duty-sdk-result.test.mjs && node scripts/verify-pack.mjs",
33
+ "test": "npm run check:built && node test.mjs && node --test lifecycle.test.mjs merchant-abort.test.mjs preparation.test.mjs braintree.test.mjs pre-claim.test.mjs ekashu.test.mjs redsys.test.mjs quickpay.test.mjs paytrail.test.mjs paypal-hosted-fields.test.mjs paypal-card-forms.test.mjs cybersource-secure-acceptance.test.mjs ebanx.test.mjs payrexx.test.mjs payrexx-follow-ups.test.mjs payrexx-adapters.test.mjs nike-order.test.mjs nike-order-adapters.test.mjs autopilot.test.mjs stripe-checkout.test.mjs stripe-setup.test.mjs stripe-legacy-checkout.test.mjs payment-core.test.mjs prepared-processor.test.mjs merchant-hosted.test.mjs merchant-total.test.mjs sandbox-declaration.test.mjs minimum-delay.test.mjs paysafe.test.mjs wix-payments.test.mjs hipay.test.mjs openpay.test.mjs processout.test.mjs payu.test.mjs attachment.test.mjs worker-targets.test.mjs mercado-checkout.test.mjs mercado-polling.test.mjs amadeus.test.mjs pelecard.test.mjs aci.test.mjs primer.test.mjs payrails.test.mjs elavon-converge.test.mjs agentcard.test.mjs buy.test.mjs clean-dist.test.mjs approvals.test.mjs gmo.test.mjs cybersource-flex.test.mjs juspay-gate.test.mjs card-endpoint.test.mjs card-endpoint-fastspring.test.mjs card-endpoint-navigation.test.mjs merchant-session-probe.test.mjs datatrans.test.mjs authorize-net-dpm.test.mjs creditguard.test.mjs eprotect.test.mjs wspay.test.mjs shiji-sts.test.mjs worldline-mycheckout.test.mjs verifone.test.mjs gravy.test.mjs paddle-vgs.test.mjs sbps.test.mjs hold.test.mjs paddle-tokenex.test.mjs lyra.test.mjs gopay.test.mjs paygent.test.mjs twoc2p.test.mjs tap-payments.test.mjs pay-nl.test.mjs toast.test.mjs redact-url.test.mjs hosted-entry.test.mjs comgate.test.mjs przelewy24.test.mjs tokenex-iframe.test.mjs transbank.test.mjs sumup.test.mjs clover.test.mjs eximbay.test.mjs xendit.test.mjs omise.test.mjs fastspring.test.mjs amazon-payment-services.test.mjs barion.test.mjs paymob.test.mjs payu-latam.test.mjs nexi-checkout.test.mjs oceanpayment.test.mjs pin-payments.test.mjs payplug.test.mjs paymentwall.test.mjs vtex-payments.test.mjs vtex-payments-window.test.mjs iyzico.test.mjs usaepay.test.mjs && node --test preflight-package.test.mjs preflight-collector.test.mjs browser-tests.test.mjs && node --test kernel-native-qualification.test.mjs && node --test ../vault/scripts/recurly-validation/watch-duty-sdk-result.test.mjs && node scripts/verify-pack.mjs",
34
34
  "test:browser": "node browser-tests.mjs",
35
35
  "check:payment-core": "node scripts/generate-payment-core.mjs --check",
36
- "check:voice-stream": "node scripts/generate-voice-stream.mjs --check",
37
36
  "test:preflight": "node --test preflight-package.test.mjs preflight-collector.test.mjs kernel-native-qualification.test.mjs",
38
37
  "test:preflight:browser": "node preflight-browser.test.mjs",
39
38
  "pack:preview": "node scripts/pack-preflight-preview.mjs",
@@ -46,7 +45,6 @@
46
45
  "browser-automation",
47
46
  "pci",
48
47
  "checkout",
49
- "voice",
50
48
  "agentcard"
51
49
  ],
52
50
  "engines": {
@@ -1,23 +0,0 @@
1
- /** A language tag as BCP 47 spells it: `en`, `es`, `pt-BR`. */
2
- export type Language = string;
3
- /** One language Agentcard speaks, as the API lists it. */
4
- export interface LanguageInfo {
5
- /** The BCP 47 tag your calls name (`en`). */
6
- tag: Language;
7
- /** The language's own name for itself (`English`, `Español`). */
8
- name: string;
9
- }
10
- export declare class Languages {
11
- private readonly request;
12
- private cached;
13
- private inflight;
14
- constructor(request: <T>(path: string) => Promise<T>);
15
- /**
16
- * The languages Agentcard speaks, read once and kept for ten minutes. `null`
17
- * when the API does not serve the list (an API older than the route), in
18
- * which case tags are passed through unchecked and the API judges them.
19
- */
20
- list(): Promise<LanguageInfo[] | null>;
21
- /** Refuses a tag the API did not list (`unsupported_language`) before any call leaves; a well-formed tag passes when the API serves no list. */
22
- check(tag: Language | undefined): Promise<void>;
23
- }
package/dist/languages.js DELETED
@@ -1,76 +0,0 @@
1
- /**
2
- * Languages are data, not types. A language is a BCP 47 tag (`en`, `es`,
3
- * `pt-BR`), and the list Agentcard speaks is read from the API
4
- * (`GET /api/v2/voice/languages`), so a language added on Agentcard's side
5
- * needs no release of this package. Every call that names a `lang` asks this
6
- * guard first and is refused with `unsupported_language` before anything is
7
- * sent when the tag is not on the list.
8
- */
9
- import { AgentcardError } from './voice-types.js';
10
- /** The list out of either wire shape: `data` on the list envelope, else `languages`; null when neither is a list. */
11
- function listOf(body) {
12
- if (Array.isArray(body?.data))
13
- return body.data;
14
- if (Array.isArray(body?.languages))
15
- return body.languages;
16
- return null;
17
- }
18
- /** A tag's shape, before the list is consulted: a primary subtag and optional subtags, letters and digits only. */
19
- const TAG_SHAPE = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{1,8})*$/;
20
- /** How long a read list is trusted before it is read again. */
21
- const LIST_TTL_MS = 10 * 60_000;
22
- export class Languages {
23
- request;
24
- cached = null;
25
- inflight = null;
26
- constructor(request) {
27
- this.request = request;
28
- }
29
- /**
30
- * The languages Agentcard speaks, read once and kept for ten minutes. `null`
31
- * when the API does not serve the list (an API older than the route), in
32
- * which case tags are passed through unchecked and the API judges them.
33
- */
34
- async list() {
35
- if (this.cached && Date.now() - this.cached.at < LIST_TTL_MS)
36
- return this.cached.list;
37
- if (this.inflight)
38
- return this.inflight;
39
- this.inflight = (async () => {
40
- let list;
41
- try {
42
- const body = await this.request('/api/v2/voice/languages');
43
- const wire = listOf(body);
44
- list = wire
45
- ? wire.flatMap((l) => (l && typeof l === 'object' && typeof l.tag === 'string'
46
- ? [{ tag: l.tag, name: typeof l.name === 'string' ? l.name : l.tag }]
47
- : []))
48
- : null;
49
- }
50
- catch (err) {
51
- // An API that has no list yet answers 404; the tag then travels unchecked. Anything else is the caller's to see.
52
- if (err instanceof AgentcardError && (err.status === 404 || err.code === 'not_found'))
53
- list = null;
54
- else
55
- throw err;
56
- }
57
- this.cached = { list, at: Date.now() };
58
- return list;
59
- })().finally(() => { this.inflight = null; });
60
- return this.inflight;
61
- }
62
- /** Refuses a tag the API did not list (`unsupported_language`) before any call leaves; a well-formed tag passes when the API serves no list. */
63
- async check(tag) {
64
- if (tag === undefined)
65
- return;
66
- if (typeof tag !== 'string' || !TAG_SHAPE.test(tag)) {
67
- throw new AgentcardError('unsupported_language', `'${String(tag)}' is not a language tag (BCP 47: en, es, pt-BR). Refused before any call.`);
68
- }
69
- const list = await this.list();
70
- if (list === null)
71
- return;
72
- if (!list.some((l) => l.tag.toLowerCase() === tag.toLowerCase())) {
73
- throw new AgentcardError('unsupported_language', `Agentcard does not speak '${tag}' yet. It speaks ${list.map((l) => l.tag).join(', ') || 'no language on this API'}; read voice.languages() for the list. Refused before any call.`, undefined, { tag, languages: list.map((l) => l.tag) });
74
- }
75
- }
76
- }
@@ -1,49 +0,0 @@
1
- /**
2
- * The grant's client half: a PKCE verifier and its S256
3
- * challenge (RFC 7636), and the opaque `state` the return link carries back.
4
- * Random bytes come from the platform's WebCrypto; SHA-256 from WebCrypto
5
- * where it exists (Node, browsers, workers), else from the small
6
- * implementation below, so the module keeps zero dependencies on a phone
7
- * runtime with no `crypto.subtle`. A runtime with no secure random source
8
- * names one through `VoiceOptions.pkce.randomBytes`; nothing here ever
9
- * falls back to `Math.random`.
10
- */
11
- import { type ReturnLink } from './voice-types.js';
12
- /** Seams for a runtime without WebCrypto (a React Native app running the demo's adapter). */
13
- export interface PkceCrypto {
14
- /** `n` cryptographically random bytes. Default: `crypto.getRandomValues`. */
15
- randomBytes?: (n: number) => Uint8Array;
16
- /** SHA-256 of the bytes. Default: `crypto.subtle.digest`, else the built-in implementation. */
17
- sha256?: (bytes: Uint8Array) => Promise<Uint8Array> | Uint8Array;
18
- }
19
- export declare const PKCE_UNAVAILABLE_MESSAGE = "This runtime has no crypto.getRandomValues, so the client cannot mint a PKCE verifier. Name voice: { pkce: { randomBytes } } with a secure source, or pass pkce: false to connect (the polling shape, deprecated).";
20
- export declare function randomBytes(n: number, seam: PkceCrypto | undefined): Uint8Array;
21
- export declare function sha256(bytes: Uint8Array, seam: PkceCrypto | undefined): Promise<Uint8Array>;
22
- /** RFC 4648 §5, no padding: what a verifier, a challenge and a state are made of. */
23
- export declare function base64url(bytes: Uint8Array): string;
24
- /** The ASCII bytes of a verifier (it is base64url, so ASCII by construction). */
25
- export declare function asciiBytes(s: string): Uint8Array;
26
- export interface PkcePair {
27
- /** 43 characters of base64url (32 random bytes): within RFC 7636's 43–128. */
28
- code_verifier: string;
29
- /** base64url(SHA-256(code_verifier)). */
30
- code_challenge: string;
31
- code_challenge_method: 'S256';
32
- /** 22 characters of base64url (16 random bytes), opaque. */
33
- state: string;
34
- }
35
- export declare function mintPkce(seam: PkceCrypto | undefined): Promise<PkcePair>;
36
- /** The `code` and `state` a return link carries, read from its query alone; the scheme may be an app's own. */
37
- export declare function grantFromReturnLink(url: string): {
38
- code: string | null;
39
- state: string | null;
40
- };
41
- /**
42
- * A return link, read from its query alone (the scheme may be an app's own, `yourapp://connected?…`): the
43
- * grant's `code` and `state` (null on a link minted to poll: a reset, an action, `pkce: false`) and the
44
- * `voice_reset` outcome the Vault appends when the visit reset the person's voice key (`done`, `unchanged`,
45
- * `failed`; null when the link says nothing about a reset, and for any other word). A pure function with no
46
- * client behind it: the app half reads the sheet's result with it too.
47
- */
48
- export declare function readReturnLink(url: string): ReturnLink;
49
- export declare function sha256Pure(input: Uint8Array): Uint8Array;
@@ -1,147 +0,0 @@
1
- /**
2
- * The grant's client half: a PKCE verifier and its S256
3
- * challenge (RFC 7636), and the opaque `state` the return link carries back.
4
- * Random bytes come from the platform's WebCrypto; SHA-256 from WebCrypto
5
- * where it exists (Node, browsers, workers), else from the small
6
- * implementation below, so the module keeps zero dependencies on a phone
7
- * runtime with no `crypto.subtle`. A runtime with no secure random source
8
- * names one through `VoiceOptions.pkce.randomBytes`; nothing here ever
9
- * falls back to `Math.random`.
10
- */
11
- import { AgentcardError } from './voice-types.js';
12
- export const PKCE_UNAVAILABLE_MESSAGE = 'This runtime has no crypto.getRandomValues, so the client cannot mint a PKCE verifier. Name voice: { pkce: { randomBytes } } with a secure source, or pass pkce: false to connect (the polling shape, deprecated).';
13
- export function randomBytes(n, seam) {
14
- if (seam?.randomBytes) {
15
- const out = seam.randomBytes(n);
16
- if (!(out instanceof Uint8Array) || out.length !== n)
17
- throw new AgentcardError('pkce_unavailable', `voice.pkce.randomBytes must return ${n} bytes.`);
18
- return out;
19
- }
20
- const c = globalThis.crypto;
21
- if (!c?.getRandomValues)
22
- throw new AgentcardError('pkce_unavailable', PKCE_UNAVAILABLE_MESSAGE);
23
- return c.getRandomValues(new Uint8Array(n));
24
- }
25
- export async function sha256(bytes, seam) {
26
- if (seam?.sha256)
27
- return seam.sha256(bytes);
28
- const subtle = globalThis.crypto?.subtle;
29
- if (subtle?.digest)
30
- return new Uint8Array(await subtle.digest('SHA-256', bytes));
31
- return sha256Pure(bytes);
32
- }
33
- /** RFC 4648 §5, no padding: what a verifier, a challenge and a state are made of. */
34
- export function base64url(bytes) {
35
- const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
36
- let out = '';
37
- for (let i = 0; i < bytes.length; i += 3) {
38
- const a = bytes[i], b = bytes[i + 1], c = bytes[i + 2];
39
- const n = (a << 16) | ((b ?? 0) << 8) | (c ?? 0);
40
- out += alphabet[(n >>> 18) & 63] + alphabet[(n >>> 12) & 63];
41
- if (b !== undefined)
42
- out += alphabet[(n >>> 6) & 63];
43
- if (c !== undefined)
44
- out += alphabet[n & 63];
45
- }
46
- return out;
47
- }
48
- /** The ASCII bytes of a verifier (it is base64url, so ASCII by construction). */
49
- export function asciiBytes(s) {
50
- const out = new Uint8Array(s.length);
51
- for (let i = 0; i < s.length; i++)
52
- out[i] = s.charCodeAt(i) & 0x7f;
53
- return out;
54
- }
55
- export async function mintPkce(seam) {
56
- const code_verifier = base64url(randomBytes(32, seam));
57
- const code_challenge = base64url(await sha256(asciiBytes(code_verifier), seam));
58
- const state = base64url(randomBytes(16, seam));
59
- return { code_verifier, code_challenge, code_challenge_method: 'S256', state };
60
- }
61
- /** The `code` and `state` a return link carries, read from its query alone; the scheme may be an app's own. */
62
- export function grantFromReturnLink(url) {
63
- const { code, state } = readReturnLink(url);
64
- return { code, state };
65
- }
66
- /**
67
- * A return link, read from its query alone (the scheme may be an app's own, `yourapp://connected?…`): the
68
- * grant's `code` and `state` (null on a link minted to poll: a reset, an action, `pkce: false`) and the
69
- * `voice_reset` outcome the Vault appends when the visit reset the person's voice key (`done`, `unchanged`,
70
- * `failed`; null when the link says nothing about a reset, and for any other word). A pure function with no
71
- * client behind it: the app half reads the sheet's result with it too.
72
- */
73
- export function readReturnLink(url) {
74
- const q = url.indexOf('?');
75
- if (q < 0)
76
- return { code: null, state: null, voice_reset: null };
77
- const hash = url.indexOf('#', q);
78
- const params = new URLSearchParams(url.slice(q + 1, hash < 0 ? undefined : hash));
79
- const reset = params.get('voice_reset');
80
- return {
81
- code: params.get('code'),
82
- state: params.get('state'),
83
- voice_reset: reset === 'done' || reset === 'unchanged' || reset === 'failed' ? reset : null,
84
- };
85
- }
86
- // ─── SHA-256, FIPS 180-4, for a runtime without crypto.subtle ───────────────
87
- const K = new Uint32Array([
88
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
89
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
90
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
91
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
92
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
93
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
94
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
95
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
96
- ]);
97
- export function sha256Pure(input) {
98
- const bitLength = input.length * 8;
99
- const padded = new Uint8Array(((input.length + 9 + 63) >> 6) << 6);
100
- padded.set(input);
101
- padded[input.length] = 0x80;
102
- const view = new DataView(padded.buffer);
103
- view.setUint32(padded.length - 8, Math.floor(bitLength / 0x100000000));
104
- view.setUint32(padded.length - 4, bitLength >>> 0);
105
- const h = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);
106
- const w = new Uint32Array(64);
107
- const rotr = (x, n) => (x >>> n) | (x << (32 - n));
108
- for (let off = 0; off < padded.length; off += 64) {
109
- for (let i = 0; i < 16; i++)
110
- w[i] = view.getUint32(off + i * 4);
111
- for (let i = 16; i < 64; i++) {
112
- const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
113
- const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
114
- w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;
115
- }
116
- let [a, b, c, d, e, f, g, hh] = h;
117
- for (let i = 0; i < 64; i++) {
118
- const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
119
- const ch = (e & f) ^ (~e & g);
120
- const t1 = (hh + S1 + ch + K[i] + w[i]) >>> 0;
121
- const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
122
- const maj = (a & b) ^ (a & c) ^ (b & c);
123
- const t2 = (S0 + maj) >>> 0;
124
- hh = g;
125
- g = f;
126
- f = e;
127
- e = (d + t1) >>> 0;
128
- d = c;
129
- c = b;
130
- b = a;
131
- a = (t1 + t2) >>> 0;
132
- }
133
- h[0] = (h[0] + a) >>> 0;
134
- h[1] = (h[1] + b) >>> 0;
135
- h[2] = (h[2] + c) >>> 0;
136
- h[3] = (h[3] + d) >>> 0;
137
- h[4] = (h[4] + e) >>> 0;
138
- h[5] = (h[5] + f) >>> 0;
139
- h[6] = (h[6] + g) >>> 0;
140
- h[7] = (h[7] + hh) >>> 0;
141
- }
142
- const out = new Uint8Array(32);
143
- const ov = new DataView(out.buffer);
144
- for (let i = 0; i < 8; i++)
145
- ov.setUint32(i * 4, h[i]);
146
- return out;
147
- }