@agent-cards/sdk 0.23.28 → 0.24.1
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/CHANGELOG.md +84 -0
- package/PREFLIGHT.md +7 -1
- package/README.md +197 -102
- package/dist/aci.d.ts +52 -22
- package/dist/aci.js +79 -15
- package/dist/adyen-merchant-hosted.generated.d.ts +2 -2
- package/dist/adyen-merchant-hosted.generated.js +586 -55
- package/dist/agent-amount.generated.js +1 -1
- package/dist/agentcard.d.ts +4 -5
- package/dist/agentcard.js +4 -5
- package/dist/amadeus.d.ts +9 -3
- package/dist/amadeus.js +33 -4
- package/dist/api-module.d.ts +1 -7
- package/dist/api-module.js +3 -5
- package/dist/{voice-retry.js → api-retry.js} +1 -1
- package/dist/api-types.d.ts +53 -0
- package/dist/{voice-types.js → api-types.js} +7 -2
- package/dist/approvals.d.ts +166 -0
- package/dist/approvals.js +213 -0
- package/dist/aurus.d.ts +33 -0
- package/dist/aurus.js +75 -0
- package/dist/builtin-registry.generated.js +1 -1
- package/dist/buy.d.ts +20 -101
- package/dist/buy.js +19 -74
- package/dist/capabilities.generated.js +1 -1
- package/dist/card-fields.generated.js +2864 -249
- package/dist/cardlink-vpos.d.ts +43 -0
- package/dist/cardlink-vpos.js +90 -0
- package/dist/cdp.d.ts +3 -13
- package/dist/cdp.js +244 -175
- package/dist/checkout-com.generated.js +5 -1
- package/dist/client.d.ts +170 -22
- package/dist/client.js +281 -40
- package/dist/creditguard.generated.d.ts +4 -4
- package/dist/cybersource-flex.generated.d.ts +39 -1
- package/dist/cybersource-flex.generated.js +100 -11
- package/dist/datatrans.generated.js +22 -1
- package/dist/eghl.d.ts +40 -0
- package/dist/eghl.js +72 -0
- package/dist/elavon-converge.generated.js +5 -3
- package/dist/gmo.generated.js +7 -2
- package/dist/hold.d.ts +8 -0
- package/dist/hold.js +43 -2
- package/dist/hosted-entry.js +4 -0
- package/dist/index.d.ts +9 -15
- package/dist/index.js +6 -10
- package/dist/lifecycle.d.ts +9 -61
- package/dist/lifecycle.js +24 -10
- package/dist/merchant-card-endpoints.generated.d.ts +6 -1
- package/dist/merchant-card-endpoints.generated.js +344 -19
- package/dist/merchant-hosted.d.ts +8 -1
- package/dist/nike-order.d.ts +51 -0
- package/dist/nike-order.js +81 -0
- package/dist/oceanpayment.d.ts +38 -0
- package/dist/oceanpayment.js +70 -0
- package/dist/paddle-tokenex.generated.js +111 -11
- package/dist/payplug.d.ts +41 -0
- package/dist/payplug.js +71 -0
- package/dist/payrails.generated.js +33 -8
- package/dist/pre-claim.d.ts +11 -0
- package/dist/pre-claim.js +130 -7
- package/dist/preflight-capabilities.generated.d.ts +0 -4
- package/dist/preflight-capabilities.generated.js +0 -5
- package/dist/preflight-catalog.json +200 -6
- package/dist/preflight-playwright.d.ts +2 -2
- package/dist/preflight-playwright.js +63 -14
- package/dist/preflight-schemas.json +18 -0
- package/dist/preflight.generated.d.ts +5 -4
- package/dist/preflight.generated.js +63 -3
- package/dist/preparation.d.ts +7 -0
- package/dist/preparation.js +21 -0
- package/dist/prepared-processor.d.ts +18 -5
- package/dist/prepared-processor.js +48 -8
- package/dist/primer.generated.js +2889 -268
- package/dist/processout.generated.d.ts +61 -0
- package/dist/processout.generated.js +577 -0
- package/dist/requests.js +1 -1
- package/dist/shiji-sts.generated.js +111 -11
- package/dist/stripe-checkout.generated.js +2761 -319
- package/dist/substitutions.generated.js +553 -26
- package/dist/tap-payments.generated.js +111 -11
- package/dist/twoc2p.generated.js +111 -11
- package/dist/url-masks/bluesnap.d.ts +2 -0
- package/dist/url-masks/bluesnap.js +15 -0
- package/dist/url-masks/oceanpayment.d.ts +2 -0
- package/dist/url-masks/oceanpayment.js +13 -0
- package/dist/url-masks/payplug.d.ts +2 -0
- package/dist/url-masks/payplug.js +13 -0
- package/dist/url-masks/vtex_payments.d.ts +2 -0
- package/dist/url-masks/vtex_payments.js +12 -0
- package/dist/url-masks.generated.d.ts +1 -1
- package/dist/url-masks.generated.js +6 -2
- package/dist/verifone.generated.js +42 -2
- package/dist/vtex-payments.generated.d.ts +127 -0
- package/dist/vtex-payments.generated.js +544 -0
- package/dist/webhooks.d.ts +2 -2
- package/dist/webhooks.js +2 -2
- package/examples/preflight/kernel-native/inventory.json +1 -1
- package/package.json +6 -8
- package/dist/languages.d.ts +0 -23
- package/dist/languages.js +0 -76
- package/dist/voice-pkce.d.ts +0 -49
- package/dist/voice-pkce.js +0 -147
- package/dist/voice-stream.generated.d.ts +0 -118
- package/dist/voice-stream.generated.js +0 -170
- package/dist/voice-types.d.ts +0 -735
- package/dist/voice.d.ts +0 -373
- package/dist/voice.js +0 -815
- package/readme.test.mjs +0 -53
- /package/dist/{voice-retry.d.ts → api-retry.d.ts} +0 -0
package/dist/webhooks.d.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* missed event, and hands back the event typed by its `type`. WebCrypto only,
|
|
8
8
|
* so it runs wherever the client runs.
|
|
9
9
|
*/
|
|
10
|
-
import { type AuthorizationStatus, type Settlement, type TerminalReason } from './
|
|
10
|
+
import { type AuthorizationStatus, type Settlement, type TerminalReason } from './api-types.js';
|
|
11
11
|
/** The purchase events an endpoint receives, `checkout_authorization.*`. */
|
|
12
|
-
export declare const CHECKOUT_AUTHORIZATION_EVENT_TYPES: readonly ["checkout_authorization.created", "checkout_authorization.notified", "checkout_authorization.watched", "checkout_authorization.approved", "checkout_authorization.declined", "checkout_authorization.refused", "checkout_authorization.expired", "checkout_authorization.cancelled", "checkout_authorization.submitted", "checkout_authorization.submitted_on_device", "checkout_authorization.replay_started", "checkout_authorization.amount_mismatch", "checkout_authorization.duplicate_charge", "checkout_authorization.duplicate_guard_reported", "checkout_authorization.outcome_reported", "checkout_authorization.continuation_checked", "checkout_authorization.bank_check_started", "checkout_authorization.settled", "checkout_authorization.settlement_unconfirmed", "checkout_authorization.autopilot_dispatched", "checkout_authorization.autopilot_completed"
|
|
12
|
+
export declare const CHECKOUT_AUTHORIZATION_EVENT_TYPES: readonly ["checkout_authorization.created", "checkout_authorization.notified", "checkout_authorization.watched", "checkout_authorization.approved", "checkout_authorization.declined", "checkout_authorization.refused", "checkout_authorization.expired", "checkout_authorization.cancelled", "checkout_authorization.submitted", "checkout_authorization.submitted_on_device", "checkout_authorization.replay_started", "checkout_authorization.amount_mismatch", "checkout_authorization.duplicate_charge", "checkout_authorization.duplicate_guard_reported", "checkout_authorization.outcome_reported", "checkout_authorization.continuation_checked", "checkout_authorization.bank_check_started", "checkout_authorization.settled", "checkout_authorization.settlement_unconfirmed", "checkout_authorization.autopilot_dispatched", "checkout_authorization.autopilot_completed"];
|
|
13
13
|
export type CheckoutAuthorizationEventType = (typeof CHECKOUT_AUTHORIZATION_EVENT_TYPES)[number];
|
|
14
14
|
/** The Vault events, `vault.*`: a person connected, stored a card, added or used a passkey. */
|
|
15
15
|
export declare const VAULT_EVENT_TYPES: readonly ["vault.session_linked", "vault.card_stored", "vault.passkey_added", "vault.passkey_signin"];
|
package/dist/webhooks.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* missed event, and hands back the event typed by its `type`. WebCrypto only,
|
|
8
8
|
* so it runs wherever the client runs.
|
|
9
9
|
*/
|
|
10
|
-
import { AgentcardError } from './
|
|
10
|
+
import { AgentcardError } from './api-types.js';
|
|
11
11
|
/** The purchase events an endpoint receives, `checkout_authorization.*`. */
|
|
12
12
|
export const CHECKOUT_AUTHORIZATION_EVENT_TYPES = [
|
|
13
13
|
'checkout_authorization.created', 'checkout_authorization.notified', 'checkout_authorization.watched', 'checkout_authorization.approved',
|
|
@@ -16,7 +16,7 @@ export const CHECKOUT_AUTHORIZATION_EVENT_TYPES = [
|
|
|
16
16
|
'checkout_authorization.amount_mismatch', 'checkout_authorization.duplicate_charge', 'checkout_authorization.duplicate_guard_reported',
|
|
17
17
|
'checkout_authorization.outcome_reported', 'checkout_authorization.continuation_checked', 'checkout_authorization.bank_check_started',
|
|
18
18
|
'checkout_authorization.settled', 'checkout_authorization.settlement_unconfirmed',
|
|
19
|
-
'checkout_authorization.autopilot_dispatched', 'checkout_authorization.autopilot_completed',
|
|
19
|
+
'checkout_authorization.autopilot_dispatched', 'checkout_authorization.autopilot_completed',
|
|
20
20
|
];
|
|
21
21
|
/** The Vault events, `vault.*`: a person connected, stored a card, added or used a passkey. */
|
|
22
22
|
export const VAULT_EVENT_TYPES = ['vault.session_linked', 'vault.card_stored', 'vault.passkey_added', 'vault.passkey_signin'];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"catalog_version": "2026-09-15.1",
|
|
4
|
-
"catalog_sha256": "
|
|
4
|
+
"catalog_sha256": "86bf0b382e6d847b49d00310f262cf697a0189d4badf89c36ebfb595e07a005b",
|
|
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.
|
|
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;
|
|
3
|
+
"version": "0.24.1",
|
|
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)
|
|
28
|
-
"build": "node
|
|
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-
|
|
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
|
|
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 cardlink-vpos.test.mjs eghl.test.mjs paymentwall.test.mjs vtex-payments.test.mjs vtex-payments-window.test.mjs iyzico.test.mjs usaepay.test.mjs viva-wallet.test.mjs aurus.test.mjs monei.test.mjs paystack.test.mjs frisbii.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": {
|
package/dist/languages.d.ts
DELETED
|
@@ -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
|
-
}
|
package/dist/voice-pkce.d.ts
DELETED
|
@@ -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;
|
package/dist/voice-pkce.js
DELETED
|
@@ -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
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The streaming door, from either side: the person's
|
|
3
|
-
* answer goes to the verifier as it is spoken, over one WebSocket, and the
|
|
4
|
-
* verifier says `hearing` the moment the key word is out and `verdict` when it
|
|
5
|
-
* has closed the span. One call serves a live microphone and a finished
|
|
6
|
-
* recording alike: a buffer pushed in one go and ended is a short stream.
|
|
7
|
-
*
|
|
8
|
-
* Uses the platform's WebSocket (Node 22, React Native, the browser). The
|
|
9
|
-
* credential rides in the first frame, never in a header, so every platform
|
|
10
|
-
* behaves the same.
|
|
11
|
-
*/
|
|
12
|
-
import { AgentcardError, type Lang, type Verdict } from './voice-types.js';
|
|
13
|
-
/**
|
|
14
|
-
* How the bytes are encoded. `pcm16-16k`: little-endian 16-bit mono at
|
|
15
|
-
* 16 kHz, judged live. `mulaw-8k`: a telephone band, judged on the words
|
|
16
|
-
* only. `opus`: an Ogg or WebM Opus stream, judged live. A media type such
|
|
17
|
-
* as `audio/m4a` or `audio/wav`: a finished recording pushed in one go, held
|
|
18
|
-
* until `end`, then judged exactly as an upload of the same bytes.
|
|
19
|
-
*/
|
|
20
|
-
export type StreamFormat = 'pcm16-16k' | 'mulaw-8k' | 'opus' | `audio/${string}`;
|
|
21
|
-
/**
|
|
22
|
-
* How the take is heard: the phone's own microphone, a wired headset, a Bluetooth one, or
|
|
23
|
-
* unknown when the platform says nothing. The verifier scores the voice on that route's cohort when it has one
|
|
24
|
-
* and records a change from the enrolment's route as evidence; only the kind travels, never a device name.
|
|
25
|
-
*/
|
|
26
|
-
export type ChannelKind = 'builtin' | 'wired' | 'bluetooth' | 'unknown';
|
|
27
|
-
export declare const CHANNEL_KINDS: readonly ChannelKind[];
|
|
28
|
-
/** The key word (and, on a phone's stream, the price) is out: a bot may start its next line now. `heard_count` is how many words landed; the words themselves never cross (WP115). */
|
|
29
|
-
export interface Hearing {
|
|
30
|
-
heard_count: number;
|
|
31
|
-
}
|
|
32
|
-
/** The verifier's verdict on the stream: the upload verdict plus what the live door knows. */
|
|
33
|
-
/**
|
|
34
|
-
* The verifier's signed word on a take (WP182): `payload` is the exact JSON string the signature covers (the challenge
|
|
35
|
-
* id, `accepted`, the template hash it matched, `z`, `cos`, `spoof_bits`, `issued_at`), `signature` the raw ECDSA
|
|
36
|
-
* `r || s` bytes base64url under the receipt key the Vault's page stamped on the listen, `kid` that key's name. The
|
|
37
|
-
* host relays it to the frame as `host-judged` once the proof landed; the frame checks the signature itself.
|
|
38
|
-
*/
|
|
39
|
-
export interface VerdictReceipt {
|
|
40
|
-
payload: string;
|
|
41
|
-
signature: string;
|
|
42
|
-
alg: string;
|
|
43
|
-
kid: string;
|
|
44
|
-
}
|
|
45
|
-
export interface StreamVerdict extends Verdict {
|
|
46
|
-
reason: string;
|
|
47
|
-
bits: {
|
|
48
|
-
words: number;
|
|
49
|
-
voice: number;
|
|
50
|
-
total: number;
|
|
51
|
-
};
|
|
52
|
-
cos: number | null;
|
|
53
|
-
z: number | null;
|
|
54
|
-
speech_s: number;
|
|
55
|
-
/** From the first byte to the verdict. */
|
|
56
|
-
ms: number;
|
|
57
|
-
/** From the caller's last byte (or `end`) to the verdict: what streaming saves. */
|
|
58
|
-
since_end_ms: number;
|
|
59
|
-
/** Why the verifier closed the span: `all_words`, `quiet`, `ended`, `stalled`, `span_cap`, `wall_cap`. */
|
|
60
|
-
closed_by: string;
|
|
61
|
-
/** The verifier's signed receipt for this take (WP182), when it sent one. */
|
|
62
|
-
receipt?: VerdictReceipt;
|
|
63
|
-
}
|
|
64
|
-
export interface StreamInput {
|
|
65
|
-
/** The verifier's streaming address, `wss://…/v1/stream` (`ws://` against a local verifier). */
|
|
66
|
-
stream_url: string;
|
|
67
|
-
authorization_id: string;
|
|
68
|
-
challenge_id: string;
|
|
69
|
-
lang: Lang;
|
|
70
|
-
format: StreamFormat;
|
|
71
|
-
/** The credential for this answer: the challenge's `answer_token` on the app side, the business's bearer on the server side. */
|
|
72
|
-
token: string;
|
|
73
|
-
/** The channel the take is heard on, when known at the open; `handle.channel(kind)` names it later. */
|
|
74
|
-
channel?: ChannelKind;
|
|
75
|
-
/** Test seam: the WebSocket constructor; defaults to the platform's. */
|
|
76
|
-
WebSocket?: typeof WebSocket;
|
|
77
|
-
}
|
|
78
|
-
type Listener<T> = (value: T) => void;
|
|
79
|
-
export interface StreamHandle {
|
|
80
|
-
readonly format: StreamFormat;
|
|
81
|
-
/** Queue bytes; they go the moment the socket is open. */
|
|
82
|
-
push(chunk: ArrayBuffer | Uint8Array): void;
|
|
83
|
-
/** Nothing more is coming: the verifier closes the span with what it has. */
|
|
84
|
-
end(): void;
|
|
85
|
-
/** How the take is heard, once the microphone is open and the device is known; before the verdict. */
|
|
86
|
-
channel(kind: ChannelKind): void;
|
|
87
|
-
/**
|
|
88
|
-
* The audio that follows is sealed (WP115): the take's ephemeral key goes ahead of it as the stream's `sealed`
|
|
89
|
-
* frame, once, before the first push. The verifier opens every later chunk with it; this side reads none of them.
|
|
90
|
-
* `kid` names the verifier key the take was sealed to (the first sixteen hex characters of SHA-256 over its SPKI,
|
|
91
|
-
* as the frame computes it): after a key rotation the verifier opens the take under the key it names, inside the
|
|
92
|
-
* previous key's grace window, instead of assuming the current one and refusing. A head with no `kid` means the
|
|
93
|
-
* current key, as a frame from before the field sealed to it.
|
|
94
|
-
*/
|
|
95
|
-
seal(head: {
|
|
96
|
-
alg: string;
|
|
97
|
-
eph: string;
|
|
98
|
-
kid?: string;
|
|
99
|
-
}): void;
|
|
100
|
-
on(event: 'hearing', fn: Listener<Hearing>): StreamHandle;
|
|
101
|
-
on(event: 'verdict', fn: Listener<StreamVerdict>): StreamHandle;
|
|
102
|
-
on(event: 'error', fn: Listener<AgentcardError>): StreamHandle;
|
|
103
|
-
/** Resolves with the verdict; rejects with an `AgentcardError` carrying the verifier's code. */
|
|
104
|
-
verdict(): Promise<StreamVerdict>;
|
|
105
|
-
/** Drops the socket without a verdict (the person walked away). */
|
|
106
|
-
close(): void;
|
|
107
|
-
}
|
|
108
|
-
/** Opens the door and hands back the handle. The first frame names the challenge; bytes follow. */
|
|
109
|
-
export declare function openStream(input: StreamInput): StreamHandle;
|
|
110
|
-
/**
|
|
111
|
-
* A finished recording through the same door. For `pcm16-16k` with `chunkMs`
|
|
112
|
-
* the bytes go in timed chunks, as a microphone would send them; otherwise
|
|
113
|
-
* the whole buffer goes at once. Ends the stream and resolves the verdict.
|
|
114
|
-
*/
|
|
115
|
-
export declare function streamBuffer(handle: StreamHandle, bytes: ArrayBuffer | Uint8Array, chunkMs?: number): Promise<StreamVerdict>;
|
|
116
|
-
/** The verifier's streaming address from its origin (`/v1/stream` appended) or a full address, as given. */
|
|
117
|
-
export declare function streamAddress(verifierUrl: string): string;
|
|
118
|
-
export {};
|