@algovoi/plugin-elizaos 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AlgoVoi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # @algovoi/plugin-elizaos
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4
+ [![ElizaOS Plugin](https://img.shields.io/badge/elizaos--plugins-1.0%2B-7c3aed)](https://github.com/elizaos-plugins/registry)
5
+ [![Agent Trust Bench](https://img.shields.io/badge/Agent_Trust_Bench-100%25_71%2F71-238636)](https://agent-trust-bench.algovoi.co.uk)
6
+
7
+ > Multi-chain agent-to-agent (A2A) crypto payments for [ElizaOS](https://elizaos.ai) agents.
8
+
9
+ ![AlgoVoi banner](images/banner.jpg)
10
+
11
+ Lets your Eliza agent **ask for, verify, and poll fiat-denominated crypto payments** that settle as stablecoins or native assets across **7 chains** — without holding any crypto, keys, or fiat.
12
+
13
+ | What | How |
14
+ |---|---|
15
+ | **Ask for a payment** | Agent generates a hosted checkout URL the payer opens in any browser |
16
+ | **Verify a payment** | Agent confirms an on-chain tx satisfies the expected amount, receiver, and binding |
17
+ | **Poll a checkout** | Agent checks whether a previously-issued token has been paid |
18
+
19
+ Settlement is direct on-chain customer-wallet → merchant-wallet via [AlgoVoi](https://algovoi.co.uk), the only live A2A-compliant crypto payment gateway as of 2026-04-26.
20
+
21
+ ## Why this plugin
22
+
23
+ - **Non-custodial.** AlgoVoi never holds funds. Your agent doesn't need a wallet, a private key, or any fiat custody — only an API key.
24
+ - **7 chains, one interface.** Algorand, VOI, Hedera, Stellar, Base, Solana, Tempo — agent says "GBP", AlgoVoi handles the chain selection.
25
+ - **4 payment protocols.** x402 (HTTP 402 micropayments), MPP (IETF), AP2 (Google Agentic Payments), and Google A2A v0.3.
26
+ - **Stablecoin-first.** USDC across Algorand, VOI, Hedera, Stellar, Base, Solana, Tempo. Native asset support where the chain has it.
27
+ - **No new SDK deps.** Plugin is a thin HTTP wrapper around the public A2A endpoint at `https://api.algovoi.co.uk/.well-known/agent.json`.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ pnpm add @algovoi/plugin-elizaos
33
+ # or
34
+ npm install @algovoi/plugin-elizaos
35
+ # or
36
+ yarn add @algovoi/plugin-elizaos
37
+ ```
38
+
39
+ ## Get an API key
40
+
41
+ Free tier (testnet) at [dash.algovoi.co.uk/signup](https://dash.algovoi.co.uk/signup).
42
+ Mainnet activation requires KYC; the free trial covers your first $1,000 of mainnet payment volume across all chains.
43
+
44
+ ## Configure
45
+
46
+ Set environment variables (or pass via the runtime's settings):
47
+
48
+ ```env
49
+ ALGOVOI_API_KEY=algvk_live_... # required — from dash.algovoi.co.uk
50
+ ALGOVOI_API_BASE=https://api.algovoi.co.uk # optional, this is the default
51
+ ALGOVOI_DEFAULT_NETWORK=algorand_mainnet # optional, default
52
+ ALGOVOI_DEFAULT_CURRENCY=GBP # optional, default
53
+ ```
54
+
55
+ ## Use it in an Eliza character
56
+
57
+ ```ts
58
+ import { algovoiPlugin } from "@algovoi/plugin-elizaos";
59
+
60
+ const character = {
61
+ name: "PayAgent",
62
+ bio: "I'm an AI assistant that can collect and verify crypto payments.",
63
+ plugins: [algovoiPlugin],
64
+ // ... rest of your character config
65
+ };
66
+ ```
67
+
68
+ A complete character JSON is in [`examples/payments-character.json`](examples/payments-character.json).
69
+
70
+ ## Actions
71
+
72
+ The plugin registers three actions on the Eliza runtime:
73
+
74
+ ### `CREATE_PAYMENT_REQUEST`
75
+
76
+ Create a hosted checkout link for a fiat amount.
77
+
78
+ **Triggers:** "create a payment request for £9.99", "invoice 50 USD", "ask for $20 on solana".
79
+
80
+ **Returns:** `{ token, checkout_url, status, expires_at, chain, amount_microunits }`.
81
+
82
+ ### `VERIFY_PAYMENT`
83
+
84
+ Verify an on-chain transaction satisfies a payment.
85
+
86
+ **Triggers:** "verify tx ABC123 on algorand_mainnet for token uW9MJN-abc123", "did the user pay for resource X".
87
+
88
+ **Returns:** `{ verified: true|false, access_token, error? }`. The `access_token` is a JWT your agent can use to gate downstream calls.
89
+
90
+ ### `CHECK_PAYMENT_STATUS`
91
+
92
+ Poll a previously-issued checkout token.
93
+
94
+ **Triggers:** "is checkout X paid?", "check status of token Y".
95
+
96
+ **Returns:** `{ token, status: "active" | "paid" | "expired" | "cancelled", redirect_url }`.
97
+
98
+ ## End-to-end example
99
+
100
+ ```ts
101
+ import { algovoiPlugin, AlgoVoiClient } from "@algovoi/plugin-elizaos";
102
+
103
+ // Or use the underlying client directly:
104
+ const client = new AlgoVoiClient({
105
+ ALGOVOI_API_KEY: process.env.ALGOVOI_API_KEY!,
106
+ ALGOVOI_API_BASE: "https://api.algovoi.co.uk",
107
+ ALGOVOI_DEFAULT_NETWORK: "algorand_mainnet",
108
+ ALGOVOI_DEFAULT_CURRENCY: "GBP",
109
+ });
110
+
111
+ // 1. Create a checkout
112
+ const checkout = await client.createCheckout({
113
+ amount: 9.99,
114
+ currency: "GBP",
115
+ label: "Premium content access",
116
+ preferred_network: "algorand_mainnet",
117
+ redirect_url: "https://your-app.example.com/thanks",
118
+ });
119
+
120
+ console.log(`Pay here: ${checkout.checkout_url}`);
121
+ console.log(`Token to poll: ${checkout.token}`);
122
+
123
+ // 2. Poll until paid
124
+ let status = checkout.status;
125
+ while (status === "active") {
126
+ await new Promise((r) => setTimeout(r, 10_000));
127
+ const result = await client.checkStatus({ token: checkout.token });
128
+ status = result.status;
129
+ }
130
+
131
+ // 3. Or — verify a known tx_id directly
132
+ const verified = await client.verifyPayment({
133
+ network: "algorand_mainnet",
134
+ tx_id: "7K9X...PQR",
135
+ token: checkout.token,
136
+ });
137
+ if (verified.verified) {
138
+ console.log(`Access granted. JWT: ${verified.access_token}`);
139
+ }
140
+ ```
141
+
142
+ ## Supported networks
143
+
144
+ | Chain | Mainnet | Testnet | Stablecoin | Native |
145
+ |---|---|---|---|---|
146
+ | Algorand | ✅ | ✅ | USDC | ALGO |
147
+ | VOI | ✅ | ✅ | — | VOI |
148
+ | Hedera | ✅ | ✅ | USDC | HBAR |
149
+ | Stellar | ✅ | ✅ | USDC | XLM |
150
+ | Base | ✅ | ✅ (Sepolia) | USDC | ETH |
151
+ | Solana | ✅ | ✅ (Devnet) | USDC | SOL |
152
+ | Tempo | ✅ | ✅ | USDC | — |
153
+
154
+ ## Discovery
155
+
156
+ The plugin connects to a Google A2A v0.3 agent. You can inspect AlgoVoi's full agent card at:
157
+
158
+ ```bash
159
+ curl https://api.algovoi.co.uk/.well-known/agent.json
160
+ ```
161
+
162
+ ## Security
163
+
164
+ - AlgoVoi is non-custodial — funds settle direct customer→merchant on a public blockchain
165
+ - Your tenant API key is the only secret; rotate it via the dashboard
166
+ - Compliance binder, security disclosure, and full policy library at [algovoi.co.uk/AlgoVoi/compliance.html](https://algovoi.co.uk/AlgoVoi/compliance.html)
167
+ - Vulnerability disclosure: [security@algovoi.co.uk](mailto:security@algovoi.co.uk) / [/.well-known/security.txt](https://algovoi.co.uk/.well-known/security.txt)
168
+
169
+ ## Contributing
170
+
171
+ PRs welcome. Open an issue first for substantial changes. The plugin's contract is intentionally narrow — it wraps the A2A endpoint and nothing more — so most enhancements belong in the upstream gateway, not here.
172
+
173
+ ## License
174
+
175
+ MIT — see [LICENSE](LICENSE).
176
+
177
+ ## Links
178
+
179
+ - AlgoVoi platform: [algovoi.co.uk](https://algovoi.co.uk)
180
+ - Docs: [docs.algovoi.co.uk](https://docs.algovoi.co.uk)
181
+ - A2A integration: [docs.algovoi.co.uk/protocols/a2a](https://docs.algovoi.co.uk/protocols/a2a)
182
+ - ElizaOS: [elizaos.ai](https://elizaos.ai)
183
+ - Plugin registry: [github.com/elizaos-plugins/registry](https://github.com/elizaos-plugins/registry)
@@ -0,0 +1,144 @@
1
+ import { IAgentRuntime, Plugin } from '@elizaos/core';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Environment configuration for the AlgoVoi ElizaOS plugin.
6
+ *
7
+ * The plugin authenticates against the AlgoVoi A2A endpoint using a
8
+ * tenant API key. Tenants are issued at https://dash.algovoi.co.uk/signup
9
+ * (free tier; testnet by default).
10
+ */
11
+
12
+ declare const algovoiEnvSchema: z.ZodObject<{
13
+ ALGOVOI_API_KEY: z.ZodString;
14
+ ALGOVOI_API_BASE: z.ZodDefault<z.ZodString>;
15
+ ALGOVOI_DEFAULT_NETWORK: z.ZodDefault<z.ZodString>;
16
+ ALGOVOI_DEFAULT_CURRENCY: z.ZodDefault<z.ZodString>;
17
+ }, "strip", z.ZodTypeAny, {
18
+ ALGOVOI_API_KEY: string;
19
+ ALGOVOI_API_BASE: string;
20
+ ALGOVOI_DEFAULT_NETWORK: string;
21
+ ALGOVOI_DEFAULT_CURRENCY: string;
22
+ }, {
23
+ ALGOVOI_API_KEY: string;
24
+ ALGOVOI_API_BASE?: string | undefined;
25
+ ALGOVOI_DEFAULT_NETWORK?: string | undefined;
26
+ ALGOVOI_DEFAULT_CURRENCY?: string | undefined;
27
+ }>;
28
+ type AlgoVoiConfig = z.infer<typeof algovoiEnvSchema>;
29
+ /**
30
+ * Resolve config from the runtime's settings (preferred) with fallback to
31
+ * `process.env`. Throws a clear message if required values are missing.
32
+ */
33
+ declare function resolveAlgoVoiConfig(runtime: IAgentRuntime): AlgoVoiConfig;
34
+ /**
35
+ * The 7 mainnet networks AlgoVoi currently supports. Used for validation
36
+ * and for the agent's available_networks introspection.
37
+ */
38
+ declare const SUPPORTED_NETWORKS: readonly ["algorand_mainnet", "voi_mainnet", "hedera_mainnet", "stellar_mainnet", "base_mainnet", "solana_mainnet", "tempo_mainnet", "algorand_testnet", "voi_testnet", "hedera_testnet", "stellar_testnet", "base_sepolia", "solana_devnet", "tempo_testnet"];
39
+ type SupportedNetwork = (typeof SUPPORTED_NETWORKS)[number];
40
+
41
+ /**
42
+ * Type definitions for AlgoVoi A2A skills.
43
+ *
44
+ * Mirrors the request/response contracts at
45
+ * `https://api.algovoi.co.uk/.well-known/agent.json`.
46
+ */
47
+
48
+ type CreateCheckoutInput = {
49
+ /** Amount in major fiat units, e.g. 9.99 for £9.99. Required. */
50
+ amount: number;
51
+ /** ISO 4217 code, e.g. "GBP", "USD", "EUR". Defaults to plugin default. */
52
+ currency?: string;
53
+ /** Item or order description shown to the payer. */
54
+ label?: string;
55
+ /** Force a specific network (e.g. "algorand_mainnet"). */
56
+ preferred_network?: SupportedNetwork | string;
57
+ /** URL to redirect the buyer to after successful payment. */
58
+ redirect_url?: string;
59
+ /** Link TTL in seconds. Default 86400 (24h). */
60
+ expires_in_seconds?: number;
61
+ };
62
+ type CreateCheckoutResult = {
63
+ token: string;
64
+ checkout_url: string;
65
+ status: "active" | "paid" | "expired" | "cancelled";
66
+ expires_at?: string | null;
67
+ amount_microunits?: number;
68
+ chain?: string;
69
+ error?: string;
70
+ };
71
+ type VerifyPaymentInput = {
72
+ /** Required. Network the tx was submitted to. */
73
+ network: SupportedNetwork | string;
74
+ /** Required. On-chain transaction id / hash / signature. */
75
+ tx_id: string;
76
+ /** Optional. Resource id when verifying resource-gated access. */
77
+ resource_id?: string;
78
+ /** Optional. Checkout token when verifying a hosted checkout payment. */
79
+ token?: string;
80
+ /** Optional protocol hint: "x402" | "mpp" | "ap2". */
81
+ protocol?: "x402" | "mpp" | "ap2";
82
+ };
83
+ type VerifyPaymentResult = {
84
+ verified: boolean;
85
+ tx_id?: string;
86
+ /** JWT issued on successful verification — present when verified=true. */
87
+ access_token?: string;
88
+ error?: string;
89
+ };
90
+ type CheckStatusInput = {
91
+ /** Required. The token returned by create-checkout. */
92
+ token: string;
93
+ };
94
+ type CheckStatusResult = {
95
+ token: string;
96
+ status: "active" | "paid" | "expired" | "cancelled";
97
+ redirect_url?: string | null;
98
+ error?: string;
99
+ };
100
+
101
+ /**
102
+ * AlgoVoi A2A client.
103
+ *
104
+ * Thin wrapper around the Google A2A v0.3 endpoints exposed by the
105
+ * AlgoVoi payment gateway at `<api_base>/message:send`.
106
+ *
107
+ * Authenticates with `Authorization: Bearer <api_key>` per the agent
108
+ * card's `securitySchemes.apiKey` definition.
109
+ */
110
+
111
+ declare class AlgoVoiClient {
112
+ private readonly config;
113
+ constructor(config: AlgoVoiConfig);
114
+ /**
115
+ * Send an A2A `message:send` request, asserting the response task
116
+ * completed successfully and returning the result data part.
117
+ */
118
+ private sendSkill;
119
+ createCheckout(input: CreateCheckoutInput): Promise<CreateCheckoutResult>;
120
+ verifyPayment(input: VerifyPaymentInput): Promise<VerifyPaymentResult>;
121
+ checkStatus(input: CheckStatusInput): Promise<CheckStatusResult>;
122
+ /**
123
+ * Fetch the public agent card (no auth required). Useful for
124
+ * introspecting the deployed AlgoVoi instance's capabilities.
125
+ */
126
+ fetchAgentCard(): Promise<unknown>;
127
+ }
128
+
129
+ /**
130
+ * @algovoi/plugin-elizaos
131
+ *
132
+ * Multi-chain agent-to-agent (A2A) crypto payments for ElizaOS agents.
133
+ * Lets an Eliza agent ask for, verify, and poll fiat-denominated
134
+ * payments that settle as stablecoins or native assets on Algorand,
135
+ * VOI, Hedera, Stellar, Base, Solana, or Tempo — without holding any
136
+ * crypto, keys, or fiat itself.
137
+ *
138
+ * Wraps the AlgoVoi Google A2A v0.3 endpoint at
139
+ * https://api.algovoi.co.uk/.well-known/agent.json
140
+ */
141
+
142
+ declare const algovoiPlugin: Plugin;
143
+
144
+ export { AlgoVoiClient, type AlgoVoiConfig, type CheckStatusInput, type CheckStatusResult, type CreateCheckoutInput, type CreateCheckoutResult, SUPPORTED_NETWORKS, type SupportedNetwork, type VerifyPaymentInput, type VerifyPaymentResult, algovoiPlugin, algovoiPlugin as default, resolveAlgoVoiConfig };
package/dist/index.js ADDED
@@ -0,0 +1,589 @@
1
+ // src/actions/createPaymentRequest.ts
2
+ import { z as z2 } from "zod";
3
+
4
+ // src/client.ts
5
+ var AlgoVoiClient = class {
6
+ constructor(config) {
7
+ this.config = config;
8
+ }
9
+ config;
10
+ /**
11
+ * Send an A2A `message:send` request, asserting the response task
12
+ * completed successfully and returning the result data part.
13
+ */
14
+ async sendSkill(skill, data) {
15
+ const url = `${this.config.ALGOVOI_API_BASE}/message:send`;
16
+ const messageId = crypto.randomUUID();
17
+ const body = {
18
+ message: {
19
+ messageId,
20
+ role: "user",
21
+ parts: [
22
+ {
23
+ kind: "data",
24
+ data: { skill, ...data }
25
+ }
26
+ ]
27
+ }
28
+ };
29
+ let resp;
30
+ try {
31
+ resp = await fetch(url, {
32
+ method: "POST",
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ Accept: "application/json",
36
+ Authorization: `Bearer ${this.config.ALGOVOI_API_KEY}`,
37
+ "User-Agent": "@algovoi/plugin-elizaos"
38
+ },
39
+ body: JSON.stringify(body)
40
+ });
41
+ } catch (err) {
42
+ throw new Error(`AlgoVoi network error: ${err.message}`);
43
+ }
44
+ if (!resp.ok) {
45
+ const text = await resp.text().catch(() => "");
46
+ throw new Error(
47
+ `AlgoVoi API ${resp.status}: ${text || resp.statusText}`
48
+ );
49
+ }
50
+ const payload = await resp.json();
51
+ const task = payload.task;
52
+ if (!task) {
53
+ throw new Error("AlgoVoi response missing 'task' field");
54
+ }
55
+ const state = task.status?.state;
56
+ if (state === "failed") {
57
+ const messageParts = task.status?.message?.parts ?? [];
58
+ const textPart = messageParts.find(
59
+ (p) => p.kind === "text"
60
+ );
61
+ const errorText = textPart?.text ?? "task failed without error detail";
62
+ throw new Error(`AlgoVoi skill '${skill}' failed: ${errorText}`);
63
+ }
64
+ if (state !== "completed") {
65
+ throw new Error(`AlgoVoi skill '${skill}' returned unexpected state '${state}'`);
66
+ }
67
+ const artifactParts = task.artifacts?.[0]?.parts ?? [];
68
+ const dataPart = artifactParts.find(
69
+ (p) => p.kind === "data"
70
+ );
71
+ if (!dataPart || !dataPart.data) {
72
+ throw new Error(`AlgoVoi skill '${skill}' completed with no data part`);
73
+ }
74
+ return dataPart.data;
75
+ }
76
+ createCheckout(input) {
77
+ return this.sendSkill("create-checkout", {
78
+ amount: input.amount,
79
+ currency: input.currency ?? this.config.ALGOVOI_DEFAULT_CURRENCY,
80
+ label: input.label ?? "Payment",
81
+ preferred_network: input.preferred_network ?? this.config.ALGOVOI_DEFAULT_NETWORK,
82
+ redirect_url: input.redirect_url,
83
+ expires_in_seconds: input.expires_in_seconds
84
+ });
85
+ }
86
+ verifyPayment(input) {
87
+ const data = {
88
+ network: input.network,
89
+ tx_id: input.tx_id
90
+ };
91
+ if (input.resource_id) data.resource_id = input.resource_id;
92
+ if (input.token) data.token = input.token;
93
+ if (input.protocol) data.protocol = input.protocol;
94
+ return this.sendSkill("verify-payment", data);
95
+ }
96
+ checkStatus(input) {
97
+ return this.sendSkill("check-status", {
98
+ token: input.token
99
+ });
100
+ }
101
+ /**
102
+ * Fetch the public agent card (no auth required). Useful for
103
+ * introspecting the deployed AlgoVoi instance's capabilities.
104
+ */
105
+ async fetchAgentCard() {
106
+ const url = `${this.config.ALGOVOI_API_BASE}/.well-known/agent.json`;
107
+ const resp = await fetch(url, {
108
+ headers: { Accept: "application/json" }
109
+ });
110
+ if (!resp.ok) {
111
+ throw new Error(`Agent card fetch failed: ${resp.status}`);
112
+ }
113
+ return resp.json();
114
+ }
115
+ };
116
+
117
+ // src/environment.ts
118
+ import { z } from "zod";
119
+ var algovoiEnvSchema = z.object({
120
+ ALGOVOI_API_KEY: z.string({ required_error: "ALGOVOI_API_KEY is required" }).min(8, "ALGOVOI_API_KEY looks too short"),
121
+ ALGOVOI_API_BASE: z.string().url().default("https://api.algovoi.co.uk"),
122
+ ALGOVOI_DEFAULT_NETWORK: z.string().default("algorand_mainnet"),
123
+ ALGOVOI_DEFAULT_CURRENCY: z.string().length(3).default("GBP")
124
+ });
125
+ function resolveAlgoVoiConfig(runtime) {
126
+ const fromRuntime = (key) => {
127
+ try {
128
+ const v = runtime.getSetting(key);
129
+ return typeof v === "string" && v.length > 0 ? v : void 0;
130
+ } catch {
131
+ return void 0;
132
+ }
133
+ };
134
+ const env = (key) => {
135
+ if (typeof process === "undefined" || !process.env) return void 0;
136
+ const v = process.env[key];
137
+ return typeof v === "string" && v.length > 0 ? v : void 0;
138
+ };
139
+ const merged = {
140
+ ALGOVOI_API_KEY: fromRuntime("ALGOVOI_API_KEY") ?? env("ALGOVOI_API_KEY"),
141
+ ALGOVOI_API_BASE: fromRuntime("ALGOVOI_API_BASE") ?? env("ALGOVOI_API_BASE"),
142
+ ALGOVOI_DEFAULT_NETWORK: fromRuntime("ALGOVOI_DEFAULT_NETWORK") ?? env("ALGOVOI_DEFAULT_NETWORK"),
143
+ ALGOVOI_DEFAULT_CURRENCY: fromRuntime("ALGOVOI_DEFAULT_CURRENCY") ?? env("ALGOVOI_DEFAULT_CURRENCY")
144
+ };
145
+ const cleaned = Object.fromEntries(
146
+ Object.entries(merged).filter(([, v]) => v !== void 0)
147
+ );
148
+ return algovoiEnvSchema.parse(cleaned);
149
+ }
150
+ var SUPPORTED_NETWORKS = [
151
+ "algorand_mainnet",
152
+ "voi_mainnet",
153
+ "hedera_mainnet",
154
+ "stellar_mainnet",
155
+ "base_mainnet",
156
+ "solana_mainnet",
157
+ "tempo_mainnet",
158
+ // Testnets — useful for development
159
+ "algorand_testnet",
160
+ "voi_testnet",
161
+ "hedera_testnet",
162
+ "stellar_testnet",
163
+ "base_sepolia",
164
+ "solana_devnet",
165
+ "tempo_testnet"
166
+ ];
167
+
168
+ // src/actions/createPaymentRequest.ts
169
+ var inputSchema = z2.object({
170
+ amount: z2.number().positive(),
171
+ currency: z2.string().length(3).optional(),
172
+ label: z2.string().max(120).optional(),
173
+ preferred_network: z2.string().optional(),
174
+ redirect_url: z2.string().url().optional(),
175
+ expires_in_seconds: z2.number().int().positive().optional()
176
+ });
177
+ function parseFromText(text) {
178
+ if (!text) return null;
179
+ const symbolMap = { "\xA3": "GBP", "$": "USD", "\u20AC": "EUR" };
180
+ const symbolMatch = text.match(/([£$€])\s*(\d+(?:\.\d{1,2})?)/);
181
+ const isoMatch = text.match(/(\d+(?:\.\d{1,2})?)\s*(GBP|USD|EUR|JPY|AUD|CAD|CHF|NZD)\b/i);
182
+ let amount;
183
+ let currency;
184
+ if (symbolMatch) {
185
+ amount = parseFloat(symbolMatch[2]);
186
+ currency = symbolMap[symbolMatch[1]];
187
+ } else if (isoMatch) {
188
+ amount = parseFloat(isoMatch[1]);
189
+ currency = isoMatch[2].toUpperCase();
190
+ }
191
+ if (amount === void 0 || !Number.isFinite(amount)) return null;
192
+ const networkMatch = text.match(
193
+ /\b(algorand|voi|hedera|stellar|base|solana|tempo)(_(?:main|test)net)?\b/i
194
+ );
195
+ const preferred_network = networkMatch ? `${networkMatch[1].toLowerCase()}${networkMatch[2] ?? "_mainnet"}` : void 0;
196
+ return inputSchema.parse({ amount, currency, preferred_network });
197
+ }
198
+ var createPaymentRequestAction = {
199
+ name: "CREATE_PAYMENT_REQUEST",
200
+ similes: [
201
+ "CREATE_CHECKOUT",
202
+ "REQUEST_PAYMENT",
203
+ "GENERATE_PAYMENT_LINK",
204
+ "INVOICE",
205
+ "BILL",
206
+ "ASK_FOR_PAYMENT"
207
+ ],
208
+ description: "Create a hosted AlgoVoi checkout link for a fiat amount. Returns a URL the payer can open in any browser, plus a token the agent can poll for payment status. Settles on Algorand, VOI, Hedera, Stellar, Base, Solana, or Tempo via stablecoin or native asset.",
209
+ validate: async (runtime, _message) => {
210
+ try {
211
+ resolveAlgoVoiConfig(runtime);
212
+ return true;
213
+ } catch {
214
+ return false;
215
+ }
216
+ },
217
+ handler: async (runtime, message, _state, options, callback) => {
218
+ const config = resolveAlgoVoiConfig(runtime);
219
+ const client = new AlgoVoiClient(config);
220
+ let parsed = null;
221
+ if (options && Object.keys(options).length > 0) {
222
+ const result = inputSchema.safeParse(options);
223
+ if (result.success) parsed = result.data;
224
+ }
225
+ if (!parsed) {
226
+ const text = message.content?.text ?? "";
227
+ parsed = parseFromText(text);
228
+ }
229
+ if (!parsed || !parsed.amount) {
230
+ const errText = `I need an amount and currency to create a payment request. Try: 'create a payment request for \xA39.99' or pass { "amount": 9.99, "currency": "GBP" } as options.`;
231
+ callback?.({ text: errText });
232
+ return false;
233
+ }
234
+ try {
235
+ const result = await client.createCheckout(parsed);
236
+ const symbol = parsed.currency === "GBP" ? "\xA3" : parsed.currency === "USD" ? "$" : parsed.currency === "EUR" ? "\u20AC" : `${parsed.currency ?? config.ALGOVOI_DEFAULT_CURRENCY} `;
237
+ const replyText = `Payment request created: ${symbol}${parsed.amount.toFixed(2)}
238
+ Pay here: ${result.checkout_url}
239
+ Token (for polling): ${result.token}` + (result.expires_at ? `
240
+ Expires at: ${result.expires_at}` : "");
241
+ callback?.({
242
+ text: replyText,
243
+ action: "CREATE_PAYMENT_REQUEST",
244
+ // @ts-expect-error — eliza Memory.content allows arbitrary keys for tool output
245
+ metadata: {
246
+ token: result.token,
247
+ checkout_url: result.checkout_url,
248
+ status: result.status,
249
+ chain: result.chain,
250
+ amount_microunits: result.amount_microunits
251
+ }
252
+ });
253
+ return true;
254
+ } catch (err) {
255
+ callback?.({
256
+ text: `Could not create the payment request: ${err.message}`
257
+ });
258
+ return false;
259
+ }
260
+ },
261
+ examples: [
262
+ [
263
+ {
264
+ // @ts-expect-error — Eliza example messages allow free-form user names
265
+ user: "{{user1}}",
266
+ content: { text: "Send me a payment request for \xA39.99" }
267
+ },
268
+ {
269
+ // @ts-expect-error
270
+ user: "{{agentName}}",
271
+ content: {
272
+ text: "Payment request created: \xA39.99\nPay here: https://api.algovoi.co.uk/p/uW9MJN-abc123",
273
+ action: "CREATE_PAYMENT_REQUEST"
274
+ }
275
+ }
276
+ ],
277
+ [
278
+ {
279
+ // @ts-expect-error
280
+ user: "{{user1}}",
281
+ content: { text: "Invoice the customer 49.50 USD on Solana mainnet" }
282
+ },
283
+ {
284
+ // @ts-expect-error
285
+ user: "{{agentName}}",
286
+ content: {
287
+ text: "Payment request created: $49.50\nPay here: https://api.algovoi.co.uk/p/Ks2pQR-xyz789",
288
+ action: "CREATE_PAYMENT_REQUEST"
289
+ }
290
+ }
291
+ ]
292
+ ]
293
+ };
294
+
295
+ // src/actions/verifyPayment.ts
296
+ import { z as z3 } from "zod";
297
+ var inputSchema2 = z3.object({
298
+ network: z3.string().min(3),
299
+ tx_id: z3.string().min(4),
300
+ resource_id: z3.string().optional(),
301
+ token: z3.string().optional(),
302
+ protocol: z3.enum(["x402", "mpp", "ap2"]).optional()
303
+ }).refine((v) => !!(v.resource_id || v.token), {
304
+ message: "Either resource_id or token is required",
305
+ path: ["resource_id"]
306
+ });
307
+ function parseFromText2(text) {
308
+ if (!text) return null;
309
+ const networkMatch = text.match(
310
+ /\b(algorand|voi|hedera|stellar|base|solana|tempo)(_(?:main|test)net|_devnet|_sepolia)?\b/i
311
+ );
312
+ const txMatch = text.match(/\b([A-Za-z0-9]{32,128})\b/);
313
+ const tokenMatch = text.match(/\b(?:token|checkout)[\s:=]+([A-Za-z0-9_-]{6,})\b/i);
314
+ const resourceMatch = text.match(/\b(?:resource|resource_id)[\s:=]+([A-Za-z0-9_-]+)\b/i);
315
+ if (!networkMatch || !txMatch) return null;
316
+ const candidate = {
317
+ network: `${networkMatch[1].toLowerCase()}${networkMatch[2] ?? "_mainnet"}`,
318
+ tx_id: txMatch[1]
319
+ };
320
+ if (tokenMatch) candidate.token = tokenMatch[1];
321
+ if (resourceMatch) candidate.resource_id = resourceMatch[1];
322
+ const result = inputSchema2.safeParse(candidate);
323
+ return result.success ? result.data : null;
324
+ }
325
+ var verifyPaymentAction = {
326
+ name: "VERIFY_PAYMENT",
327
+ similes: [
328
+ "CONFIRM_PAYMENT",
329
+ "CHECK_TRANSACTION",
330
+ "VERIFY_TX",
331
+ "VALIDATE_PAYMENT",
332
+ "AUTHENTICATE_PAYMENT"
333
+ ],
334
+ description: "Verify an on-chain crypto payment. Given a network and tx_id (plus a checkout token or resource_id for context), AlgoVoi confirms the transaction matches the expected amount, receiver, and binding. Supports x402, MPP (IETF), and AP2 (Google Agentic Payments) on Algorand, VOI, Hedera, Stellar, Base, Solana, and Tempo. Returns an access_token JWT on success.",
335
+ validate: async (runtime) => {
336
+ try {
337
+ resolveAlgoVoiConfig(runtime);
338
+ return true;
339
+ } catch {
340
+ return false;
341
+ }
342
+ },
343
+ handler: async (runtime, message, _state, options, callback) => {
344
+ const config = resolveAlgoVoiConfig(runtime);
345
+ const client = new AlgoVoiClient(config);
346
+ let parsed = null;
347
+ if (options && Object.keys(options).length > 0) {
348
+ const result = inputSchema2.safeParse(options);
349
+ if (result.success) parsed = result.data;
350
+ }
351
+ if (!parsed) {
352
+ const text = message.content?.text ?? "";
353
+ parsed = parseFromText2(text);
354
+ }
355
+ if (!parsed) {
356
+ callback?.({
357
+ text: 'To verify a payment I need a network, a tx_id, and either a checkout token or a resource_id. Try: { "network": "algorand_mainnet", "tx_id": "ABC...", "token": "uW9MJN-abc123" }'
358
+ });
359
+ return false;
360
+ }
361
+ try {
362
+ const result = await client.verifyPayment(parsed);
363
+ if (result.verified) {
364
+ callback?.({
365
+ text: `Payment verified on ${parsed.network}.
366
+ tx_id: ${parsed.tx_id}
367
+ ` + (result.access_token ? `access_token: ${result.access_token}` : ""),
368
+ action: "VERIFY_PAYMENT",
369
+ // @ts-expect-error
370
+ metadata: {
371
+ verified: true,
372
+ tx_id: parsed.tx_id,
373
+ access_token: result.access_token
374
+ }
375
+ });
376
+ } else {
377
+ callback?.({
378
+ text: `Payment NOT verified: ${result.error ?? "unknown error"}`,
379
+ action: "VERIFY_PAYMENT",
380
+ // @ts-expect-error
381
+ metadata: { verified: false, error: result.error }
382
+ });
383
+ }
384
+ return true;
385
+ } catch (err) {
386
+ callback?.({
387
+ text: `Verification call failed: ${err.message}`
388
+ });
389
+ return false;
390
+ }
391
+ },
392
+ examples: [
393
+ [
394
+ {
395
+ // @ts-expect-error
396
+ user: "{{user1}}",
397
+ content: {
398
+ text: "Verify tx 7K9X...PQR on algorand_mainnet for token uW9MJN-abc123"
399
+ }
400
+ },
401
+ {
402
+ // @ts-expect-error
403
+ user: "{{agentName}}",
404
+ content: {
405
+ text: "Payment verified on algorand_mainnet. tx_id: 7K9X...PQR",
406
+ action: "VERIFY_PAYMENT"
407
+ }
408
+ }
409
+ ],
410
+ [
411
+ {
412
+ // @ts-expect-error
413
+ user: "{{user1}}",
414
+ content: {
415
+ text: "Did the user pay for resource premium-content on solana_mainnet (tx 5Hg...M4)?"
416
+ }
417
+ },
418
+ {
419
+ // @ts-expect-error
420
+ user: "{{agentName}}",
421
+ content: {
422
+ text: "Payment verified on solana_mainnet. tx_id: 5Hg...M4",
423
+ action: "VERIFY_PAYMENT"
424
+ }
425
+ }
426
+ ]
427
+ ]
428
+ };
429
+
430
+ // src/actions/checkPaymentStatus.ts
431
+ import { z as z4 } from "zod";
432
+ var inputSchema3 = z4.object({
433
+ token: z4.string().min(6)
434
+ });
435
+ function parseFromText3(text) {
436
+ if (!text) return null;
437
+ const explicit = text.match(/\b(?:token|checkout)[\s:=]+([A-Za-z0-9_-]{6,})\b/i);
438
+ if (explicit) return { token: explicit[1] };
439
+ const bare = text.match(/\b([A-Za-z0-9]{6,12}-[A-Za-z0-9]{6,})\b/);
440
+ if (bare) return { token: bare[1] };
441
+ return null;
442
+ }
443
+ var checkPaymentStatusAction = {
444
+ name: "CHECK_PAYMENT_STATUS",
445
+ similes: [
446
+ "POLL_PAYMENT",
447
+ "PAYMENT_STATUS",
448
+ "IS_PAID",
449
+ "CHECK_CHECKOUT",
450
+ "HAS_USER_PAID"
451
+ ],
452
+ description: "Poll a previously-issued AlgoVoi checkout token for its current payment status. Returns one of: active (waiting), paid, expired, or cancelled. Use after CREATE_PAYMENT_REQUEST to detect when the payer completes settlement on-chain.",
453
+ validate: async (runtime) => {
454
+ try {
455
+ resolveAlgoVoiConfig(runtime);
456
+ return true;
457
+ } catch {
458
+ return false;
459
+ }
460
+ },
461
+ handler: async (runtime, message, _state, options, callback) => {
462
+ const config = resolveAlgoVoiConfig(runtime);
463
+ const client = new AlgoVoiClient(config);
464
+ let parsed = null;
465
+ if (options && Object.keys(options).length > 0) {
466
+ const result = inputSchema3.safeParse(options);
467
+ if (result.success) parsed = result.data;
468
+ }
469
+ if (!parsed) {
470
+ const text = message.content?.text ?? "";
471
+ parsed = parseFromText3(text);
472
+ }
473
+ if (!parsed) {
474
+ callback?.({
475
+ text: 'I need a checkout token to look up. Try: "check payment status for token uW9MJN-abc123" or pass { "token": "uW9MJN-abc123" } as options.'
476
+ });
477
+ return false;
478
+ }
479
+ try {
480
+ const result = await client.checkStatus(parsed);
481
+ const friendly = result.status === "paid" ? `Paid. Redirect target: ${result.redirect_url ?? "(none)"}` : result.status === "active" ? "Still waiting for payment." : result.status === "expired" ? "Checkout link has expired." : result.status === "cancelled" ? "Checkout was cancelled." : `Unknown status: ${result.status}`;
482
+ callback?.({
483
+ text: `Status for token ${parsed.token}: ${result.status}
484
+ ${friendly}`,
485
+ action: "CHECK_PAYMENT_STATUS",
486
+ // @ts-expect-error
487
+ metadata: result
488
+ });
489
+ return true;
490
+ } catch (err) {
491
+ callback?.({
492
+ text: `Status lookup failed: ${err.message}`
493
+ });
494
+ return false;
495
+ }
496
+ },
497
+ examples: [
498
+ [
499
+ {
500
+ // @ts-expect-error
501
+ user: "{{user1}}",
502
+ content: { text: "Has token uW9MJN-abc123 been paid?" }
503
+ },
504
+ {
505
+ // @ts-expect-error
506
+ user: "{{agentName}}",
507
+ content: {
508
+ text: "Status for token uW9MJN-abc123: paid",
509
+ action: "CHECK_PAYMENT_STATUS"
510
+ }
511
+ }
512
+ ],
513
+ [
514
+ {
515
+ // @ts-expect-error
516
+ user: "{{user1}}",
517
+ content: { text: "What's the status of checkout Ks2pQR-xyz789?" }
518
+ },
519
+ {
520
+ // @ts-expect-error
521
+ user: "{{agentName}}",
522
+ content: {
523
+ text: "Status for token Ks2pQR-xyz789: active",
524
+ action: "CHECK_PAYMENT_STATUS"
525
+ }
526
+ }
527
+ ]
528
+ ]
529
+ };
530
+
531
+ // src/providers/algovoiAgent.ts
532
+ var algovoiProvider = {
533
+ name: "algovoi",
534
+ description: "Provides context on AlgoVoi payment capabilities \u2014 supported chains, default network, agent endpoint.",
535
+ get: async (runtime, _message) => {
536
+ let config;
537
+ try {
538
+ config = resolveAlgoVoiConfig(runtime);
539
+ } catch (err) {
540
+ return {
541
+ text: `AlgoVoi is not configured. Set ALGOVOI_API_KEY in environment or runtime settings. (${err.message})`,
542
+ values: { configured: false }
543
+ };
544
+ }
545
+ const text = `AlgoVoi payment capabilities are available on this agent.
546
+ Endpoint: ${config.ALGOVOI_API_BASE}
547
+ Default network: ${config.ALGOVOI_DEFAULT_NETWORK}
548
+ Default currency: ${config.ALGOVOI_DEFAULT_CURRENCY}
549
+ Supported networks: ${SUPPORTED_NETWORKS.filter((n) => n.endsWith("_mainnet")).join(", ")}
550
+ Available actions:
551
+ - CREATE_PAYMENT_REQUEST: ask for a fiat-denominated payment, returns a checkout URL
552
+ - VERIFY_PAYMENT: confirm an on-chain tx satisfies a payment
553
+ - CHECK_PAYMENT_STATUS: poll an outstanding checkout token
554
+ `;
555
+ return {
556
+ text,
557
+ values: {
558
+ configured: true,
559
+ api_base: config.ALGOVOI_API_BASE,
560
+ default_network: config.ALGOVOI_DEFAULT_NETWORK,
561
+ default_currency: config.ALGOVOI_DEFAULT_CURRENCY,
562
+ supported_networks: SUPPORTED_NETWORKS.filter((n) => n.endsWith("_mainnet"))
563
+ }
564
+ };
565
+ }
566
+ };
567
+
568
+ // src/index.ts
569
+ var algovoiPlugin = {
570
+ name: "algovoi",
571
+ description: "AlgoVoi multi-chain payments. Ask for, verify, and poll fiat-denominated crypto payments across 7 chains via the AlgoVoi A2A gateway.",
572
+ actions: [
573
+ createPaymentRequestAction,
574
+ verifyPaymentAction,
575
+ checkPaymentStatusAction
576
+ ],
577
+ providers: [algovoiProvider],
578
+ evaluators: [],
579
+ services: []
580
+ };
581
+ var index_default = algovoiPlugin;
582
+ export {
583
+ AlgoVoiClient,
584
+ SUPPORTED_NETWORKS,
585
+ algovoiPlugin,
586
+ index_default as default,
587
+ resolveAlgoVoiConfig
588
+ };
589
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/actions/createPaymentRequest.ts","../src/client.ts","../src/environment.ts","../src/actions/verifyPayment.ts","../src/actions/checkPaymentStatus.ts","../src/providers/algovoiAgent.ts","../src/index.ts"],"sourcesContent":["/**\n * CREATE_PAYMENT_REQUEST — generates a hosted AlgoVoi checkout link.\n *\n * This action lets an Eliza agent ask the user (or another agent) for a\n * payment of a specified fiat amount, settled on any of AlgoVoi's\n * supported chains. The user gets a checkout URL they can open in a\n * browser; the agent gets a `token` it can poll later via CHECK_PAYMENT_STATUS.\n */\n\nimport type {\n Action,\n HandlerCallback,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { z } from \"zod\";\n\nimport { AlgoVoiClient } from \"../client.js\";\nimport { resolveAlgoVoiConfig } from \"../environment.js\";\n\nconst inputSchema = z.object({\n amount: z.number().positive(),\n currency: z.string().length(3).optional(),\n label: z.string().max(120).optional(),\n preferred_network: z.string().optional(),\n redirect_url: z.string().url().optional(),\n expires_in_seconds: z.number().int().positive().optional(),\n});\n\n/**\n * Best-effort fallback parser when the LLM doesn't supply a structured\n * options blob. Pulls amount/currency/network from message text using\n * a tolerant regex set.\n */\nfunction parseFromText(text: string): z.infer<typeof inputSchema> | null {\n if (!text) return null;\n // Currency symbols and ISO codes\n const symbolMap: Record<string, string> = { \"£\": \"GBP\", \"$\": \"USD\", \"€\": \"EUR\" };\n const symbolMatch = text.match(/([£$€])\\s*(\\d+(?:\\.\\d{1,2})?)/);\n const isoMatch = text.match(/(\\d+(?:\\.\\d{1,2})?)\\s*(GBP|USD|EUR|JPY|AUD|CAD|CHF|NZD)\\b/i);\n let amount: number | undefined;\n let currency: string | undefined;\n if (symbolMatch) {\n amount = parseFloat(symbolMatch[2]);\n currency = symbolMap[symbolMatch[1]];\n } else if (isoMatch) {\n amount = parseFloat(isoMatch[1]);\n currency = isoMatch[2].toUpperCase();\n }\n if (amount === undefined || !Number.isFinite(amount)) return null;\n\n const networkMatch = text.match(\n /\\b(algorand|voi|hedera|stellar|base|solana|tempo)(_(?:main|test)net)?\\b/i,\n );\n const preferred_network = networkMatch\n ? `${networkMatch[1].toLowerCase()}${networkMatch[2] ?? \"_mainnet\"}`\n : undefined;\n\n return inputSchema.parse({ amount, currency, preferred_network });\n}\n\nexport const createPaymentRequestAction: Action = {\n name: \"CREATE_PAYMENT_REQUEST\",\n similes: [\n \"CREATE_CHECKOUT\",\n \"REQUEST_PAYMENT\",\n \"GENERATE_PAYMENT_LINK\",\n \"INVOICE\",\n \"BILL\",\n \"ASK_FOR_PAYMENT\",\n ],\n description:\n \"Create a hosted AlgoVoi checkout link for a fiat amount. Returns a URL the payer can open in any browser, plus a token the agent can poll for payment status. Settles on Algorand, VOI, Hedera, Stellar, Base, Solana, or Tempo via stablecoin or native asset.\",\n\n validate: async (runtime: IAgentRuntime, _message: Memory) => {\n try {\n resolveAlgoVoiConfig(runtime);\n return true;\n } catch {\n return false;\n }\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n options: Record<string, unknown> | undefined,\n callback: HandlerCallback | undefined,\n ) => {\n const config = resolveAlgoVoiConfig(runtime);\n const client = new AlgoVoiClient(config);\n\n let parsed: z.infer<typeof inputSchema> | null = null;\n if (options && Object.keys(options).length > 0) {\n const result = inputSchema.safeParse(options);\n if (result.success) parsed = result.data;\n }\n if (!parsed) {\n const text =\n (message.content as { text?: string } | undefined)?.text ?? \"\";\n parsed = parseFromText(text);\n }\n\n if (!parsed || !parsed.amount) {\n const errText =\n \"I need an amount and currency to create a payment request. \" +\n \"Try: 'create a payment request for £9.99' or pass \" +\n '{ \"amount\": 9.99, \"currency\": \"GBP\" } as options.';\n callback?.({ text: errText });\n return false;\n }\n\n try {\n const result = await client.createCheckout(parsed);\n const symbol =\n parsed.currency === \"GBP\"\n ? \"£\"\n : parsed.currency === \"USD\"\n ? \"$\"\n : parsed.currency === \"EUR\"\n ? \"€\"\n : `${parsed.currency ?? config.ALGOVOI_DEFAULT_CURRENCY} `;\n const replyText =\n `Payment request created: ${symbol}${parsed.amount.toFixed(2)}\\n` +\n `Pay here: ${result.checkout_url}\\n` +\n `Token (for polling): ${result.token}` +\n (result.expires_at ? `\\nExpires at: ${result.expires_at}` : \"\");\n callback?.({\n text: replyText,\n action: \"CREATE_PAYMENT_REQUEST\",\n // @ts-expect-error — eliza Memory.content allows arbitrary keys for tool output\n metadata: {\n token: result.token,\n checkout_url: result.checkout_url,\n status: result.status,\n chain: result.chain,\n amount_microunits: result.amount_microunits,\n },\n });\n return true;\n } catch (err) {\n callback?.({\n text: `Could not create the payment request: ${(err as Error).message}`,\n });\n return false;\n }\n },\n\n examples: [\n [\n {\n // @ts-expect-error — Eliza example messages allow free-form user names\n user: \"{{user1}}\",\n content: { text: \"Send me a payment request for £9.99\" },\n },\n {\n // @ts-expect-error\n user: \"{{agentName}}\",\n content: {\n text: \"Payment request created: £9.99\\nPay here: https://api.algovoi.co.uk/p/uW9MJN-abc123\",\n action: \"CREATE_PAYMENT_REQUEST\",\n },\n },\n ],\n [\n {\n // @ts-expect-error\n user: \"{{user1}}\",\n content: { text: \"Invoice the customer 49.50 USD on Solana mainnet\" },\n },\n {\n // @ts-expect-error\n user: \"{{agentName}}\",\n content: {\n text: \"Payment request created: $49.50\\nPay here: https://api.algovoi.co.uk/p/Ks2pQR-xyz789\",\n action: \"CREATE_PAYMENT_REQUEST\",\n },\n },\n ],\n ],\n};\n","/**\n * AlgoVoi A2A client.\n *\n * Thin wrapper around the Google A2A v0.3 endpoints exposed by the\n * AlgoVoi payment gateway at `<api_base>/message:send`.\n *\n * Authenticates with `Authorization: Bearer <api_key>` per the agent\n * card's `securitySchemes.apiKey` definition.\n */\n\nimport type { AlgoVoiConfig } from \"./environment.js\";\nimport type {\n CreateCheckoutInput,\n CreateCheckoutResult,\n VerifyPaymentInput,\n VerifyPaymentResult,\n CheckStatusInput,\n CheckStatusResult,\n A2APart,\n A2ATask,\n} from \"./types.js\";\n\nexport class AlgoVoiClient {\n constructor(private readonly config: AlgoVoiConfig) {}\n\n /**\n * Send an A2A `message:send` request, asserting the response task\n * completed successfully and returning the result data part.\n */\n private async sendSkill<TResult>(skill: string, data: Record<string, unknown>): Promise<TResult> {\n const url = `${this.config.ALGOVOI_API_BASE}/message:send`;\n const messageId = crypto.randomUUID();\n\n const body = {\n message: {\n messageId,\n role: \"user\",\n parts: [\n {\n kind: \"data\",\n data: { skill, ...data },\n },\n ],\n },\n };\n\n let resp: Response;\n try {\n resp = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: `Bearer ${this.config.ALGOVOI_API_KEY}`,\n \"User-Agent\": \"@algovoi/plugin-elizaos\",\n },\n body: JSON.stringify(body),\n });\n } catch (err) {\n throw new Error(`AlgoVoi network error: ${(err as Error).message}`);\n }\n\n if (!resp.ok) {\n const text = await resp.text().catch(() => \"\");\n throw new Error(\n `AlgoVoi API ${resp.status}: ${text || resp.statusText}`,\n );\n }\n\n const payload = (await resp.json()) as { task?: A2ATask };\n const task = payload.task;\n if (!task) {\n throw new Error(\"AlgoVoi response missing 'task' field\");\n }\n\n const state = task.status?.state;\n if (state === \"failed\") {\n const messageParts = task.status?.message?.parts ?? [];\n const textPart = messageParts.find(\n (p): p is Extract<A2APart, { kind: \"text\" }> => p.kind === \"text\",\n );\n const errorText = textPart?.text ?? \"task failed without error detail\";\n throw new Error(`AlgoVoi skill '${skill}' failed: ${errorText}`);\n }\n if (state !== \"completed\") {\n throw new Error(`AlgoVoi skill '${skill}' returned unexpected state '${state}'`);\n }\n\n const artifactParts = task.artifacts?.[0]?.parts ?? [];\n const dataPart = artifactParts.find(\n (p): p is Extract<A2APart, { kind: \"data\" }> => p.kind === \"data\",\n );\n if (!dataPart || !dataPart.data) {\n throw new Error(`AlgoVoi skill '${skill}' completed with no data part`);\n }\n return dataPart.data as TResult;\n }\n\n createCheckout(input: CreateCheckoutInput): Promise<CreateCheckoutResult> {\n return this.sendSkill<CreateCheckoutResult>(\"create-checkout\", {\n amount: input.amount,\n currency: input.currency ?? this.config.ALGOVOI_DEFAULT_CURRENCY,\n label: input.label ?? \"Payment\",\n preferred_network: input.preferred_network ?? this.config.ALGOVOI_DEFAULT_NETWORK,\n redirect_url: input.redirect_url,\n expires_in_seconds: input.expires_in_seconds,\n });\n }\n\n verifyPayment(input: VerifyPaymentInput): Promise<VerifyPaymentResult> {\n const data: Record<string, unknown> = {\n network: input.network,\n tx_id: input.tx_id,\n };\n if (input.resource_id) data.resource_id = input.resource_id;\n if (input.token) data.token = input.token;\n if (input.protocol) data.protocol = input.protocol;\n return this.sendSkill<VerifyPaymentResult>(\"verify-payment\", data);\n }\n\n checkStatus(input: CheckStatusInput): Promise<CheckStatusResult> {\n return this.sendSkill<CheckStatusResult>(\"check-status\", {\n token: input.token,\n });\n }\n\n /**\n * Fetch the public agent card (no auth required). Useful for\n * introspecting the deployed AlgoVoi instance's capabilities.\n */\n async fetchAgentCard(): Promise<unknown> {\n const url = `${this.config.ALGOVOI_API_BASE}/.well-known/agent.json`;\n const resp = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n if (!resp.ok) {\n throw new Error(`Agent card fetch failed: ${resp.status}`);\n }\n return resp.json();\n }\n}\n","/**\n * Environment configuration for the AlgoVoi ElizaOS plugin.\n *\n * The plugin authenticates against the AlgoVoi A2A endpoint using a\n * tenant API key. Tenants are issued at https://dash.algovoi.co.uk/signup\n * (free tier; testnet by default).\n */\n\nimport { z } from \"zod\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\n\nexport const algovoiEnvSchema = z.object({\n ALGOVOI_API_KEY: z\n .string({ required_error: \"ALGOVOI_API_KEY is required\" })\n .min(8, \"ALGOVOI_API_KEY looks too short\"),\n ALGOVOI_API_BASE: z\n .string()\n .url()\n .default(\"https://api.algovoi.co.uk\"),\n ALGOVOI_DEFAULT_NETWORK: z\n .string()\n .default(\"algorand_mainnet\"),\n ALGOVOI_DEFAULT_CURRENCY: z\n .string()\n .length(3)\n .default(\"GBP\"),\n});\n\nexport type AlgoVoiConfig = z.infer<typeof algovoiEnvSchema>;\n\n/**\n * Resolve config from the runtime's settings (preferred) with fallback to\n * `process.env`. Throws a clear message if required values are missing.\n */\nexport function resolveAlgoVoiConfig(runtime: IAgentRuntime): AlgoVoiConfig {\n const fromRuntime = (key: string): string | undefined => {\n try {\n const v = runtime.getSetting(key);\n return typeof v === \"string\" && v.length > 0 ? v : undefined;\n } catch {\n return undefined;\n }\n };\n const env = (key: string): string | undefined => {\n if (typeof process === \"undefined\" || !process.env) return undefined;\n const v = process.env[key];\n return typeof v === \"string\" && v.length > 0 ? v : undefined;\n };\n\n const merged = {\n ALGOVOI_API_KEY: fromRuntime(\"ALGOVOI_API_KEY\") ?? env(\"ALGOVOI_API_KEY\"),\n ALGOVOI_API_BASE: fromRuntime(\"ALGOVOI_API_BASE\") ?? env(\"ALGOVOI_API_BASE\"),\n ALGOVOI_DEFAULT_NETWORK:\n fromRuntime(\"ALGOVOI_DEFAULT_NETWORK\") ?? env(\"ALGOVOI_DEFAULT_NETWORK\"),\n ALGOVOI_DEFAULT_CURRENCY:\n fromRuntime(\"ALGOVOI_DEFAULT_CURRENCY\") ?? env(\"ALGOVOI_DEFAULT_CURRENCY\"),\n };\n\n const cleaned = Object.fromEntries(\n Object.entries(merged).filter(([, v]) => v !== undefined),\n );\n\n return algovoiEnvSchema.parse(cleaned);\n}\n\n/**\n * The 7 mainnet networks AlgoVoi currently supports. Used for validation\n * and for the agent's available_networks introspection.\n */\nexport const SUPPORTED_NETWORKS = [\n \"algorand_mainnet\",\n \"voi_mainnet\",\n \"hedera_mainnet\",\n \"stellar_mainnet\",\n \"base_mainnet\",\n \"solana_mainnet\",\n \"tempo_mainnet\",\n // Testnets — useful for development\n \"algorand_testnet\",\n \"voi_testnet\",\n \"hedera_testnet\",\n \"stellar_testnet\",\n \"base_sepolia\",\n \"solana_devnet\",\n \"tempo_testnet\",\n] as const;\n\nexport type SupportedNetwork = (typeof SUPPORTED_NETWORKS)[number];\n","/**\n * VERIFY_PAYMENT — verify an on-chain transaction satisfies a payment.\n *\n * Given a network + tx_id, plus either a checkout token or a resource id,\n * AlgoVoi confirms the transaction matches the expected amount, receiver,\n * memo / reference binding, and (where relevant) asset. Returns a JWT\n * access_token on success that the agent can use to gate downstream calls.\n */\n\nimport type {\n Action,\n HandlerCallback,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { z } from \"zod\";\n\nimport { AlgoVoiClient } from \"../client.js\";\nimport { resolveAlgoVoiConfig } from \"../environment.js\";\n\nconst inputSchema = z\n .object({\n network: z.string().min(3),\n tx_id: z.string().min(4),\n resource_id: z.string().optional(),\n token: z.string().optional(),\n protocol: z.enum([\"x402\", \"mpp\", \"ap2\"]).optional(),\n })\n .refine((v) => !!(v.resource_id || v.token), {\n message: \"Either resource_id or token is required\",\n path: [\"resource_id\"],\n });\n\nfunction parseFromText(text: string): z.infer<typeof inputSchema> | null {\n if (!text) return null;\n const networkMatch = text.match(\n /\\b(algorand|voi|hedera|stellar|base|solana|tempo)(_(?:main|test)net|_devnet|_sepolia)?\\b/i,\n );\n // tx ids are typically 32+ hex/base32/base58 chars.\n const txMatch = text.match(/\\b([A-Za-z0-9]{32,128})\\b/);\n const tokenMatch = text.match(/\\b(?:token|checkout)[\\s:=]+([A-Za-z0-9_-]{6,})\\b/i);\n const resourceMatch = text.match(/\\b(?:resource|resource_id)[\\s:=]+([A-Za-z0-9_-]+)\\b/i);\n if (!networkMatch || !txMatch) return null;\n\n const candidate: Record<string, unknown> = {\n network: `${networkMatch[1].toLowerCase()}${networkMatch[2] ?? \"_mainnet\"}`,\n tx_id: txMatch[1],\n };\n if (tokenMatch) candidate.token = tokenMatch[1];\n if (resourceMatch) candidate.resource_id = resourceMatch[1];\n\n const result = inputSchema.safeParse(candidate);\n return result.success ? result.data : null;\n}\n\nexport const verifyPaymentAction: Action = {\n name: \"VERIFY_PAYMENT\",\n similes: [\n \"CONFIRM_PAYMENT\",\n \"CHECK_TRANSACTION\",\n \"VERIFY_TX\",\n \"VALIDATE_PAYMENT\",\n \"AUTHENTICATE_PAYMENT\",\n ],\n description:\n \"Verify an on-chain crypto payment. Given a network and tx_id (plus a checkout token or resource_id for context), AlgoVoi confirms the transaction matches the expected amount, receiver, and binding. Supports x402, MPP (IETF), and AP2 (Google Agentic Payments) on Algorand, VOI, Hedera, Stellar, Base, Solana, and Tempo. Returns an access_token JWT on success.\",\n\n validate: async (runtime: IAgentRuntime) => {\n try {\n resolveAlgoVoiConfig(runtime);\n return true;\n } catch {\n return false;\n }\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n options: Record<string, unknown> | undefined,\n callback: HandlerCallback | undefined,\n ) => {\n const config = resolveAlgoVoiConfig(runtime);\n const client = new AlgoVoiClient(config);\n\n let parsed: z.infer<typeof inputSchema> | null = null;\n if (options && Object.keys(options).length > 0) {\n const result = inputSchema.safeParse(options);\n if (result.success) parsed = result.data;\n }\n if (!parsed) {\n const text =\n (message.content as { text?: string } | undefined)?.text ?? \"\";\n parsed = parseFromText(text);\n }\n\n if (!parsed) {\n callback?.({\n text:\n \"To verify a payment I need a network, a tx_id, and either a checkout token or a resource_id. \" +\n 'Try: { \"network\": \"algorand_mainnet\", \"tx_id\": \"ABC...\", \"token\": \"uW9MJN-abc123\" }',\n });\n return false;\n }\n\n try {\n const result = await client.verifyPayment(parsed);\n if (result.verified) {\n callback?.({\n text:\n `Payment verified on ${parsed.network}.\\n` +\n `tx_id: ${parsed.tx_id}\\n` +\n (result.access_token ? `access_token: ${result.access_token}` : \"\"),\n action: \"VERIFY_PAYMENT\",\n // @ts-expect-error\n metadata: {\n verified: true,\n tx_id: parsed.tx_id,\n access_token: result.access_token,\n },\n });\n } else {\n callback?.({\n text: `Payment NOT verified: ${result.error ?? \"unknown error\"}`,\n action: \"VERIFY_PAYMENT\",\n // @ts-expect-error\n metadata: { verified: false, error: result.error },\n });\n }\n return true;\n } catch (err) {\n callback?.({\n text: `Verification call failed: ${(err as Error).message}`,\n });\n return false;\n }\n },\n\n examples: [\n [\n {\n // @ts-expect-error\n user: \"{{user1}}\",\n content: {\n text: \"Verify tx 7K9X...PQR on algorand_mainnet for token uW9MJN-abc123\",\n },\n },\n {\n // @ts-expect-error\n user: \"{{agentName}}\",\n content: {\n text: \"Payment verified on algorand_mainnet. tx_id: 7K9X...PQR\",\n action: \"VERIFY_PAYMENT\",\n },\n },\n ],\n [\n {\n // @ts-expect-error\n user: \"{{user1}}\",\n content: {\n text: \"Did the user pay for resource premium-content on solana_mainnet (tx 5Hg...M4)?\",\n },\n },\n {\n // @ts-expect-error\n user: \"{{agentName}}\",\n content: {\n text: \"Payment verified on solana_mainnet. tx_id: 5Hg...M4\",\n action: \"VERIFY_PAYMENT\",\n },\n },\n ],\n ],\n};\n","/**\n * CHECK_PAYMENT_STATUS — poll a checkout token for current status.\n *\n * Pairs with CREATE_PAYMENT_REQUEST. After issuing a checkout the agent\n * holds a token; this action polls the gateway for current status:\n * `active`, `paid`, `expired`, or `cancelled`.\n */\n\nimport type {\n Action,\n HandlerCallback,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { z } from \"zod\";\n\nimport { AlgoVoiClient } from \"../client.js\";\nimport { resolveAlgoVoiConfig } from \"../environment.js\";\n\nconst inputSchema = z.object({\n token: z.string().min(6),\n});\n\nfunction parseFromText(text: string): z.infer<typeof inputSchema> | null {\n if (!text) return null;\n // Accept \"token X\", \"checkout X\", or a bare slug-looking string.\n const explicit = text.match(/\\b(?:token|checkout)[\\s:=]+([A-Za-z0-9_-]{6,})\\b/i);\n if (explicit) return { token: explicit[1] };\n const bare = text.match(/\\b([A-Za-z0-9]{6,12}-[A-Za-z0-9]{6,})\\b/);\n if (bare) return { token: bare[1] };\n return null;\n}\n\nexport const checkPaymentStatusAction: Action = {\n name: \"CHECK_PAYMENT_STATUS\",\n similes: [\n \"POLL_PAYMENT\",\n \"PAYMENT_STATUS\",\n \"IS_PAID\",\n \"CHECK_CHECKOUT\",\n \"HAS_USER_PAID\",\n ],\n description:\n \"Poll a previously-issued AlgoVoi checkout token for its current payment status. Returns one of: active (waiting), paid, expired, or cancelled. Use after CREATE_PAYMENT_REQUEST to detect when the payer completes settlement on-chain.\",\n\n validate: async (runtime: IAgentRuntime) => {\n try {\n resolveAlgoVoiConfig(runtime);\n return true;\n } catch {\n return false;\n }\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n options: Record<string, unknown> | undefined,\n callback: HandlerCallback | undefined,\n ) => {\n const config = resolveAlgoVoiConfig(runtime);\n const client = new AlgoVoiClient(config);\n\n let parsed: z.infer<typeof inputSchema> | null = null;\n if (options && Object.keys(options).length > 0) {\n const result = inputSchema.safeParse(options);\n if (result.success) parsed = result.data;\n }\n if (!parsed) {\n const text =\n (message.content as { text?: string } | undefined)?.text ?? \"\";\n parsed = parseFromText(text);\n }\n\n if (!parsed) {\n callback?.({\n text:\n 'I need a checkout token to look up. Try: \"check payment status for token uW9MJN-abc123\" ' +\n 'or pass { \"token\": \"uW9MJN-abc123\" } as options.',\n });\n return false;\n }\n\n try {\n const result = await client.checkStatus(parsed);\n const friendly =\n result.status === \"paid\"\n ? `Paid. Redirect target: ${result.redirect_url ?? \"(none)\"}`\n : result.status === \"active\"\n ? \"Still waiting for payment.\"\n : result.status === \"expired\"\n ? \"Checkout link has expired.\"\n : result.status === \"cancelled\"\n ? \"Checkout was cancelled.\"\n : `Unknown status: ${result.status}`;\n callback?.({\n text: `Status for token ${parsed.token}: ${result.status}\\n${friendly}`,\n action: \"CHECK_PAYMENT_STATUS\",\n // @ts-expect-error\n metadata: result,\n });\n return true;\n } catch (err) {\n callback?.({\n text: `Status lookup failed: ${(err as Error).message}`,\n });\n return false;\n }\n },\n\n examples: [\n [\n {\n // @ts-expect-error\n user: \"{{user1}}\",\n content: { text: \"Has token uW9MJN-abc123 been paid?\" },\n },\n {\n // @ts-expect-error\n user: \"{{agentName}}\",\n content: {\n text: \"Status for token uW9MJN-abc123: paid\",\n action: \"CHECK_PAYMENT_STATUS\",\n },\n },\n ],\n [\n {\n // @ts-expect-error\n user: \"{{user1}}\",\n content: { text: \"What's the status of checkout Ks2pQR-xyz789?\" },\n },\n {\n // @ts-expect-error\n user: \"{{agentName}}\",\n content: {\n text: \"Status for token Ks2pQR-xyz789: active\",\n action: \"CHECK_PAYMENT_STATUS\",\n },\n },\n ],\n ],\n};\n","/**\n * AlgoVoi provider — surfaces the agent's capabilities and configured\n * defaults into the runtime context so the LLM understands what\n * AlgoVoi can do without needing the user to spell it out.\n */\n\nimport type {\n IAgentRuntime,\n Memory,\n Provider,\n ProviderResult,\n} from \"@elizaos/core\";\n\nimport { resolveAlgoVoiConfig, SUPPORTED_NETWORKS } from \"../environment.js\";\n\nexport const algovoiProvider: Provider = {\n name: \"algovoi\",\n description:\n \"Provides context on AlgoVoi payment capabilities — supported chains, default network, agent endpoint.\",\n\n get: async (runtime: IAgentRuntime, _message: Memory): Promise<ProviderResult> => {\n let config: ReturnType<typeof resolveAlgoVoiConfig>;\n try {\n config = resolveAlgoVoiConfig(runtime);\n } catch (err) {\n return {\n text: `AlgoVoi is not configured. Set ALGOVOI_API_KEY in environment or runtime settings. (${(err as Error).message})`,\n values: { configured: false },\n };\n }\n\n const text =\n `AlgoVoi payment capabilities are available on this agent.\\n` +\n `Endpoint: ${config.ALGOVOI_API_BASE}\\n` +\n `Default network: ${config.ALGOVOI_DEFAULT_NETWORK}\\n` +\n `Default currency: ${config.ALGOVOI_DEFAULT_CURRENCY}\\n` +\n `Supported networks: ${SUPPORTED_NETWORKS.filter((n) => n.endsWith(\"_mainnet\")).join(\", \")}\\n` +\n `Available actions:\\n` +\n ` - CREATE_PAYMENT_REQUEST: ask for a fiat-denominated payment, returns a checkout URL\\n` +\n ` - VERIFY_PAYMENT: confirm an on-chain tx satisfies a payment\\n` +\n ` - CHECK_PAYMENT_STATUS: poll an outstanding checkout token\\n`;\n\n return {\n text,\n values: {\n configured: true,\n api_base: config.ALGOVOI_API_BASE,\n default_network: config.ALGOVOI_DEFAULT_NETWORK,\n default_currency: config.ALGOVOI_DEFAULT_CURRENCY,\n supported_networks: SUPPORTED_NETWORKS.filter((n) => n.endsWith(\"_mainnet\")),\n },\n };\n },\n};\n","/**\n * @algovoi/plugin-elizaos\n *\n * Multi-chain agent-to-agent (A2A) crypto payments for ElizaOS agents.\n * Lets an Eliza agent ask for, verify, and poll fiat-denominated\n * payments that settle as stablecoins or native assets on Algorand,\n * VOI, Hedera, Stellar, Base, Solana, or Tempo — without holding any\n * crypto, keys, or fiat itself.\n *\n * Wraps the AlgoVoi Google A2A v0.3 endpoint at\n * https://api.algovoi.co.uk/.well-known/agent.json\n */\n\nimport type { Plugin } from \"@elizaos/core\";\n\nimport {\n createPaymentRequestAction,\n verifyPaymentAction,\n checkPaymentStatusAction,\n} from \"./actions/index.js\";\nimport { algovoiProvider } from \"./providers/algovoiAgent.js\";\n\nexport { AlgoVoiClient } from \"./client.js\";\nexport { resolveAlgoVoiConfig, SUPPORTED_NETWORKS } from \"./environment.js\";\nexport type {\n AlgoVoiConfig,\n SupportedNetwork,\n} from \"./environment.js\";\nexport type {\n CreateCheckoutInput,\n CreateCheckoutResult,\n VerifyPaymentInput,\n VerifyPaymentResult,\n CheckStatusInput,\n CheckStatusResult,\n} from \"./types.js\";\n\nexport const algovoiPlugin: Plugin = {\n name: \"algovoi\",\n description:\n \"AlgoVoi multi-chain payments. Ask for, verify, and poll fiat-denominated crypto payments across 7 chains via the AlgoVoi A2A gateway.\",\n actions: [\n createPaymentRequestAction,\n verifyPaymentAction,\n checkPaymentStatusAction,\n ],\n providers: [algovoiProvider],\n evaluators: [],\n services: [],\n};\n\nexport default algovoiPlugin;\n"],"mappings":"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","names":["z","z","z","inputSchema","z","parseFromText","z","inputSchema","z","parseFromText"]}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="AlgoVoi">
2
+ <rect width="512" height="512" rx="128" ry="128" fill="#00b8a9"/>
3
+ <text x="256" y="256"
4
+ font-family="Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif"
5
+ font-weight="900"
6
+ font-size="240"
7
+ fill="#ffffff"
8
+ text-anchor="middle"
9
+ dominant-baseline="central"
10
+ letter-spacing="-8">AV</text>
11
+ </svg>
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "@algovoi/plugin-elizaos",
3
+ "version": "0.1.0",
4
+ "description": "Multi-chain agent-to-agent (A2A) crypto payments for ElizaOS — ask, verify, and poll fiat-denominated payments that settle as USDC or native assets across Algorand, VOI, Hedera, Stellar, Base, Solana, and Tempo. Non-custodial.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE",
19
+ "images"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup --format esm --dts",
23
+ "dev": "tsup --format esm --dts --watch",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest",
26
+ "lint": "tsc --noEmit",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "dependencies": {
30
+ "zod": "^3.22.4"
31
+ },
32
+ "peerDependencies": {
33
+ "@elizaos/core": "^0.25.0 || ^1.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@elizaos/core": "^0.25.0",
37
+ "@types/node": "^20.0.0",
38
+ "tsup": "^8.3.5",
39
+ "typescript": "^5.7.3",
40
+ "vitest": "^3.0.0"
41
+ },
42
+ "engines": {
43
+ "node": ">=20"
44
+ },
45
+ "keywords": [
46
+ "elizaos",
47
+ "elizaos-plugins",
48
+ "ai-agent",
49
+ "payments",
50
+ "crypto",
51
+ "x402",
52
+ "ap2",
53
+ "a2a",
54
+ "algorand",
55
+ "voi",
56
+ "hedera",
57
+ "stellar",
58
+ "base",
59
+ "solana",
60
+ "tempo",
61
+ "stablecoin",
62
+ "usdc"
63
+ ],
64
+ "license": "MIT",
65
+ "author": "AlgoVoi <support@algovoi.co.uk>",
66
+ "homepage": "https://algovoi.co.uk",
67
+ "repository": "github:chopmob-cloud/elizaos-plugin-algovoi",
68
+ "bugs": {
69
+ "url": "https://github.com/chopmob-cloud/elizaos-plugin-algovoi/issues"
70
+ },
71
+ "agentConfig": {
72
+ "pluginType": "elizaos:plugin:1.0.0",
73
+ "pluginParameters": {
74
+ "ALGOVOI_API_KEY": {
75
+ "type": "string",
76
+ "description": "Tenant API key obtained from https://dash.algovoi.co.uk/signup. Required.",
77
+ "sensitive": true,
78
+ "required": true
79
+ },
80
+ "ALGOVOI_API_BASE": {
81
+ "type": "string",
82
+ "description": "AlgoVoi A2A endpoint base URL.",
83
+ "default": "https://api.algovoi.co.uk",
84
+ "required": false
85
+ },
86
+ "ALGOVOI_DEFAULT_NETWORK": {
87
+ "type": "string",
88
+ "description": "Default settlement network when none is specified by the user. One of: algorand_mainnet, voi_mainnet, hedera_mainnet, stellar_mainnet, base_mainnet, solana_mainnet, tempo_mainnet (or their testnet equivalents).",
89
+ "default": "algorand_mainnet",
90
+ "required": false
91
+ },
92
+ "ALGOVOI_DEFAULT_CURRENCY": {
93
+ "type": "string",
94
+ "description": "Default ISO 4217 currency for new checkouts. Defaults to GBP.",
95
+ "default": "GBP",
96
+ "required": false
97
+ }
98
+ },
99
+ "actions": [
100
+ "CREATE_PAYMENT_REQUEST",
101
+ "VERIFY_PAYMENT",
102
+ "CHECK_PAYMENT_STATUS"
103
+ ],
104
+ "providers": ["algovoi"],
105
+ "evaluators": [],
106
+ "services": [],
107
+ "models": []
108
+ }
109
+ }