@hey-research-lab/virtuals-plugin 0.0.0-stage → 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/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project uses
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## 0.1.0 — 2026-10-13
8
+
9
+ Initial release.
10
+
11
+ - GAME worker for `@virtuals-protocol/game` 0.1.14: `heyResearchWorker({ apiKey?, baseUrl? })` and
12
+ `heyResearchFunctions()` with five functions — `hey_research_project`, `hey_find_projects`,
13
+ `hey_recent_changes`, `hey_project_timeline`, `hey_chain_overview` — each returning
14
+ `ExecutableGameFunctionResponse` (Done for an answer, including "HEY holds no such project";
15
+ Failed for a refused or failed read) with text that keeps HEY's semantics, its as-of time, the
16
+ HEY link and the attribution line.
17
+ - Research by HEY slug, `$TICKER`, name or 0x contract: a contract resolves through HEY's token
18
+ lookup, a ticker or name through HEY's search, and is researched only on one exact match; several
19
+ matches are listed, never guessed.
20
+ - `@hey-research-lab/virtuals-plugin/acp`: an Agent Commerce Protocol provider scaffold for
21
+ `@virtuals-protocol/acp-node-v2` 0.1.15 offering "HEY builder research on a Robinhood Chain
22
+ project/contract". Off by default: it needs every `HEY_ACP_*` variable and `HEY_ACP_ENABLE=1`.
23
+ Price defaults to 0 USDC (pricing is the founder's decision); settlement chain (Base or Robinhood
24
+ Chain) has no default.
25
+ - Robinhood Chain (4663) only; any other chain is refused with `unsupported_chain`.
26
+ - Tests over saved fixtures with the network blocked and the ACP client fully stubbed; a
27
+ forbidden-word scan over every output.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 HEY Research Lab
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 CHANGED
@@ -1,3 +1,246 @@
1
- # Temporary Holding Version
1
+ # hey-virtuals-plugin
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A Virtuals Protocol GAME worker, plus an Agent Commerce Protocol provider scaffold, that lets an
4
+ agent ask HEY Research Lab which Robinhood Chain projects are still building, what they shipped and
5
+ what HEY does not know.
6
+
7
+ [![CI](https://github.com/hey-research-lab/hey-virtuals-plugin/actions/workflows/ci.yml/badge.svg)](https://github.com/hey-research-lab/hey-virtuals-plugin/actions/workflows/ci.yml)
8
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
9
+ [![Node >= 22](https://img.shields.io/badge/node-%3E%3D22-informational.svg)](package.json)
10
+ [![Robinhood Chain 4663](https://img.shields.io/badge/Robinhood%20Chain-4663-black.svg)](https://heyresearch.xyz)
11
+
12
+ ## Why it exists
13
+
14
+ Many agents on Robinhood Chain run on Virtuals: in HEY's own catalogue, 668 of the 971 "AI Agents"
15
+ projects were launched through Virtuals. Those agents are asked about projects, tickers and
16
+ contracts every day. This package gives them HEY's answer — activity status, the last meaningful
17
+ ship, the change ledger and the gaps, each with its evidence and source — without having to find
18
+ HEY first. It reads only HEY's public API, through the published
19
+ [`@hey-research-lab/sdk`](https://www.npmjs.com/package/@hey-research-lab/sdk).
20
+
21
+ ## Why Robinhood Chain only
22
+
23
+ HEY researches one chain: Robinhood Chain, chain id `4663` (`eip155:4663`). Every function takes
24
+ an optional `chain_id` that accepts `4663` or `eip155:4663` only; anything else is refused with
25
+ `unsupported_chain` ("HEY supports Robinhood Chain (4663) only; chain X is not supported.") before
26
+ any request. The ACP provider applies the same rule to a buyer's requirement. (Which chain an ACP
27
+ job _settles_ on is a separate choice; see below.)
28
+
29
+ ## Install
30
+
31
+ ```sh
32
+ npm install @hey-research-lab/virtuals-plugin @virtuals-protocol/game
33
+ # only for the ACP provider:
34
+ npm install @virtuals-protocol/acp-node-v2
35
+ ```
36
+
37
+ Node.js 22 or later. No HEY API key is needed; `HEY_API_KEY` (from heyresearch.xyz/account) only
38
+ lifts the anonymous rate limit.
39
+
40
+ ## Smallest working example
41
+
42
+ ```ts
43
+ import { GameAgent } from '@virtuals-protocol/game';
44
+ import { heyResearchWorker } from '@hey-research-lab/virtuals-plugin';
45
+
46
+ const agent = new GameAgent(process.env.GAME_API_KEY!, {
47
+ name: 'Robinhood Chain builder scout',
48
+ goal: 'Report which Robinhood Chain projects are still building, citing HEY.',
49
+ description: 'Reports building evidence with its source and as-of time; unknown stays unknown.',
50
+ workers: [heyResearchWorker()], // or heyResearchWorker({ apiKey, baseUrl })
51
+ });
52
+ await agent.init();
53
+ await agent.run(60, { verbose: true });
54
+ ```
55
+
56
+ To call one function without an agent (offline-friendly for your own tests, with an injected
57
+ `fetchImpl`):
58
+
59
+ ```ts
60
+ import { heyResearchFunctions } from '@hey-research-lab/virtuals-plugin';
61
+ const [research] = heyResearchFunctions();
62
+ const res = await research.executable({ query: '$AGENTOS' }, console.log);
63
+ console.log(res.status, res.feedback); // "done", HEY's answer as text
64
+ ```
65
+
66
+ A runnable script is in [`examples/game-agent.ts`](examples/game-agent.ts).
67
+
68
+ ## Functions
69
+
70
+ | Name | What it answers | SDK read |
71
+ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
72
+ | `hey_research_project` | One project by HEY slug, `$TICKER`, name or 0x contract: activity status, last meaningful ship, meaningful events in 30 days, Build Momentum, Still Building, token contract and its verification, market context, unknowns, evidence ids | `agent.answer('research_project')`, after `token.lookup` (contract) or `search.suggest` (ticker, name) |
73
+ | `hey_find_projects` | Projects in HEY's index by name, ticker or contract, each labelled: published project (slug, status, link), launch record (not researched), issuer stock token (never a project) | `search.suggest` |
74
+ | `hey_recent_changes` | What changed on the chain or for one project in 1–30 days: the true total, how many count as building, each event with its date, precision and evidence id | `agent.answer('what_changed')` |
75
+ | `hey_project_timeline` | One project's ships and timeline: date and precision, verification state, whether it counts as building, source | `projects.timeline` |
76
+ | `hey_chain_overview` | Robinhood Chain day by day: ships, builders shipping, projects published, then transactions, launches and DEX figures (market context) | `chain` |
77
+
78
+ Each returns an `ExecutableGameFunctionResponse`:
79
+
80
+ - **Done** with HEY's answer as text — including "HEY holds no published project for …" and a
81
+ list of candidates for an ambiguous name, which are answers, not failures.
82
+ - **Failed** for an unsupported chain, a malformed argument, or a read HEY refused or could not
83
+ serve, with HEY's own error code and sentence, the retry delay and the request id
84
+ (`HEY could not answer: rate_limited (HTTP 429) — … Retry after 12 seconds. Request id: …`).
85
+
86
+ Every answer keeps HEY's semantics: an unknown value reads "unknown", "not measured — reason",
87
+ "withheld — reason" or "not read", never 0 or "none"; market figures are labelled context and
88
+ never a builder signal; a ticker is not identity (a ticker that several records share is called
89
+ out, and a name that matches several projects is listed, not guessed). Every answer ends with:
90
+
91
+ ```
92
+ Source: HEY Research Lab — heyresearch.xyz · https://heyresearch.xyz/project/<slug>
93
+ ```
94
+
95
+ `heyResearchWorker(options)` takes `apiKey`, `baseUrl` (tests and local mocks only: `https:` or
96
+ `http://localhost`), `fetchImpl`, `timeoutMs`, `client`, and `id` / `name` / `description` /
97
+ `getEnvironment` overrides. `heyResearchFunctions(options)` returns the five `GameFunction`s for
98
+ your own worker. The framework-neutral reads (`researchProject`, `findProjects`, `recentChanges`,
99
+ `projectTimeline`, `chainOverview`) are exported too.
100
+
101
+ ## ACP provider (seller) scaffold
102
+
103
+ `@hey-research-lab/virtuals-plugin/acp` lets HEY act as an
104
+ [Agent Commerce Protocol](https://app.virtuals.io/research/agent-commerce-protocol) provider with
105
+ one offering: **"HEY builder research on a Robinhood Chain project/contract"**. A buyer sends
106
+ `{"query": "<slug | $TICKER | name | 0x contract>", "chainId": 4663}`; the seller checks HEY holds
107
+ an answer, proposes the budget, and when the job is funded reads HEY again and submits the
108
+ deliverable: JSON (`hey.virtuals-acp-deliverable/v1`) with the same report text the GAME function
109
+ returns, the project link, HEY's citation and as-of time, and the attribution line. If HEY holds no
110
+ such project, or several match, the job is rejected _before_ any budget, with HEY's answer in the
111
+ message. If HEY cannot be read at delivery, the job is rejected so the funds return.
112
+
113
+ It is built on `@virtuals-protocol/acp-node-v2`. The package named in older guides,
114
+ `@virtuals-protocol/acp-node`, is deprecated on npm in favour of v2, so this scaffold compiles
115
+ against v2 (0.1.15).
116
+
117
+ **It does nothing by default.** Importing it connects to nothing. `startHeyAcpSeller()` throws a
118
+ clear `AcpConfigError` naming every missing variable (never a value) and does not load the ACP SDK
119
+ until all of these are set and `HEY_ACP_ENABLE=1`:
120
+
121
+ | Variable | What | Where it comes from |
122
+ | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
123
+ | `HEY_ACP_WALLET_ADDRESS` | The agent wallet address | Agent page on app.virtuals.io |
124
+ | `HEY_ACP_WALLET_ID` | The agent wallet id (v2's replacement for v1's "session entity key id") | Agent page on app.virtuals.io |
125
+ | `HEY_ACP_SIGNER_PRIVATE_KEY` | The signer key: a Privy authorization key (base64, not an EOA private key) | Agent page → **Signers** → **+ Add Signer** → **Copy Key** |
126
+ | `HEY_ACP_CHAIN_ID` | Settlement chain: `8453` (Base) or `4663` (Robinhood Chain). No default | The founder's decision |
127
+ | `HEY_ACP_PRICE_USDC` | USDC per job; **default `0`**, the lowest value the SDK and registry accept (the SDK's own seller example runs a 0 USDC offering) | **The founder's decision**; set it equal to the offering's price on the registry |
128
+ | `HEY_ACP_OFFERING_NAME` | Defaults to `hey_builder_research`; must equal the offering name on the registry | — |
129
+ | `HEY_ACP_BUILDER_CODE` | Optional Base builder code | Agent page → **Settings** |
130
+ | `HEY_ACP_ENABLE` | `1` to start. Anything else: nothing starts | The founder |
131
+
132
+ ```sh
133
+ pnpm dlx tsx examples/acp-seller.ts # explains what is missing, or checks the config and exits unless HEY_ACP_ENABLE=1
134
+ ```
135
+
136
+ ```ts
137
+ import { startHeyAcpSeller } from '@hey-research-lab/virtuals-plugin/acp';
138
+ const seller = await startHeyAcpSeller(); // reads HEY_ACP_* from the environment
139
+ // … later: await seller.stop();
140
+ ```
141
+
142
+ The building blocks are exported for review and for your own wiring: `loadHeyAcpConfig`,
143
+ `createHeyAcpEntryHandler`, `parseRequirement`, `buildDeliverable`, `HEY_ACP_OFFERING` (name,
144
+ description, requirement JSON Schema, deliverable description, SLA) and the `AcpRuntime` seam.
145
+
146
+ ### Which wallet and chain ACP settles on
147
+
148
+ Facts as the ACP v2 SDK (0.1.15) states them in its own constants; HEY has not independently
149
+ verified any of these contracts:
150
+
151
+ - **Wallet.** Each registered agent has an agent wallet: a Privy server-managed smart account (on
152
+ Alchemy's account infrastructure) created on app.virtuals.io. HEY's process never holds that
153
+ wallet's key; it holds a _signer_ authorization key the founder generates under the agent's
154
+ Signers tab, which lets the SDK ask Privy to sign for the agent wallet. The buyer's payment, in
155
+ USDC, is escrowed by the ACP contract and released to the agent wallet when the job completes.
156
+ - **Chains.** The SDK's mainnets are Base (`8453`), Robinhood Chain (`4663`) and Arc (`5042`), plus
157
+ Solana. On Base and Robinhood Chain the ACP contract is
158
+ `0x238E541BfefD82238730D00a2208E5497F1832E0`; USDC is
159
+ `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` on Base and
160
+ `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` on Robinhood Chain. Both chains are in the SDK's
161
+ ERC-20 gas-sponsored list. This scaffold allows Base or Robinhood Chain and picks neither.
162
+ - **To decide:** the settlement chain (Base is where most ACP buyers already hold USDC; Robinhood
163
+ Chain keeps HEY on the chain it researches), the price, and whether to register at all. Any
164
+ protocol fee is Virtuals' and is not modelled here; check their current terms.
165
+
166
+ A paid job buys delivery of the same public answer anyone can read free on heyresearch.xyz; it
167
+ changes no status, score or order on HEY.
168
+
169
+ ## Listing
170
+
171
+ **GAME (game-node plugins).**
172
+
173
+ 1. Publish this package to npm under `@hey-research-lab` (`npm publish <tarball> --access public`)
174
+ and push the repository to `github.com/hey-research-lab/hey-virtuals-plugin`.
175
+ 2. Fork [game-by-virtuals/game-node](https://github.com/game-by-virtuals/game-node), add
176
+ `plugins/heyResearchPlugin/` with a `README.md` (install, usage, functions, troubleshooting) and
177
+ the [`plugin_metadata.yml`](plugin_metadata.yml) in this repository (filled from their
178
+ template). Plugins there keep their own package names (`tokenmetrics-virtuals-plugin` is one).
179
+ 3. Open a pull request with their plugin PR template and the `plugin` label, with a log of a run.
180
+
181
+ **ACP (Service Registry on app.virtuals.io).**
182
+
183
+ 1. Sign in at [app.virtuals.io](https://app.virtuals.io/acp/new) and register a new agent as a
184
+ provider (seller). Give it HEY's name and description; never imply Robinhood affiliation.
185
+ 2. On the agent's page, note the wallet address and wallet id; under **Signers**, add a signer and
186
+ copy its key; under **Settings**, copy the builder code (optional).
187
+ 3. Add one offering: name `hey_builder_research`; description, requirement schema and deliverable
188
+ from `HEY_ACP_OFFERING`; SLA at least 5 minutes; price as decided; on the settlement chain chosen.
189
+ 4. Set the `HEY_ACP_*` variables on the host that will run the seller (never in the repository), run
190
+ `examples/acp-seller.ts` once without `HEY_ACP_ENABLE` to check them, then with
191
+ `HEY_ACP_ENABLE=1`.
192
+ 5. Test with a separate buyer agent (the SDK requires different wallets) at a 0 or minimal price
193
+ before announcing the offering.
194
+
195
+ ## How it relates to HEY Research Lab
196
+
197
+ It reads HEY's public API through `@hey-research-lab/sdk` and nothing else — no page scraping, no
198
+ provider calls, no key embedded. The `x-hey-integration` header (`hey-virtuals-plugin/<version>`)
199
+ lets HEY count this plugin's calls. HEY's private quality gate stays authoritative: the plugin
200
+ relays what HEY publishes and computes no status, score or verdict of its own.
201
+
202
+ ## What it does NOT prove
203
+
204
+ The plugin relays HEY's public research to an agent. A HEY answer is evidence with provenance:
205
+ activity status is a record of development, not a view on a token, and nothing it returns is
206
+ investment advice, a safety verdict or a recommendation. An unknown value means HEY does not know —
207
+ not zero. A paid ACP job buys delivery of the same public answer anyone can read free; it does not
208
+ make the answer true, current or advice, and it changes nothing on HEY.
209
+
210
+ HEY Research Lab is an independent research project and is not affiliated with, endorsed by or
211
+ partnered with Robinhood Markets, Inc. or Robinhood Chain. It is not affiliated with or endorsed by
212
+ Virtuals Protocol either.
213
+
214
+ ## What it never does
215
+
216
+ - Never says a token is safe, never tells anyone to buy or sell, never predicts a price.
217
+ - Never profiles addresses, never calls them people, never follows one.
218
+ - Never fills an unknown with 0, false or "none".
219
+ - Never claims Robinhood affiliation.
220
+ - Never calls a provider, a write route or `POST /api/scan`; never embeds a key.
221
+ - ACP: never connects, registers or signs without the founder's configuration and
222
+ `HEY_ACP_ENABLE=1`; never logs or stores the signer key.
223
+
224
+ ## Security
225
+
226
+ See [SECURITY.md](SECURITY.md). Network: HTTPS GETs to `https://heyresearch.xyz` only (and, for an
227
+ enabled ACP seller, the ACP SDK's own connections). No files are read or written. Peer dependencies
228
+ beyond the allowed set, with why: `@virtuals-protocol/game` (the framework this plugs into) and,
229
+ optional, `@virtuals-protocol/acp-node-v2` (the ACP client, loaded only when the seller starts).
230
+
231
+ ## Contributing
232
+
233
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Tests run offline over saved fixtures with the network
234
+ blocked and the ACP client stubbed; `pnpm scan` checks for leaked secrets and attribution.
235
+
236
+ ## Links
237
+
238
+ [Site](https://heyresearch.xyz) · [Developers](https://heyresearch.xyz/developers) ·
239
+ [Public API](https://heyresearch.xyz/docs/public-api) · [Agents guide](https://heyresearch.xyz/developers/agents) ·
240
+ [MCP](https://heyresearch.xyz/docs/mcp) · [SDK](https://www.npmjs.com/package/@hey-research-lab/sdk) ·
241
+ [Organisation](https://github.com/hey-research-lab) · [GAME SDK](https://github.com/game-by-virtuals/game-node) ·
242
+ [ACP SDK v2](https://www.npmjs.com/package/@virtuals-protocol/acp-node-v2) · Contact: hi@heyresearch.xyz
243
+
244
+ ## Licence
245
+
246
+ MIT © 2026 HEY Research Lab
package/dist/acp.d.ts ADDED
@@ -0,0 +1,257 @@
1
+ import { FetchLike, HeyClient, HeyAgentResponse } from '@hey-research-lab/sdk';
2
+ import { inspect } from 'node:util';
3
+ import { JobRoomEntry, AssetToken } from '@virtuals-protocol/acp-node-v2';
4
+
5
+ /** How the plugin reaches HEY. Everything is optional: with nothing set it reads the public API anonymously. */
6
+ type HeyPluginOptions = {
7
+ /**
8
+ * A HEY API key from heyresearch.xyz/account. Optional: it lifts the anonymous rate limit and
9
+ * nothing else. Defaults to `HEY_API_KEY` from the environment. Sent as a bearer token, never logged.
10
+ */
11
+ apiKey?: string;
12
+ /**
13
+ * Defaults to https://heyresearch.xyz. Only for tests and local mocks: `https:` or
14
+ * `http://localhost` / `http://127.0.0.1`. It is not a network switch.
15
+ */
16
+ baseUrl?: string;
17
+ /** For tests and exotic runtimes; the global `fetch` by default. */
18
+ fetchImpl?: FetchLike;
19
+ /** Milliseconds before a HEY read is abandoned; the SDK's default is 15 000. */
20
+ timeoutMs?: number;
21
+ /** A ready client, when the host already has one. Overrides the four fields above. */
22
+ client?: HeyClient;
23
+ };
24
+
25
+ /**
26
+ * Settlement chains this scaffold allows. Both are mainnets the ACP v2 SDK
27
+ * (`@virtuals-protocol/acp-node-v2` 0.1.15) lists in `EVM_MAINNET_CHAINS`, with a USDC address
28
+ * and the ACP contract registered. Which one HEY settles on is the founder's decision; there is
29
+ * deliberately no default.
30
+ */
31
+ declare const ACP_SETTLEMENT_CHAINS: {
32
+ readonly 8453: "Base";
33
+ readonly 4663: "Robinhood Chain";
34
+ };
35
+ type AcpSettlementChainId = keyof typeof ACP_SETTLEMENT_CHAINS;
36
+ /**
37
+ * The default price, in USDC per job: 0, the lowest value the ACP v2 SDK and the registry accept
38
+ * (the SDK's own seller example runs a 0 USDC offering). Pricing is the founder's decision: set
39
+ * `HEY_ACP_PRICE_USDC` to the same value as the offering on app.virtuals.io.
40
+ */
41
+ declare const DEFAULT_PRICE_USDC = 0;
42
+ /** A typo guard, not a policy: a price above this is refused as a likely mistake. */
43
+ declare const MAX_PRICE_USDC = 1000;
44
+ declare const DEFAULT_OFFERING_NAME = "hey_builder_research";
45
+ /** Holds a secret so that logging, `JSON.stringify` and `util.inspect` never print it. */
46
+ declare class Secret {
47
+ #private;
48
+ constructor(value: string);
49
+ /** The only way to read the value; called once, when the wallet adapter is built. */
50
+ reveal(): string;
51
+ toString(): string;
52
+ toJSON(): string;
53
+ [inspect.custom](): string;
54
+ }
55
+ type HeyAcpConfig = {
56
+ /** `HEY_ACP_ENABLE=1`. Without it nothing connects, registers or signs. */
57
+ enabled: boolean;
58
+ /** The agent wallet address shown on the agent's page on app.virtuals.io. */
59
+ walletAddress: `0x${string}`;
60
+ /** The agent wallet id shown on the same page. */
61
+ walletId: string;
62
+ /** The signer key from the agent's Signers tab (a Privy authorization key, not an EOA key). */
63
+ signer: Secret;
64
+ settlementChainId: AcpSettlementChainId;
65
+ priceUsdc: number;
66
+ offeringName: string;
67
+ /** Optional Base builder code from the agent's Settings tab. */
68
+ builderCode?: string;
69
+ };
70
+ declare class AcpConfigError extends Error {
71
+ readonly missing: string[];
72
+ readonly invalid: string[];
73
+ readonly code = "acp_not_configured";
74
+ constructor(missing: string[], invalid: string[]);
75
+ }
76
+ type AcpEnv = Record<string, string | undefined>;
77
+ /**
78
+ * Reads and checks the seller's configuration from the environment. Throws one `AcpConfigError`
79
+ * naming every missing or invalid variable, never their values.
80
+ */
81
+ declare function loadHeyAcpConfig(env?: AcpEnv): HeyAcpConfig;
82
+ /** A one-line, secret-free description of the configuration for logs. */
83
+ declare function describeAcpConfig(config: HeyAcpConfig): string;
84
+
85
+ /**
86
+ * What one HEY read produced, before a framework wraps it.
87
+ *
88
+ * - `answer`: HEY answered about a project or the chain.
89
+ * - `not_found` / `ambiguous`: HEY answered that it holds no such project, or several match. These
90
+ * are answers too (a reading of HEY's index), so `ok` is true.
91
+ * - `invalid` / `error`: the request was malformed, refused, or HEY could not be read.
92
+ */
93
+ type HeyOutcome = 'answer' | 'not_found' | 'ambiguous' | 'invalid' | 'error';
94
+ type HeyResult = {
95
+ ok: boolean;
96
+ outcome: HeyOutcome;
97
+ /** The text an agent reads: HEY's semantics kept, ending with the attribution line. */
98
+ text: string;
99
+ projectUrl?: string;
100
+ asOf?: string;
101
+ citation?: HeyAgentResponse['citation'];
102
+ error?: {
103
+ code: string;
104
+ message: string;
105
+ retryable: boolean;
106
+ status?: number;
107
+ retryAfterSeconds?: number;
108
+ requestId?: string;
109
+ };
110
+ };
111
+
112
+ /** What to enter on app.virtuals.io when adding the offering. The price is not here: it is the founder's. */
113
+ declare const HEY_ACP_OFFERING: {
114
+ readonly name: "hey_builder_research";
115
+ readonly description: string;
116
+ readonly requirement: {
117
+ readonly type: "object";
118
+ readonly additionalProperties: false;
119
+ readonly required: readonly ["query"];
120
+ readonly properties: {
121
+ readonly query: {
122
+ readonly type: "string";
123
+ readonly minLength: 2;
124
+ readonly maxLength: 200;
125
+ readonly description: "A HEY project slug, a $TICKER, a project name, or a 0x token/contract address on Robinhood Chain.";
126
+ };
127
+ readonly chainId: {
128
+ readonly type: "integer";
129
+ readonly const: 4663;
130
+ readonly description: "Optional; only 4663 (Robinhood Chain) is supported.";
131
+ };
132
+ };
133
+ };
134
+ readonly deliverable: string;
135
+ /** The registry's floor is 5 minutes (`MIN_SLA_MINS`); a HEY read takes seconds. */
136
+ readonly slaMinutes: 5;
137
+ };
138
+ declare const DELIVERABLE_SCHEMA = "hey.virtuals-acp-deliverable/v1";
139
+ type ParsedRequirement = {
140
+ ok: true;
141
+ query: string;
142
+ } | {
143
+ ok: false;
144
+ code: 'invalid_requirement' | 'unsupported_chain';
145
+ message: string;
146
+ };
147
+ /**
148
+ * A buyer's requirement: `{"query": "...", "chainId": 4663}` as the offering's schema asks, or a
149
+ * bare string. Only `query` and `chainId` are read; anything else is ignored, never merged.
150
+ */
151
+ declare function parseRequirement(content: string): ParsedRequirement;
152
+ /** The deliverable the buyer receives: HEY's report, its link, citation and as-of time, and the attribution. */
153
+ declare function buildDeliverable(query: string, result: HeyResult, deliveredAt: Date): string;
154
+ /**
155
+ * The part of an ACP v2 `JobSession` the seller uses. `JobSession` satisfies it (a type test holds
156
+ * that), and tests pass a stub, so no test ever builds a real session, wallet or connection.
157
+ */
158
+ type AcpSessionLike = {
159
+ readonly jobId: string;
160
+ readonly chainId: number;
161
+ readonly status: string;
162
+ readonly job: {
163
+ readonly description: string;
164
+ } | null;
165
+ readonly entries: readonly JobRoomEntry[];
166
+ setBudget(amount: AssetToken): Promise<void>;
167
+ submit(deliverable: string): Promise<void>;
168
+ reject(reason: string): Promise<void>;
169
+ sendMessage(content: string): Promise<void>;
170
+ };
171
+ type HeyAcpHandlerDeps = {
172
+ offeringName: string;
173
+ priceUsdc: number;
174
+ /** `AssetToken.usdc` from the ACP SDK; injected so tests never load it. */
175
+ usdc: (amount: number, chainId: number) => AssetToken;
176
+ /** The HEY read that answers a job (the same `researchProject` the GAME worker uses). */
177
+ research: (query: string) => Promise<HeyResult>;
178
+ log?: (message: string) => void;
179
+ now?: () => Date;
180
+ };
181
+ /**
182
+ * The seller's state machine, after the ACP v2 seller example:
183
+ *
184
+ * requirement message (status open) → check offering, chain and that HEY holds an answer,
185
+ * then `setBudget` (or `reject` before anything is paid)
186
+ * job.funded → read HEY again and `submit` the deliverable
187
+ * (or `reject`, which returns the funds, if HEY is unreachable)
188
+ * job.completed / rejected / expired → log only
189
+ *
190
+ * The requirement is read back from the session's own history at `job.funded`, so a restarted
191
+ * seller resumes a funded job without any state of its own.
192
+ */
193
+ declare function createHeyAcpEntryHandler(deps: HeyAcpHandlerDeps): (session: AcpSessionLike, entry: JobRoomEntry) => Promise<void>;
194
+
195
+ /** The part of an ACP v2 `AcpAgent` the seller uses; `AcpAgent` satisfies it (a type test holds that). */
196
+ type AcpAgentLike = {
197
+ on(event: 'entry', handler: (session: AcpSessionLike, entry: JobRoomEntry) => void | Promise<void>): unknown;
198
+ start(onConnected?: () => void): Promise<void>;
199
+ stop(): Promise<void>;
200
+ getAddress(): Promise<string>;
201
+ };
202
+ type CreateAcpAgentInput = {
203
+ walletAddress: `0x${string}`;
204
+ walletId: string;
205
+ signer: Secret;
206
+ chainId: AcpSettlementChainId;
207
+ builderCode?: string;
208
+ };
209
+ /**
210
+ * Everything the seller needs from the ACP SDK, behind one seam: building the agent (the only step
211
+ * that touches the wallet) and making a USDC amount. Tests replace it entirely.
212
+ */
213
+ type AcpRuntime = {
214
+ createAgent(input: CreateAcpAgentInput): Promise<AcpAgentLike>;
215
+ usdc(amount: number, chainId: number): AssetToken;
216
+ };
217
+ declare class AcpSdkMissingError extends Error {
218
+ readonly code = "acp_sdk_missing";
219
+ constructor();
220
+ }
221
+ /**
222
+ * Loads `@virtuals-protocol/acp-node-v2` on first use (never at import time) and adapts it to
223
+ * `AcpRuntime`: a Privy-managed agent wallet through `PrivyAlchemyEvmProviderAdapter`, on the one
224
+ * settlement chain configured, and `AcpAgent.create({ evmProvider })`.
225
+ */
226
+ declare function loadAcpRuntime(): Promise<AcpRuntime>;
227
+
228
+ /**
229
+ * `@hey-research-lab/virtuals-plugin/acp`: HEY as an Agent Commerce Protocol provider (seller)
230
+ * offering one service, "HEY builder research on a Robinhood Chain project/contract".
231
+ *
232
+ * A scaffold the founder switches on: nothing here connects, registers or signs until
233
+ * `startHeyAcpSeller` runs with a complete configuration and `HEY_ACP_ENABLE=1`.
234
+ */
235
+
236
+ type StartHeyAcpSellerOptions = HeyPluginOptions & {
237
+ /** A checked configuration; read from `env` (default `process.env`) when absent. */
238
+ config?: HeyAcpConfig;
239
+ env?: AcpEnv;
240
+ /** The ACP SDK seam; `loadAcpRuntime()` by default. Tests pass a stub. */
241
+ runtime?: AcpRuntime;
242
+ /** Where progress lines go; never receives a secret. `console.log` by default. */
243
+ log?: (message: string) => void;
244
+ now?: () => Date;
245
+ };
246
+ type HeyAcpSeller = {
247
+ agent: AcpAgentLike;
248
+ config: HeyAcpConfig;
249
+ stop(): Promise<void>;
250
+ };
251
+ /**
252
+ * Builds the agent wallet adapter, registers the HEY entry handler and starts listening for jobs.
253
+ * Refuses, before loading the ACP SDK, when the configuration is incomplete or not enabled.
254
+ */
255
+ declare function startHeyAcpSeller(options?: StartHeyAcpSellerOptions): Promise<HeyAcpSeller>;
256
+
257
+ export { ACP_SETTLEMENT_CHAINS, type AcpAgentLike, AcpConfigError, type AcpEnv, type AcpRuntime, AcpSdkMissingError, type AcpSessionLike, type AcpSettlementChainId, type CreateAcpAgentInput, DEFAULT_OFFERING_NAME, DEFAULT_PRICE_USDC, DELIVERABLE_SCHEMA, HEY_ACP_OFFERING, type HeyAcpConfig, type HeyAcpHandlerDeps, type HeyAcpSeller, MAX_PRICE_USDC, type ParsedRequirement, Secret, type StartHeyAcpSellerOptions, buildDeliverable, createHeyAcpEntryHandler, describeAcpConfig, loadAcpRuntime, loadHeyAcpConfig, parseRequirement, startHeyAcpSeller };