@elizaos/plugin-elizacloud 2.0.0-beta.1 → 2.0.11-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -44
- package/auto-enable.ts +10 -5
- package/dist/browser/index.browser.js +2 -2
- package/dist/browser/index.browser.js.map +4 -4
- package/dist/cjs/index.node.cjs +2874 -5915
- package/dist/cjs/index.node.js.map +47 -116
- package/dist/cloud/auth-service-types.d.ts +8 -0
- package/dist/cloud/auth-service-types.d.ts.map +1 -0
- package/dist/cloud/auth-service-types.js +36 -0
- package/dist/cloud/auth-service-types.js.map +10 -0
- package/dist/cloud/auth.js +4 -51
- package/dist/cloud/auth.js.map +4 -4
- package/dist/cloud/base-url.d.ts +6 -2
- package/dist/cloud/base-url.d.ts.map +1 -1
- package/dist/cloud/base-url.js +3 -51
- package/dist/cloud/base-url.js.map +3 -3
- package/dist/cloud/bridge-client.d.ts +3 -3
- package/dist/cloud/bridge-client.d.ts.map +1 -1
- package/dist/cloud/bridge-client.js +3 -51
- package/dist/cloud/bridge-client.js.map +3 -3
- package/dist/cloud/clack-observer.d.ts +35 -0
- package/dist/cloud/clack-observer.d.ts.map +1 -0
- package/dist/cloud/clack-observer.js +143 -0
- package/dist/cloud/clack-observer.js.map +10 -0
- package/dist/cloud/cloud-manager.js +45 -92
- package/dist/cloud/cloud-manager.js.map +6 -6
- package/dist/cloud/cloud-wallet.js +2 -4835
- package/dist/cloud/cloud-wallet.js.map +3 -82
- package/dist/cloud/duffel-client.d.ts +181 -0
- package/dist/cloud/duffel-client.d.ts.map +1 -0
- package/dist/cloud/duffel-client.js +506 -0
- package/dist/cloud/duffel-client.js.map +11 -0
- package/dist/cloud/index.d.ts +6 -0
- package/dist/cloud/index.d.ts.map +1 -1
- package/dist/cloud/index.js +1782 -1
- package/dist/cloud/index.js.map +18 -3
- package/dist/cloud/lifeops-schedule-sync-client.d.ts +43 -0
- package/dist/cloud/lifeops-schedule-sync-client.d.ts.map +1 -0
- package/dist/cloud/lifeops-schedule-sync-client.js +180 -0
- package/dist/cloud/lifeops-schedule-sync-client.js.map +11 -0
- package/dist/cloud/lifeops-schedule-sync-contracts.d.ts +89 -0
- package/dist/cloud/lifeops-schedule-sync-contracts.d.ts.map +1 -0
- package/dist/cloud/lifeops-schedule-sync-contracts.js +39 -0
- package/dist/cloud/lifeops-schedule-sync-contracts.js.map +10 -0
- package/dist/cloud/managed-payment-clients.d.ts +166 -0
- package/dist/cloud/managed-payment-clients.d.ts.map +1 -0
- package/dist/cloud/managed-payment-clients.js +238 -0
- package/dist/cloud/managed-payment-clients.js.map +11 -0
- package/dist/cloud/null-observer.d.ts +35 -0
- package/dist/cloud/null-observer.d.ts.map +1 -0
- package/dist/cloud/null-observer.js +45 -0
- package/dist/cloud/null-observer.js.map +10 -0
- package/dist/cloud/setup-observer.d.ts +98 -0
- package/dist/cloud/setup-observer.d.ts.map +1 -0
- package/dist/cloud/setup-observer.js +2 -0
- package/dist/cloud/setup-observer.js.map +9 -0
- package/dist/cloud/validate-url.d.ts.map +1 -1
- package/dist/cloud/validate-url.js +2 -1
- package/dist/cloud/validate-url.js.map +3 -3
- package/dist/cloud/x402-payment-handler.d.ts +85 -0
- package/dist/cloud/x402-payment-handler.d.ts.map +1 -0
- package/dist/cloud/x402-payment-handler.js +119 -0
- package/dist/cloud/x402-payment-handler.js.map +10 -0
- package/dist/cloud-setup.d.ts +36 -0
- package/dist/cloud-setup.d.ts.map +1 -0
- package/dist/{onboarding.js → cloud-setup.js} +139 -139
- package/dist/cloud-setup.js.map +14 -0
- package/dist/cloud-voice-catalog.d.ts +65 -0
- package/dist/cloud-voice-catalog.d.ts.map +1 -0
- package/dist/cloud-voice-catalog.js +278 -0
- package/dist/cloud-voice-catalog.js.map +12 -0
- package/dist/index.browser.d.ts +11 -0
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5416 -8405
- package/dist/index.js.map +48 -116
- package/dist/index.node.d.ts +8 -1
- package/dist/index.node.d.ts.map +1 -1
- package/dist/init.js +17 -4
- package/dist/init.js.map +4 -4
- package/dist/lib/cloud-connection.d.ts +0 -1
- package/dist/lib/cloud-connection.d.ts.map +1 -1
- package/dist/lib/cloud-connection.js +14 -91
- package/dist/lib/cloud-connection.js.map +7 -7
- package/dist/lib/cloud-secrets.d.ts +5 -18
- package/dist/lib/cloud-secrets.d.ts.map +1 -1
- package/dist/lib/cloud-secrets.js +8 -36
- package/dist/lib/cloud-secrets.js.map +3 -3
- package/dist/lib/config-like.d.ts +1 -1
- package/dist/lib/config-like.d.ts.map +1 -1
- package/dist/lib/config-like.js +3 -3
- package/dist/lib/config-like.js.map +3 -3
- package/dist/lib/credential-type-map.d.ts +1 -1
- package/dist/lib/credential-type-map.js.map +1 -1
- package/dist/lib/http.d.ts +0 -11
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js.map +2 -2
- package/dist/lib/server-cloud-tts.d.ts +12 -25
- package/dist/lib/server-cloud-tts.d.ts.map +1 -1
- package/dist/lib/server-cloud-tts.js +31 -329
- package/dist/lib/server-cloud-tts.js.map +4 -7
- package/dist/lib/tts-debug.d.ts +5 -3
- package/dist/lib/tts-debug.d.ts.map +1 -1
- package/dist/lib/tts-debug.js +1 -34
- package/dist/lib/tts-debug.js.map +3 -4
- package/dist/models/embeddings.d.ts.map +1 -1
- package/dist/models/embeddings.js +79 -69
- package/dist/models/embeddings.js.map +6 -6
- package/dist/models/image.d.ts.map +1 -1
- package/dist/models/image.js +42 -15
- package/dist/models/image.js.map +6 -6
- package/dist/models/index.js +676 -166
- package/dist/models/index.js.map +11 -12
- package/dist/models/research.d.ts.map +1 -1
- package/dist/models/research.js +24 -7
- package/dist/models/research.js.map +6 -6
- package/dist/models/speech.d.ts +61 -3
- package/dist/models/speech.d.ts.map +1 -1
- package/dist/models/speech.js +173 -17
- package/dist/models/speech.js.map +5 -5
- package/dist/models/text.d.ts +106 -1
- package/dist/models/text.d.ts.map +1 -1
- package/dist/models/text.js +452 -82
- package/dist/models/text.js.map +7 -8
- package/dist/models/tokenization.d.ts.map +1 -1
- package/dist/models/tokenization.js.map +2 -2
- package/dist/models/transcription.d.ts.map +1 -1
- package/dist/models/transcription.js +20 -6
- package/dist/models/transcription.js.map +5 -5
- package/dist/node/index.node.js +2828 -5838
- package/dist/node/index.node.js.map +47 -116
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +376 -5050
- package/dist/plugin.js.map +16 -92
- package/dist/providers/openai.js +11 -2
- package/dist/providers/openai.js.map +3 -3
- package/dist/register-routes.js +376 -5050
- package/dist/register-routes.js.map +16 -92
- package/dist/routes/cloud-billing-routes.d.ts.map +1 -1
- package/dist/routes/cloud-billing-routes.js +17 -60
- package/dist/routes/cloud-billing-routes.js.map +8 -7
- package/dist/routes/cloud-coding-container-routes.d.ts +8 -0
- package/dist/routes/cloud-coding-container-routes.d.ts.map +1 -0
- package/dist/routes/cloud-coding-container-routes.js +214 -0
- package/dist/routes/cloud-coding-container-routes.js.map +11 -0
- package/dist/routes/cloud-compat-routes.d.ts.map +1 -1
- package/dist/routes/cloud-compat-routes.js +17 -60
- package/dist/routes/cloud-compat-routes.js.map +8 -7
- package/dist/routes/cloud-features-routes.js +2 -2
- package/dist/routes/cloud-features-routes.js.map +4 -4
- package/dist/routes/cloud-relay-routes.d.ts +2 -1
- package/dist/routes/cloud-relay-routes.d.ts.map +1 -1
- package/dist/routes/cloud-relay-routes.js +84 -2
- package/dist/routes/cloud-relay-routes.js.map +5 -4
- package/dist/routes/cloud-routes-autonomous.d.ts +3 -4
- package/dist/routes/cloud-routes-autonomous.d.ts.map +1 -1
- package/dist/routes/cloud-routes-autonomous.js +11 -4893
- package/dist/routes/cloud-routes-autonomous.js.map +8 -87
- package/dist/routes/cloud-routes.d.ts +2 -2
- package/dist/routes/cloud-routes.d.ts.map +1 -1
- package/dist/routes/cloud-routes.js +343 -5058
- package/dist/routes/cloud-routes.js.map +13 -90
- package/dist/routes/cloud-status-routes-autonomous.d.ts +1 -2
- package/dist/routes/cloud-status-routes-autonomous.d.ts.map +1 -1
- package/dist/routes/cloud-status-routes-autonomous.js +4 -51
- package/dist/routes/cloud-status-routes-autonomous.js.map +5 -5
- package/dist/routes/cloud-status-routes.js +14 -90
- package/dist/routes/cloud-status-routes.js.map +7 -7
- package/dist/routes/home-remote-runner-access-url.d.ts +16 -0
- package/dist/routes/home-remote-runner-access-url.d.ts.map +1 -0
- package/dist/routes/home-remote-runner-access-url.js +91 -0
- package/dist/routes/home-remote-runner-access-url.js.map +10 -0
- package/dist/routes/travel-provider-relay-routes.d.ts +9 -0
- package/dist/routes/travel-provider-relay-routes.d.ts.map +1 -0
- package/dist/routes/travel-provider-relay-routes.js +358 -0
- package/dist/routes/travel-provider-relay-routes.js.map +14 -0
- package/dist/services/cloud-auth.d.ts +1 -1
- package/dist/services/cloud-auth.d.ts.map +1 -1
- package/dist/services/cloud-auth.js +7 -2
- package/dist/services/cloud-auth.js.map +4 -4
- package/dist/services/cloud-backup.js.map +2 -2
- package/dist/services/cloud-bootstrap.d.ts.map +1 -1
- package/dist/services/cloud-bootstrap.js.map +2 -2
- package/dist/services/cloud-bridge.js.map +3 -3
- package/dist/services/cloud-container.d.ts +5 -1
- package/dist/services/cloud-container.d.ts.map +1 -1
- package/dist/services/cloud-container.js +52 -1
- package/dist/services/cloud-container.js.map +4 -4
- package/dist/services/cloud-credential-provider.js.map +2 -2
- package/dist/services/cloud-model-registry.js.map +2 -2
- package/dist/types/cloud.d.ts +1 -0
- package/dist/types/cloud.d.ts.map +1 -1
- package/dist/types/cloud.js.map +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/cloud-sdk/client.d.ts.map +1 -1
- package/dist/utils/cloud-sdk/client.js +136 -4
- package/dist/utils/cloud-sdk/client.js.map +5 -5
- package/dist/utils/cloud-sdk/http.js.map +1 -1
- package/dist/utils/cloud-sdk/public-routes.d.ts +186 -0
- package/dist/utils/cloud-sdk/public-routes.d.ts.map +1 -1
- package/dist/utils/cloud-sdk/public-routes.js +99 -1
- package/dist/utils/cloud-sdk/public-routes.js.map +3 -3
- package/dist/utils/cloud-sdk/types.d.ts +0 -2
- package/dist/utils/cloud-sdk/types.d.ts.map +1 -1
- package/dist/utils/cloud-sdk/types.js.map +1 -1
- package/dist/utils/config.d.ts +10 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -2
- package/dist/utils/config.js.map +3 -3
- package/dist/utils/events.d.ts +23 -2
- package/dist/utils/events.d.ts.map +1 -1
- package/dist/utils/events.js +5 -3
- package/dist/utils/events.js.map +3 -3
- package/dist/utils/sdk-client.d.ts.map +1 -1
- package/dist/utils/sdk-client.js +17 -4
- package/dist/utils/sdk-client.js.map +4 -4
- package/dist/utils/waifu-metering.d.ts +108 -0
- package/dist/utils/waifu-metering.d.ts.map +1 -0
- package/dist/utils/waifu-metering.js +166 -0
- package/dist/utils/waifu-metering.js.map +10 -0
- package/package.json +51 -22
- package/src/cloud/auth-service-types.ts +24 -0
- package/src/cloud/base-url.ts +6 -62
- package/src/cloud/clack-observer.ts +189 -0
- package/src/cloud/duffel-client.ts +847 -0
- package/src/cloud/index.ts +10 -0
- package/src/cloud/lifeops-schedule-sync-client.ts +245 -0
- package/src/cloud/lifeops-schedule-sync-contracts.ts +124 -0
- package/src/cloud/managed-payment-clients.ts +374 -0
- package/src/cloud/null-observer.ts +45 -0
- package/src/cloud/setup-observer.ts +125 -0
- package/src/cloud/validate-url.ts +7 -1
- package/src/cloud/x402-payment-handler.ts +215 -0
- package/src/cloud-setup.ts +531 -0
- package/src/cloud-voice-catalog.test.ts +254 -0
- package/src/cloud-voice-catalog.ts +246 -0
- package/src/index.browser.ts +29 -0
- package/src/index.node.ts +31 -1
- package/src/index.ts +76 -4
- package/src/lib/cloud-connection.ts +2 -4
- package/src/lib/cloud-secrets.ts +10 -54
- package/src/lib/config-like.ts +1 -1
- package/src/lib/credential-type-map.ts +2 -2
- package/src/lib/http.ts +0 -17
- package/src/lib/server-cloud-tts.ts +33 -341
- package/src/lib/tts-debug.ts +5 -34
- package/src/models/embeddings.ts +140 -76
- package/src/models/image.ts +29 -14
- package/src/models/research.ts +11 -1
- package/src/models/speech.ts +269 -23
- package/src/models/text.ts +704 -110
- package/src/models/tokenization.ts +2 -2
- package/src/models/transcription.ts +7 -3
- package/src/plugin.ts +38 -0
- package/src/routes/cloud-billing-routes.ts +4 -14
- package/src/routes/cloud-coding-container-routes.ts +198 -0
- package/src/routes/cloud-compat-routes.ts +4 -14
- package/src/routes/cloud-features-routes.ts +1 -1
- package/src/routes/cloud-relay-routes.ts +47 -1
- package/src/routes/cloud-routes-autonomous.ts +7 -10
- package/src/routes/cloud-routes.ts +68 -7
- package/src/routes/cloud-status-routes-autonomous.ts +6 -2
- package/src/routes/home-remote-runner-access-url.ts +83 -0
- package/src/routes/travel-provider-relay-routes.ts +193 -0
- package/src/services/cloud-auth.ts +9 -2
- package/src/services/cloud-bootstrap.ts +1 -3
- package/src/services/cloud-bridge.ts +1 -1
- package/src/services/cloud-container.ts +93 -0
- package/src/services/cloud-credential-provider.ts +1 -1
- package/src/services/cloud-model-registry.ts +1 -1
- package/src/types/cloud.ts +22 -0
- package/src/types/index.ts +19 -0
- package/src/utils/cloud-sdk/client.ts +42 -3
- package/src/utils/cloud-sdk/public-routes.ts +168 -0
- package/src/utils/cloud-sdk/types.ts +0 -2
- package/src/utils/config.ts +20 -1
- package/src/utils/events.ts +30 -2
- package/src/utils/sdk-client.ts +5 -1
- package/src/utils/waifu-metering.ts +302 -0
- package/dist/onboarding.d.ts +0 -35
- package/dist/onboarding.d.ts.map +0 -1
- package/dist/onboarding.js.map +0 -14
- package/src/onboarding.ts +0 -396
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 (HTTP 402 Payment Required) handler for Eliza Cloud relays.
|
|
3
|
+
*
|
|
4
|
+
* Spec reference: https://www.x402.org
|
|
5
|
+
*
|
|
6
|
+
* When the user's Cloud credit balance can't cover a metered call, the
|
|
7
|
+
* Cloud relay returns HTTP 402 with a `payment-requirements` envelope —
|
|
8
|
+
* either as a `WWW-Authenticate: x402 <json>` header or as a JSON body
|
|
9
|
+
* with a top-level `paymentRequirements` array. Each requirement
|
|
10
|
+
* describes one acceptable payment option (asset, network, recipient,
|
|
11
|
+
* amount).
|
|
12
|
+
*
|
|
13
|
+
* This module is intentionally thin:
|
|
14
|
+
* - `parseX402Response` extracts requirements from a Response.
|
|
15
|
+
* - `PaymentRequiredError` carries them up to the action layer.
|
|
16
|
+
* - `requestPayment` is the agent-side bridge: today it surfaces the
|
|
17
|
+
* requirement back to the owner via the runtime logger so the UI /
|
|
18
|
+
* planner can route the user to the existing wallet top-up flow.
|
|
19
|
+
* Auto-pay intentionally lives outside this bridge — the actual money
|
|
20
|
+
* movement is Cloud-side and gated by the wallet UI (commandment 4).
|
|
21
|
+
*
|
|
22
|
+
* No silent failures: a malformed 402 throws so the action layer can
|
|
23
|
+
* surface a clear "payment-required" message rather than treating the
|
|
24
|
+
* upstream as a generic HTTP error.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { type IAgentRuntime, logger } from "@elizaos/core";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* One acceptable payment option as advertised by the server.
|
|
31
|
+
*
|
|
32
|
+
* Fields mirror the x402 spec's `paymentRequirements` entry. We type
|
|
33
|
+
* everything as required so silent partial parses are impossible — the
|
|
34
|
+
* parser either yields a complete requirement or rejects it.
|
|
35
|
+
*/
|
|
36
|
+
export interface X402PaymentRequirement {
|
|
37
|
+
/** Decimal amount in the asset's smallest unit (e.g. "1500000" for
|
|
38
|
+
* 1.50 USDC). String, not number, to preserve precision. */
|
|
39
|
+
readonly amount: string;
|
|
40
|
+
/** Asset symbol or ERC-20 contract address (e.g. "USDC"). */
|
|
41
|
+
readonly asset: string;
|
|
42
|
+
/** Network identifier (e.g. "base", "ethereum", "solana"). */
|
|
43
|
+
readonly network: string;
|
|
44
|
+
/** Recipient address that should receive the payment. */
|
|
45
|
+
readonly payTo: string;
|
|
46
|
+
/** Payment scheme — currently x402 supports "exact" only. */
|
|
47
|
+
readonly scheme: string;
|
|
48
|
+
/** ISO-8601 deadline after which the requirement is no longer valid. */
|
|
49
|
+
readonly expiresAt: string | null;
|
|
50
|
+
/** Human-readable description of the resource being purchased. */
|
|
51
|
+
readonly description: string | null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Wire shape we accept from JSON bodies. Loose at the boundary, strict
|
|
56
|
+
* after parsing.
|
|
57
|
+
*/
|
|
58
|
+
interface RawRequirement {
|
|
59
|
+
readonly amount?: unknown;
|
|
60
|
+
readonly asset?: unknown;
|
|
61
|
+
readonly network?: unknown;
|
|
62
|
+
readonly payTo?: unknown;
|
|
63
|
+
readonly scheme?: unknown;
|
|
64
|
+
readonly expiresAt?: unknown;
|
|
65
|
+
readonly description?: unknown;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface RawX402Body {
|
|
69
|
+
readonly paymentRequirements?: ReadonlyArray<RawRequirement>;
|
|
70
|
+
readonly accepts?: ReadonlyArray<RawRequirement>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function readString(value: unknown): string | null {
|
|
74
|
+
if (typeof value !== "string") return null;
|
|
75
|
+
const trimmed = value.trim();
|
|
76
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function readAmount(value: unknown): string | null {
|
|
80
|
+
if (typeof value === "string") {
|
|
81
|
+
const trimmed = value.trim();
|
|
82
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
83
|
+
}
|
|
84
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
85
|
+
return String(value);
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function normalizeRequirement(
|
|
91
|
+
raw: RawRequirement | null | undefined,
|
|
92
|
+
): X402PaymentRequirement | null {
|
|
93
|
+
if (!raw || typeof raw !== "object") return null;
|
|
94
|
+
const amount = readAmount(raw.amount);
|
|
95
|
+
const asset = readString(raw.asset);
|
|
96
|
+
const network = readString(raw.network);
|
|
97
|
+
const payTo = readString(raw.payTo);
|
|
98
|
+
if (!amount || !asset || !network || !payTo) return null;
|
|
99
|
+
const scheme = readString(raw.scheme) ?? "exact";
|
|
100
|
+
return {
|
|
101
|
+
amount,
|
|
102
|
+
asset,
|
|
103
|
+
network,
|
|
104
|
+
payTo,
|
|
105
|
+
scheme,
|
|
106
|
+
expiresAt: readString(raw.expiresAt),
|
|
107
|
+
description: readString(raw.description),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parseRequirementsArray(
|
|
112
|
+
raw: ReadonlyArray<RawRequirement> | undefined,
|
|
113
|
+
): X402PaymentRequirement[] {
|
|
114
|
+
if (!Array.isArray(raw)) return [];
|
|
115
|
+
const out: X402PaymentRequirement[] = [];
|
|
116
|
+
for (const entry of raw) {
|
|
117
|
+
const normalized = normalizeRequirement(entry);
|
|
118
|
+
if (normalized) out.push(normalized);
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Pull payment requirements out of an x402 response. Tries the header
|
|
125
|
+
* form first (lowest-overhead per spec), then falls back to the JSON
|
|
126
|
+
* body. Returns `null` when the response carries no parseable
|
|
127
|
+
* requirements — callers should treat that as a generic 402 and
|
|
128
|
+
* surface the upstream status text.
|
|
129
|
+
*/
|
|
130
|
+
export async function parseX402Response(
|
|
131
|
+
response: Response,
|
|
132
|
+
): Promise<X402PaymentRequirement[] | null> {
|
|
133
|
+
const headerValue = response.headers.get("www-authenticate");
|
|
134
|
+
if (headerValue?.toLowerCase().startsWith("x402")) {
|
|
135
|
+
const jsonPart = headerValue.slice(4).trim();
|
|
136
|
+
if (jsonPart.length > 0) {
|
|
137
|
+
const parsed = JSON.parse(jsonPart) as RawX402Body | RawRequirement[];
|
|
138
|
+
const requirements = Array.isArray(parsed)
|
|
139
|
+
? parseRequirementsArray(parsed)
|
|
140
|
+
: parseRequirementsArray(parsed.paymentRequirements ?? parsed.accepts);
|
|
141
|
+
if (requirements.length > 0) return requirements;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Fall back to body parse. Clone so the caller can still read it.
|
|
145
|
+
const cloned = response.clone();
|
|
146
|
+
const text = await cloned.text();
|
|
147
|
+
if (text.length === 0) return null;
|
|
148
|
+
const body = JSON.parse(text) as RawX402Body;
|
|
149
|
+
const requirements = parseRequirementsArray(
|
|
150
|
+
body.paymentRequirements ?? body.accepts,
|
|
151
|
+
);
|
|
152
|
+
return requirements.length > 0 ? requirements : null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Thrown by adapters when an upstream metered call returns 402 with
|
|
157
|
+
* actionable payment requirements. Action handlers convert this into an
|
|
158
|
+
* approval-queue entry so the user sees both the cost and the
|
|
159
|
+
* top-up prompt together.
|
|
160
|
+
*/
|
|
161
|
+
export class PaymentRequiredError extends Error {
|
|
162
|
+
readonly code = "PAYMENT_REQUIRED" as const;
|
|
163
|
+
readonly requirements: ReadonlyArray<X402PaymentRequirement>;
|
|
164
|
+
|
|
165
|
+
constructor(
|
|
166
|
+
requirements: ReadonlyArray<X402PaymentRequirement>,
|
|
167
|
+
message?: string,
|
|
168
|
+
) {
|
|
169
|
+
const text =
|
|
170
|
+
message ??
|
|
171
|
+
`Eliza Cloud returned HTTP 402 — your credit balance can't cover this call. ${requirements.length} payment option(s) available.`;
|
|
172
|
+
super(text);
|
|
173
|
+
this.name = "PaymentRequiredError";
|
|
174
|
+
this.requirements = requirements;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface PaymentReceipt {
|
|
179
|
+
readonly status: "surfaced" | "paid";
|
|
180
|
+
readonly requirement: X402PaymentRequirement;
|
|
181
|
+
/** Transaction id when status === "paid", null when only surfaced. */
|
|
182
|
+
readonly txId: string | null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Bridge from a raw payment requirement to user action. For now this
|
|
187
|
+
* does not auto-pay: the actual money movement happens in the existing
|
|
188
|
+
* wallet UI (Cloud-side). We log the requirement so the agent's
|
|
189
|
+
* messaging surface and the desktop dev console both pick it up, then
|
|
190
|
+
* return a "surfaced" receipt for the action layer to forward into the
|
|
191
|
+
* approval queue.
|
|
192
|
+
*/
|
|
193
|
+
export async function requestPayment(
|
|
194
|
+
runtime: IAgentRuntime,
|
|
195
|
+
requirements: ReadonlyArray<X402PaymentRequirement>,
|
|
196
|
+
): Promise<PaymentReceipt> {
|
|
197
|
+
if (requirements.length === 0) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
"[x402] requestPayment called with no requirements — adapter bug",
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
const preferred = requirements[0];
|
|
203
|
+
logger.warn(
|
|
204
|
+
{
|
|
205
|
+
boundary: "elizacloud",
|
|
206
|
+
integration: "x402",
|
|
207
|
+
asset: preferred.asset,
|
|
208
|
+
network: preferred.network,
|
|
209
|
+
amount: preferred.amount,
|
|
210
|
+
runtimeId: runtime.agentId,
|
|
211
|
+
},
|
|
212
|
+
`[x402] payment-required: ${preferred.amount} ${preferred.asset} on ${preferred.network} → ${preferred.payTo}${preferred.description ? ` (${preferred.description})` : ""}`,
|
|
213
|
+
);
|
|
214
|
+
return { status: "surfaced", requirement: preferred, txId: null };
|
|
215
|
+
}
|