web3agent 0.1.0 → 0.2.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/README.md CHANGED
@@ -24,14 +24,113 @@ npx web3agent --help
24
24
  npx web3agent --version
25
25
  ```
26
26
 
27
+ ## Programmatic Usage
28
+
29
+ ### Root API
30
+
31
+ Use the package root when you want stable, typed Web3 capabilities from another app or agent layer.
32
+
33
+ ```js
34
+ import { getChain, listChainTokens, resolveCanonicalTokenSync, resolveToken } from "web3agent";
35
+
36
+ const chain = getChain(8453);
37
+ const usdc = resolveCanonicalTokenSync({ symbol: "USDC", chainId: 8453 });
38
+ const tokens = listChainTokens({ chainId: 8453 });
39
+ const discovered = await resolveToken({ symbol: "DEGEN", chainId: 8453 });
40
+
41
+ console.log(chain?.name, usdc?.address, discovered.address, tokens.tokens.length);
42
+ ```
43
+
44
+ Use `resolveCanonicalToken()` / `resolveCanonicalTokenSync()` when you only want well-known registry tokens and native-token aliases. Use `resolveToken()` when you want registry resolution plus DexScreener discovery fallback for long-tail assets.
45
+
46
+ Root API helpers lazily create a shared default runtime under the hood. Long-lived processes can import `shutdownDefaultRuntime` from `web3agent/runtime` to release those resources when finished.
47
+
48
+ ### Browser Wallet Flows
49
+
50
+ Use the root package API when your app owns the signer, for example a browser wallet connected through wagmi or AppKit.
51
+
52
+ ```js
53
+ import { prepareOperation, resumeOperation, simulateTransaction } from "web3agent";
54
+ ```
55
+
56
+ The primary flow is generic:
57
+
58
+ 1. `prepareOperation(...)` returns the next wallet actions plus `resumeState`
59
+ 2. Your app executes those actions with the browser wallet
60
+ 3. `resumeOperation(...)` continues until the operation completes
61
+
62
+ Protocol-specific helpers like `prepareSwapIntent()` and `submitSignedSwap()` remain available as compatibility wrappers, but new integrations should target the generic prepared-operation API first.
63
+
64
+ Prepared browser-wallet flows are staged. `prepareOperation()` and `resumeOperation()` only return the next required actions, and `resumeOperation()` persists previously completed action results inside the opaque resume state so callers only need to submit newly finished actions on each round.
65
+
66
+ Transaction actions are only considered complete once the caller returns a confirmed result:
67
+
68
+ ```js
69
+ { type: "transaction", txHash: "0x...", status: "confirmed" }
70
+ ```
71
+
72
+ `resumeOperation()` independently verifies the receipt before advancing to the next stage.
73
+
74
+ For LI.FI compatibility helpers, `prepareBridgeIntent()` now returns both `steps` and `actions` as the transaction-only sequence for browser wallets, including any required approval transactions before the bridge call. Use `prepareOperation()` with `integration: "lifi"` when you need the staged external-wallet flow with typed-data signing.
75
+
76
+ `simulateTransaction()` returns a success payload on successful simulation and throws structured `Web3AgentError` failures for invalid inputs, reverts, or RPC errors. When `debug_traceCall` is unavailable, balance changes come from a best-effort fallback decoder.
77
+
78
+ Architecture notes live in [docs/architecture/browser-wallet-operations.md](./docs/architecture/browser-wallet-operations.md).
79
+
80
+ ### Runtime API
81
+
82
+ Use `web3agent/runtime` when you need tool discovery, generic invocation, wallet flows, or upstream passthrough tools.
83
+
84
+ ```js
85
+ import { createRuntime } from "web3agent/runtime";
86
+
87
+ const runtime = await createRuntime();
88
+
89
+ try {
90
+ console.log(runtime.getHealth());
91
+ console.log(runtime.listTools().slice(0, 5).map((tool) => tool.name));
92
+ const result = await runtime.invokeTool("list_supported_chains");
93
+ console.log(result.structuredContent);
94
+ } finally {
95
+ await runtime.shutdown();
96
+ }
97
+ ```
98
+
99
+ ## Smoke Tests
100
+
101
+ Run the standard repo checks first:
102
+
103
+ ```bash
104
+ pnpm lint
105
+ pnpm typecheck
106
+ pnpm test
107
+ pnpm build
108
+ ```
109
+
110
+ Then run the packaged API smoke scripts:
111
+
112
+ ```bash
113
+ node examples/root-api-smoke.mjs
114
+ node examples/runtime-smoke.mjs
115
+ node examples/runtime-smoke.mjs --run
116
+ ```
117
+
118
+ `root-api-smoke.mjs` is fully local. `runtime-smoke.mjs` without flags verifies the runtime import surface only. `runtime-smoke.mjs --run` starts the real runtime in read-only mode, so upstream services may appear as degraded or fail if network access is unavailable.
119
+
120
+ The env-gated browser-wallet e2e test in [`tests/e2e/browser-wallet-flow.test.ts`](tests/e2e/browser-wallet-flow.test.ts) runs when these variables are present: `BROWSER_WALLET_E2E`, `BROWSER_WALLET_E2E_CHAIN_ID`, `BROWSER_WALLET_E2E_ACCOUNT`, `BROWSER_WALLET_E2E_FROM_TOKEN`, `BROWSER_WALLET_E2E_TO_TOKEN`, `BROWSER_WALLET_E2E_IN_AMOUNT`, and `BROWSER_WALLET_E2E_SIGNATURE`.
121
+
27
122
  ## What you get
28
123
 
29
- - **Blockscout** — indexed blockchain data (address info, tx history, NFTs, contract ABIs)
30
- - **EVM MCP** — live on-chain state (balances, contract reads, gas, ENS)
31
- - **GOAT plugins** — Uniswap, Balancer, ERC-20/721, DexScreener
32
- - **LI.FI** — cross-chain bridging and swaps
124
+ - **Blockscout** — indexed blockchain data (address info, tx history, NFTs, contract ABIs). Supported on 8 chains: Ethereum, Polygon, Arbitrum, Optimism, Base, Gnosis, Scroll, zkSync Era.
125
+ - **Etherscan** — contract ABI fetching (requires `ETHERSCAN_API_KEY`)
126
+ - **EVM MCP** — live on-chain state (balances, contract reads/writes, gas, ENS, multicall)
127
+ - **GOAT plugins** — Uniswap, Balancer, ERC-20/721, ENS, DexScreener
128
+ - **Optional GOAT plugins** — 0x (requires `ZEROX_API_KEY`), CoinGecko (requires `COINGECKO_API_KEY`)
129
+ - **LI.FI** — cross-chain bridging and swaps across 20+ chains
33
130
  - **Orbs** — Liquidity Hub aggregated swaps, dTWAP, dLIMIT orders
34
- - **Wallet management** — generate, persist, derive addresses
131
+ - **Token resolver** — symbol-to-address resolution with built-in registry and DexScreener fallback
132
+ - **Wallet management** — generate, persist, activate/deactivate, derive addresses, sign messages
133
+ - **Confirmation queue** — write operations require explicit confirmation by default
35
134
 
36
135
  ## Supported Hosts
37
136
 
@@ -52,9 +151,16 @@ Default: **Base (8453)**. Override with `CHAIN_ID` env var or `chainId` paramete
52
151
 
53
152
  See [WEB3_CONTEXT.md](./WEB3_CONTEXT.md) for the full environment variable table.
54
153
 
154
+ ## Known Limitations
155
+
156
+ - **Blockscout** tools only work on 8 chains (Ethereum, Polygon, Arbitrum, Optimism, Base, Gnosis, Scroll, zkSync Era)
157
+ - **dSLTP** (stop-loss/take-profit orders) is not yet available
158
+ - **0x** and **CoinGecko** plugins require their respective API keys
159
+ - **Browser wallet signing over MCP** is indirect: MCP can prepare, simulate, and submit signed payloads, but generic MCP hosts cannot open a browser wallet prompt on their own
160
+
55
161
  ## Requirements
56
162
 
57
- - Node.js 18+
163
+ - Node.js 22+
58
164
  - pnpm (for development)
59
165
 
60
166
  ## License
package/WEB3_CONTEXT.md CHANGED
@@ -18,11 +18,20 @@ Live on-chain state: current balances, contract reads, gas estimation, ENS resol
18
18
  - `wallet_from_mnemonic` — derive address from mnemonic
19
19
  - `wallet_derive_addresses` — batch derive 1-20 addresses
20
20
  - `wallet_get_active` — get current wallet address, chain, mode
21
+ - `wallet_activate` — activate wallet from private key or mnemonic, persists to disk (mode 0600)
22
+ - `wallet_deactivate` — deactivate current wallet, delete key file, revert to read-only
23
+ - `wallet_set_confirmation` — toggle write confirmation at runtime (enabled/disabled)
21
24
 
22
25
  ### Transaction management
23
26
  - `transaction_confirm(id)` — execute a queued write operation
24
27
  - `transaction_deny(id)` — discard a queued operation
25
28
  - `transaction_list()` — list pending operations
29
+ - `transaction_simulate()` — simulate an unsigned transaction, estimate gas, and preview balance changes
30
+
31
+ ### Browser-wallet operations
32
+ - `operation_prepare` — prepare the next external-wallet actions plus opaque `resumeState`
33
+ - `operation_resume` — continue a prepared operation after signatures or transactions complete externally
34
+ - These are the primary MCP tools for browser-wallet flows across Orbs, LI.FI, and GOAT
26
35
 
27
36
  ### DeFi tools
28
37
 
@@ -35,18 +44,78 @@ Live on-chain state: current balances, contract reads, gas estimation, ENS resol
35
44
  - `lifi_get_chains` — list supported chains
36
45
  - `lifi_get_quote` — get bridge/swap quote
37
46
  - `lifi_execute_bridge` — execute cross-chain bridge (write, confirmation-gated)
47
+ - `lifi_prepare_bridge_intent` — prepare raw bridge transaction steps for an external wallet (read-only)
48
+ Compatibility note: `operation_prepare` / `operation_resume` are the preferred generic MCP flow
38
49
 
39
50
  **Orbs DeFi** (prefix: `orbs_`):
40
51
  - `orbs_get_quote` — Liquidity Hub aggregated swap quote (chains: 137, 56, 8453, 59144, 81457, 42161)
41
52
  - `orbs_swap` — execute swap (write, confirmation-gated)
53
+ - `orbs_prepare_swap_intent` — prepare swap quote + EIP-712 payload for an external wallet (read-only)
54
+ - `orbs_get_required_approvals` — check wrap / Permit2 approval steps before signing (read-only)
55
+ - `orbs_swap_status` — check status of a pending Liquidity Hub swap (takes chainId, sessionId, user)
42
56
  - `orbs_place_twap` — place dTWAP order (write, confirmation-gated)
57
+ - `orbs_prepare_twap_intent` — prepare dTWAP order data for an external wallet (read-only)
43
58
  - `orbs_place_limit` — place dLIMIT order (write, confirmation-gated)
59
+ - `orbs_prepare_limit_intent` — prepare dLIMIT order data for an external wallet (read-only)
60
+ - `orbs_submit_signed_swap` — submit an externally signed Orbs swap (write)
61
+ - `orbs_submit_signed_twap_order` — submit an externally signed dTWAP or dLIMIT order (write)
44
62
  - `orbs_list_orders` — list open TWAP/dLIMIT orders
63
+ Compatibility note: these remain supported, but `operation_prepare` / `operation_resume` are the generic-first browser-wallet flow
64
+
65
+ ### Browser-wallet limitation
66
+ The browser-wallet tools are MCP-compatible, but generic MCP hosts cannot trigger browser wallet popups themselves. Use MCP to prepare, simulate, and resume operations; perform the actual wallet signing in the surrounding app or host integration.
67
+
68
+ ### Token resolution (prefix: none)
69
+ - `resolve_token(symbol, chainId)` — resolve token symbol to contract address and decimals. Uses built-in registry with DexScreener fallback. ALWAYS use this before swaps/bridges.
70
+ - `list_chain_tokens(chainId)` — list all well-known tokens for a chain from the built-in registry
45
71
 
46
72
  ### Utilities
47
73
  - `server_status` — wallet mode, active chain, confirmation setting, backend health
48
74
  - `list_supported_chains` — all 17 supported chains with IDs and names
49
75
 
76
+ ### Agentic Economy — x402 Payments (prefix: `x402_`)
77
+ HTTP-native stablecoin payments for AI agent services. Use `x402_check_requirements` first to preview cost, then `x402_fetch` to execute.
78
+ - `x402_check_requirements` — probe a URL for payment requirements (amount, token, network). Returns null if no payment needed. (read-only)
79
+ - `x402_fetch` — fetch a URL with automatic x402 payment. Shows cost in confirmation before paying. (write, confirmation-gated)
80
+
81
+ ### Agentic Economy — Job Escrow / ERC-8183 (prefix: `erc8183_`)
82
+ EIP-8183 specification reference implementation (no canonical deployed contract). Job flow: create → setBudget → fund → submit → complete/reject. Expired jobs support `erc8183_claim_refund`. Distinct from `acp_*` tools which target the Virtuals production ACPRouter on Base.
83
+ - `erc8183_create_job` — create a new job specifying provider, evaluator, description, and expiry duration (write)
84
+ - `erc8183_set_budget` — set the budget for a job (write)
85
+ - `erc8183_fund_job` — approve token allowance + fund job escrow in one confirmation (write)
86
+ - `erc8183_submit_job` — submit a deliverable (string, gets keccak256-hashed on-chain) (write)
87
+ - `erc8183_complete_job` — mark job complete, release payment to provider (write)
88
+ - `erc8183_reject_job` — reject submitted deliverable, funds remain in escrow (write)
89
+ - `erc8183_claim_refund` — reclaim escrowed funds after job expiry (write)
90
+ - `erc8183_get_job` — read current job state: client, provider, budget, status, deliverable (read-only)
91
+
92
+ ### Agentic Economy — Virtuals ACP / ACPRouter (prefix: `acp_`)
93
+ On-chain job lifecycle on the Virtuals ACPRouter V2 (Base mainnet and Base Sepolia). Uses a memo-based protocol: jobs progress through phases (Request → Negotiation → Transaction → Evaluation → Completed/Rejected) via memos that participants create and sign. No `ACP_CONTRACT_ADDRESS` env var needed — canonical addresses are hardcoded.
94
+ - `acp_create_job` — create a job specifying provider, evaluator, description, expiry, and optional budget (write)
95
+ - `acp_set_budget` — set or update job budget with payment token (write)
96
+ - `acp_fund_job` — approve token allowance + fund job via payable escrow memo (write)
97
+ - `acp_submit_job` — submit deliverable as a memo, advancing job to evaluation phase (write)
98
+ - `acp_complete_job` — approve the latest pending memo (auto-resolved), completing the job (write)
99
+ - `acp_reject_job` — reject the latest pending memo (auto-resolved), rejecting the deliverable (write)
100
+ - `acp_claim_refund` — claim escrowed budget after job completion or expiry (write)
101
+ - `acp_get_job` — read job state with full memo history, phase, participants, and pending actions (read-only)
102
+
103
+ ### Agentic Economy — Agent Marketplace / aGDP (prefix: `agdp_`)
104
+ Discover and hire agents on the Virtuals Protocol aGDP marketplace (`acpx.virtuals.io`). No wallet required for discovery.
105
+ - `agdp_get_offerings` — search agent marketplace by query string; returns name, wallet, offerings, metrics (read-only)
106
+ - `agdp_get_offering` — get details of a specific agent by ID (read-only)
107
+ - `agdp_get_my_jobs` — list active or completed jobs for the current wallet (read-only)
108
+ - `agdp_hire_agent` — hire an agent via aGDP API (write, confirmation-gated). For on-chain job creation, use `acp_create_job` separately.
109
+ - `agdp_create_offering` — register an agent offering on aGDP. Requires `LITE_AGENT_API_KEY` from Virtuals — visit agdp.io/join to register.
110
+
111
+ ### Agentic Economy — Agent Identity / ERC-8004 (prefix: `erc8004_`)
112
+ On-chain agent identity (ERC-721) and reputation registry. Canonical contracts deployed on Base and Base Sepolia. Requires IPFS hosting or `PINATA_JWT` for registration JSON.
113
+ - `erc8004_register_agent` — register agent on-chain: checks for duplicate, validates JSON, pins to IPFS via Pinata or uses provided `agentURI` (write, confirmation-gated)
114
+ - `erc8004_get_agent` — get agent info by agentId or wallet address (read-only)
115
+ - `erc8004_update_agent` — update agent registration URI on-chain (write, confirmation-gated)
116
+ - `erc8004_submit_feedback` — submit reputation feedback (-100 to +100) for an agent (write, confirmation-gated)
117
+ - `erc8004_get_feedback` — get aggregated reputation summary for an agent (read-only)
118
+
50
119
  ## Chain Selection
51
120
  Default chain: **Base (8453)**. Override per-call with `chainId` parameter.
52
121
 
@@ -89,3 +158,13 @@ Write operations (swaps, bridges, transfers) are queued by default. Use `transac
89
158
  | `LIFI_API_KEY` | — | LI.Fi API key |
90
159
  | `ZEROX_API_KEY` | — | 0x API key (enables 0x plugin) |
91
160
  | `COINGECKO_API_KEY` | — | CoinGecko API key (enables CoinGecko plugin) |
161
+ | `ACP_PAYMENT_TOKEN` | — | ERC-20 token address for ACP escrow (defaults to USDC on active chain) |
162
+ | `PINATA_JWT` | — | Pinata JWT for auto-pinning ERC-8004 agent registration JSON to IPFS |
163
+ | `ERC8004_AGENT_URI` | — | Advertised MCP endpoint URI for ERC-8004 agent registration |
164
+ | `AGDP_API_URL` | https://acpx.virtuals.io/api | aGDP marketplace API base URL |
165
+
166
+ ## Known Limitations
167
+
168
+ - **Blockscout chain coverage**: Blockscout hosted instances support only 8 chains (Ethereum, Polygon, Arbitrum, Optimism, Base, Gnosis, Scroll, zkSync Era). Other chains (BSC, Linea, Avalanche, Blast, Mantle, Mode) are NOT supported by Blockscout tools.
169
+ - **dSLTP (Stop Loss/Take Profit)**: Not yet available. Feature-gated for future release.
170
+ - **CoinGecko and 0x plugins**: Require API keys (`COINGECKO_API_KEY`, `ZEROX_API_KEY`) to activate.
@@ -0,0 +1,65 @@
1
+ declare const AGDP_DEFAULT_URL = "https://acpx.virtuals.io/api";
2
+ interface AgdpOffering {
3
+ id: number;
4
+ name: string;
5
+ description: string;
6
+ price: number;
7
+ type: string;
8
+ requiredFunds: boolean;
9
+ slaMinutes: number;
10
+ }
11
+ interface AgdpAgent {
12
+ id: number;
13
+ name: string;
14
+ description: string;
15
+ walletAddress: string;
16
+ contractAddress: string;
17
+ metrics: {
18
+ successRate: number | null;
19
+ isOnline: boolean;
20
+ };
21
+ jobs: AgdpOffering[];
22
+ }
23
+ interface AgdpJob {
24
+ id: number;
25
+ phase: string;
26
+ providerName: string;
27
+ providerWalletAddress: string;
28
+ clientWalletAddress: string;
29
+ deliverable: string;
30
+ memos: Array<{
31
+ nextPhase: string;
32
+ content: string;
33
+ createdAt: string;
34
+ }>;
35
+ }
36
+ interface AgdpJobResponse {
37
+ id: number;
38
+ phase: string;
39
+ providerName: string;
40
+ [key: string]: unknown;
41
+ }
42
+ declare function getAgdpBaseUrl(): string;
43
+ declare function searchOfferings(params: {
44
+ query?: string;
45
+ topK?: number;
46
+ }): Promise<AgdpAgent[]>;
47
+ declare function getOfferingById(offeringId: number | string, cachedAgents?: AgdpAgent[]): Promise<AgdpAgent | null>;
48
+ declare function getJobs(params: {
49
+ walletAddress: string;
50
+ status?: "active" | "completed";
51
+ }): Promise<AgdpJob[]>;
52
+ declare function createJobViaApi(params: {
53
+ providerWalletAddress: string;
54
+ jobOfferingName: string;
55
+ serviceRequirements?: Record<string, unknown>;
56
+ }): Promise<AgdpJobResponse>;
57
+ declare function createOfferingViaApi(_params: {
58
+ name: string;
59
+ description: string;
60
+ price: number;
61
+ category?: string;
62
+ walletAddress: string;
63
+ }): Promise<unknown>;
64
+
65
+ export { AGDP_DEFAULT_URL, type AgdpAgent, type AgdpJob, type AgdpJobResponse, type AgdpOffering, createJobViaApi, createOfferingViaApi, getAgdpBaseUrl, getJobs, getOfferingById, searchOfferings };
@@ -0,0 +1,19 @@
1
+ import {
2
+ AGDP_DEFAULT_URL,
3
+ createJobViaApi,
4
+ createOfferingViaApi,
5
+ getAgdpBaseUrl,
6
+ getJobs,
7
+ getOfferingById,
8
+ searchOfferings
9
+ } from "../chunk-ETI3ZR2C.js";
10
+ import "../chunk-7QEKU2RP.js";
11
+ export {
12
+ AGDP_DEFAULT_URL,
13
+ createJobViaApi,
14
+ createOfferingViaApi,
15
+ getAgdpBaseUrl,
16
+ getJobs,
17
+ getOfferingById,
18
+ searchOfferings
19
+ };
@@ -0,0 +1,63 @@
1
+ import {
2
+ getActiveAccount,
3
+ getTransportForChain
4
+ } from "./chunk-KPRIUALX.js";
5
+ import {
6
+ getChainById
7
+ } from "./chunk-7QEKU2RP.js";
8
+
9
+ // src/x402/client.ts
10
+ import { decodePaymentRequiredHeader } from "@x402/core/http";
11
+ import { ExactEvmScheme, toClientEvmSigner } from "@x402/evm";
12
+ import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
13
+ import { createPublicClient, createWalletClient, publicActions } from "viem";
14
+ function createX402Client(chainId) {
15
+ const chain = getChainById(chainId);
16
+ if (!chain) {
17
+ throw new Error(`[x402] Unsupported chain ID: ${chainId}`);
18
+ }
19
+ const transport = getTransportForChain(chainId);
20
+ const publicClient = createPublicClient({ chain, transport });
21
+ const account = getActiveAccount();
22
+ const walletClient = createWalletClient({ account, chain, transport }).extend(publicActions);
23
+ const localAccount = walletClient.account ?? account;
24
+ const signer = toClientEvmSigner(localAccount, publicClient);
25
+ const scheme = new ExactEvmScheme(signer);
26
+ const client = new x402Client().register("eip155:*", scheme);
27
+ const fetchWithPayment = wrapFetchWithPayment(globalThis.fetch, client);
28
+ return { client, fetchWithPayment };
29
+ }
30
+ async function probePaymentRequirements(url, method = "GET", headers = {}, body) {
31
+ const response = await globalThis.fetch(url, {
32
+ method,
33
+ headers,
34
+ body: body ?? void 0
35
+ });
36
+ if (response.status !== 402) {
37
+ return { requirements: null, probeResponse: response };
38
+ }
39
+ const headerValue = response.headers.get("PAYMENT-REQUIRED");
40
+ if (headerValue) {
41
+ try {
42
+ return { requirements: decodePaymentRequiredHeader(headerValue), probeResponse: response };
43
+ } catch (err) {
44
+ process.stderr.write(`[x402] Failed to decode PAYMENT-REQUIRED header: ${err}
45
+ `);
46
+ }
47
+ }
48
+ try {
49
+ const text = await response.text();
50
+ if (text) {
51
+ return { requirements: JSON.parse(text), probeResponse: response };
52
+ }
53
+ } catch (err) {
54
+ process.stderr.write(`[x402] Failed to parse 402 response body from ${url}: ${err}
55
+ `);
56
+ }
57
+ return { requirements: null, probeResponse: response };
58
+ }
59
+
60
+ export {
61
+ createX402Client,
62
+ probePaymentRequirements
63
+ };
@@ -0,0 +1,26 @@
1
+ import {
2
+ createRuntime
3
+ } from "./chunk-B4LSSN7C.js";
4
+
5
+ // src/runtime/default.ts
6
+ var defaultRuntimePromise;
7
+ function getDefaultRuntime() {
8
+ if (!defaultRuntimePromise) {
9
+ defaultRuntimePromise = createRuntime();
10
+ }
11
+ return defaultRuntimePromise;
12
+ }
13
+ async function shutdownDefaultRuntime() {
14
+ if (!defaultRuntimePromise) {
15
+ return;
16
+ }
17
+ const runtimePromise = defaultRuntimePromise;
18
+ defaultRuntimePromise = void 0;
19
+ const runtime = await runtimePromise;
20
+ await runtime.shutdown();
21
+ }
22
+
23
+ export {
24
+ getDefaultRuntime,
25
+ shutdownDefaultRuntime
26
+ };
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env node
2
-
3
1
  // src/chains/registry.ts
4
2
  import * as viemChains from "viem/chains";
5
3
  var CHAINS_BY_ID = /* @__PURE__ */ new Map();
@@ -14,6 +12,14 @@ for (const value of Object.values(viemChains)) {
14
12
  function getChainById(id) {
15
13
  return CHAINS_BY_ID.get(id);
16
14
  }
15
+ function getRequiredChain(chainId) {
16
+ const chain = getChainById(chainId);
17
+ if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);
18
+ return chain;
19
+ }
20
+ function getChainByName(name) {
21
+ return CHAINS_BY_NAME.get(name.toLowerCase());
22
+ }
17
23
  function isSupported(id) {
18
24
  return CHAINS_BY_ID.has(id);
19
25
  }
@@ -75,33 +81,59 @@ function parseEnv(env = {}) {
75
81
  rpcUrl: env.RPC_URL || void 0,
76
82
  chainRpcUrls: parseChainRpcUrls(env),
77
83
  confirmWrites: parseBoolean(env.CONFIRM_WRITES, true),
84
+ confirmTtlMinutes: parseIntStrict("CONFIRM_TTL_MINUTES", env.CONFIRM_TTL_MINUTES, 30),
78
85
  blockscoutMcpUrl: env.BLOCKSCOUT_MCP_URL || BLOCKSCOUT_DEFAULT_URL,
79
86
  etherscanMcpUrl: env.ETHERSCAN_MCP_URL || ETHERSCAN_DEFAULT_URL,
80
87
  etherscanApiKey: env.ETHERSCAN_API_KEY || void 0,
81
88
  lifiApiKey: env.LIFI_API_KEY || void 0,
82
89
  zeroxApiKey: env.ZEROX_API_KEY || void 0,
83
90
  coingeckoApiKey: env.COINGECKO_API_KEY || void 0,
84
- orbsPartner: env.ORBS_PARTNER || void 0
91
+ orbsPartner: env.ORBS_PARTNER || void 0,
92
+ acpContractAddress: env.ACP_CONTRACT_ADDRESS || void 0,
93
+ acpPaymentToken: env.ACP_PAYMENT_TOKEN || void 0,
94
+ pinataJwt: env.PINATA_JWT || void 0,
95
+ erc8004AgentUri: env.ERC8004_AGENT_URI || void 0,
96
+ agdpApiUrl: env.AGDP_API_URL || "https://acpx.virtuals.io/api"
85
97
  };
86
98
  }
87
99
  var cached;
88
100
  function setConfig(config) {
89
101
  cached = config;
90
102
  }
103
+ function resetConfig() {
104
+ cached = void 0;
105
+ }
91
106
  function getConfig() {
92
107
  if (!cached) {
93
108
  throw new Error("Config not initialized \u2014 call setConfig() during startup");
94
109
  }
95
110
  return cached;
96
111
  }
112
+ function tryGetConfig() {
113
+ return cached;
114
+ }
115
+ async function withConfig(config, fn) {
116
+ const previous = cached;
117
+ cached = config;
118
+ try {
119
+ return await fn();
120
+ } finally {
121
+ cached = previous;
122
+ }
123
+ }
97
124
 
98
125
  export {
99
126
  getChainById,
127
+ getRequiredChain,
128
+ getChainByName,
100
129
  isSupported,
101
130
  BLOCKSCOUT_DEFAULT_URL,
102
131
  ETHERSCAN_DEFAULT_URL,
103
132
  ValidationError,
104
133
  parseEnv,
105
134
  setConfig,
106
- getConfig
135
+ resetConfig,
136
+ getConfig,
137
+ tryGetConfig,
138
+ withConfig
107
139
  };