From 3d34ae41c81bfd20fb78b9f73231e226fddb77ab Mon Sep 17 00:00:00 2001 From: FilipBl4gojevic <84703395+FilipBl4gojevic@users.noreply.github.com> Date: Mon, 27 Jul 2026 12:47:49 +0200 Subject: [PATCH] Agent-facing strings: AP3X terminology, working Koios default, vocabulary cleanup - ADA -> AP3X in tool/param descriptions, outputs, and safety messages - default testnet Koios URL -> v2 endpoint (old default returns 503) - self-improvement descriptions: improvement proposals / proposal metrics - em dashes -> hyphens in strings and comments No logic changes; code identifiers and protocol field names untouched. Co-Authored-By: Claude Fable 5 --- .env.example | 2 +- src/index.ts | 4 +- src/vector/agent-network.ts | 24 +++---- src/vector/ogmios-provider.ts | 4 +- src/vector/safety.ts | 8 +-- src/vector/self-improvement.ts | 40 ++++++------ src/vector/vector.ts | 112 ++++++++++++++++----------------- 7 files changed, 97 insertions(+), 97 deletions(-) diff --git a/.env.example b/.env.example index ba6753c..f9cfa5e 100644 --- a/.env.example +++ b/.env.example @@ -3,7 +3,7 @@ # Vector Network Endpoints VECTOR_OGMIOS_URL=https://ogmios.vector.testnet.apexfusion.org -VECTOR_KOIOS_URL=https://koios.vector.testnet.apexfusion.org/ +VECTOR_KOIOS_URL=https://v2.koios.vector.testnet.apexfusion.org/ VECTOR_SUBMIT_URL=https://submit.vector.testnet.apexfusion.org/api/submit/tx VECTOR_EXPLORER_URL=https://vector.testnet.apexscan.org diff --git a/src/index.ts b/src/index.ts index 4672939..16205c3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,14 +13,14 @@ const envPath = resolve(__dirname, '../.env'); console.error('Looking for .env file at:', envPath); console.error('.env file exists:', existsSync(envPath)); -// Load environment variables (non-fatal if missing — env vars can be passed directly) +// Load environment variables (non-fatal if missing - env vars can be passed directly) if (existsSync(envPath)) { const result = config({ path: envPath }); if (result.error) { console.error('Warning: Error loading .env file:', result.error); } } else { - console.error('No .env file found — using environment variables directly'); + console.error('No .env file found - using environment variables directly'); } import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; diff --git a/src/vector/agent-network.ts b/src/vector/agent-network.ts index b3cf253..90981ac 100644 --- a/src/vector/agent-network.ts +++ b/src/vector/agent-network.ts @@ -11,10 +11,10 @@ import { rateLimiter } from './rate-limiter.js'; // Env config (mirrors vector.ts) const VECTOR_OGMIOS_URL = process.env.VECTOR_OGMIOS_URL || 'https://ogmios.vector.testnet.apexfusion.org'; const VECTOR_SUBMIT_URL = process.env.VECTOR_SUBMIT_URL || 'https://submit.vector.testnet.apexfusion.org/api/submit/tx'; -const VECTOR_KOIOS_URL = process.env.VECTOR_KOIOS_URL || 'https://koios.vector.testnet.apexfusion.org/'; +const VECTOR_KOIOS_URL = process.env.VECTOR_KOIOS_URL || 'https://v2.koios.vector.testnet.apexfusion.org/'; const VECTOR_EXPLORER_URL = process.env.VECTOR_EXPLORER_URL || 'https://vector.testnet.apexscan.org'; -// Registry constants — agent-registry v2 (audited, compliant) +// Registry constants - agent-registry v2 (audited, compliant) // Source blueprint: vector-ai-agents/agent-registry/deploy/agent-registry/plutus.json const REGISTRY_SCRIPT_CBOR = "5909d101010029800aba2aba1aba0aab9faab9eaab9dab9a4888888966003300130033754011370e90004dc3a40052300730080019180398041804000c8c01cc020c020c020c02000644b30010018a40011337009001198010011804800a00c91803980418041804000c88c8c8cc004004010896600200300389919912cc004cdc8803801456600266e3c01c00a20030064025133005005300f00440246eb8c020004dd598048009805800a01214bd6f7b630488c8cc00400400c896600200314a115980098019805000c528c4cc008008c02c00500520109ba5480026e1d2004488888888888a60026026019301200c912cc004c034c040dd5000c4c8c8cc004004dd6180b180b980b980b980b980b980b980b980b98099baa0042259800800c528456600266e3cdd7180b800801c528c4cc008008c060005012202a375c602860226ea8006294100f48966002601a60206ea800a2646464646464653001375a6036003375c603600d375c603600b37586036009375c6036007375c60360049111112cc004c08801e2646644b3001301d002899192cc004c09c00a0071640906eb8c094004c084dd5001c566002603800513232598009813801400e2c8120dd7181280098109baa0038b203e407c603c6ea80044c8cc00400401489660020030118991980180198130011bae30240014088604201b16407c301b001301a00130190013018001301700130160013011375400516403d259800980618079baa0018a518a504039300600691119199119801001000912cc00400600713233225980099b910070028acc004cdc78038014400600c80b226600a00a603800880b0dd7180a8009bad3016001301800140586601000800629000488c8cc00400400c896600200314c103d87a80008992cc004c0100062600e6602c00297ae0899801801980c001202430160014050911111114c004c0680226034603601125980099b89371a6eb8c048c060dd5000a41000915980099b89371a6eb8c044c060dd5000a41002115980099b89371a6eb8c040c060dd5000a41000515980099b89371a6eb8c06cc070c070c070c070c070c060dd5000a41001115980099b8930043758601c60306ea80052040899198008009bac300f3019375400444b30010018a518acc004cdc49b8d375c603a00290400144cc008008c078006294101820368a50405914a080b229410164528202c8a50405929800800d220100a44100400c9111192cc004c0600062646644b3001301b0018992cc004c090006264b3001301d30203754003132323322598009814801c0222c8130dd698130009bae302600230260013021375400316407c6046003164084603e6ea80222b3001301a0018acc004c07cdd5004400a2c81022c80e901d0992cc004c068c074dd5003c4c8cc89660026602a6eb0c090c084dd5008919baf30253022375400200915980099912cc0040060051598009813800c4c96600266e3cdd71811800802c4c07cdd69812000c52820443026001801204840902940cc058dd5980c98109baa011005899912cc0040060051598009813800c4c966002602c60466ea8006264660260022b300130123028302537540031598009980a00a981418129baa00189806000c52820468a50408c604e60486ea80062c8110c070c08cdd51813000c009024204814a064660020026eb0c06cc088dd5009112cc004006297ae0899912cc0056600266ebcc0a0c094dd5001002c566002b3001301730243754603c604a6ea800a294629410234566002604130013756603e604a6ea800a013006404113371290406d620498059bab301f3025375400514a0811a29410234528204689981380119802002000c4cc01001000502318130009813800a0488a50407d14a080f8dca1bb300130020033021301e375400f1332259800800c00a2b30013024001899192cc004cdc39bad30220024800626464b300130203023375400313259800980b98121baa0018991980a00089980a80b181498131baa00130283025375400316408c603a60486ea8c078c090dd5181398121baa0018a5040886601a6eb0c098c08cdd500992cc004cdd7981398121baa301e302437540020051301f98009bab301e30243754603c60486ea8006011003403d14a08110c01401a2c8100dd718100009811800c009021204214a0660266eacc058c078dd5007001203823011330203374a9001198101ba90014bd7019810260103d87a80004bd70180e1baa006375c603e60386ea80122b30013017001899199119912cc004c0740062b3001302137540150028b20448acc004c0700062b3001302137540150028b20448b203e407c2b3001301b301e3754003198009811180f9baa00191192cc004c078c084dd5000c4c094c088dd5180e18111baa30253022375400316408066016004466ebcc094c088dd500080148c966002603860406ea800626eb8c090c084dd5000c5901f181198101baa00191192cc004c078c084dd5000c4dd5980e18111baa301c30223754604a60446ea80062c8100cc02c0088cdd7981298111baa00100291192cc004c098006264b3001301e375a60460031375c6044003164084604a00316408c6602c004002911112cc004c080c08cdd5006c4c8cc88cc896600266030032605860526ea802a2b3001302432330010013758605a60546ea8068896600200314800226644b30013375e6060605a6ea8c09cc0b4dd5001004c4cdc0000a4005100140ac605c00266004004605e0028162264b30013026302937540031323259800980f18159baa0018991980d8008acc004cdc39bad3005302d37540026eb4c014c0b4dd5007456600260346060605a6ea80062b30013014001899b89301300730133756604e605a6ea800e294102b452820568a5040ac605e60586ea80062c8150c090c0acdd5000981698151baa0018a5040a0660266eb0c088c0a4dd500c92cc004cdd7981698151baa00100689812cc004dd5981218151baa001802c00d015452820508a50409d14a08138cc0100040088c0acc0b0c0b0c0b0c0b0c0b0c0b0004c010004cc00cdd6181418129baa015008330043758604e60486ea805001e26464b30013301501630293026375400f15980099912cc0040060051598009816000c4c96600266e3cdd7181400080244cdc39bad30290014800629410271815800c009029205214a0660366eacc078c098dd500b00144c9660026046604c6ea8006264660386eb0c084c0a0dd500c12cc004cdd7981618149baa302c30293754002605860526ea800a266e252080dac409300f3756604660526ea80062941027180d19814980d19814981518139baa0014bd7019814a6103d87a80004bd704528204a30293026375400f14a08122294102419801198019bac30283025375402a0100026006660086eb0c09cc090dd500a003a04445901d180f1baa008302000130203021001301c375400916406880d0c068dd500188a4d13656400401"; const REGISTRY_POLICY_ID = "be1a0a2912da180757ed3cd61b56bb8eab0188c19dc3c0e3912d2c01"; @@ -147,7 +147,7 @@ async function resolveAgentUtxo(provider, agentId) { try { utxo = await provider.getUtxoByUnit(unit); } catch { - // Koios unavailable or asset not found — will try Ogmios fallback below + // Koios unavailable or asset not found - will try Ogmios fallback below } // If Koios returned a UTxO without datum, or didn't find one, scan via Ogmios @@ -232,7 +232,7 @@ function checkRateLimit() { export function registerAgentNetworkTools(server) { - // vector_get_agent_profile (read-only — no mnemonic needed) + // vector_get_agent_profile (read-only - no mnemonic needed) server.tool( "vector_get_agent_profile", "Get a registered agent's profile from the on-chain registry by DID (did:vector:agent:...)", @@ -282,7 +282,7 @@ ${capList} } ); - // vector_discover_agents (read-only — no mnemonic needed) + // vector_discover_agents (read-only - no mnemonic needed) server.tool( "vector_discover_agents", "Discover registered agents in the Vector on-chain registry, optionally filtered by capability or framework", @@ -329,7 +329,7 @@ ${capList} **Troubleshooting Tips:** 1. Check that Ogmios is reachable at ${VECTOR_OGMIOS_URL} -2. The registry may be empty — no agents have registered yet +2. The registry may be empty - no agents have registered yet 3. Try without filters to list all agents`, }], }; @@ -405,7 +405,7 @@ ${capList} [View on Explorer](${explorerTxLink(txHash)}) -Save your Agent DID — you'll need it to update, deregister, or let other agents discover you.`, +Save your Agent DID - you'll need it to update, deregister, or let other agents discover you.`, }], }; } catch (err) { @@ -510,7 +510,7 @@ The agent's profile has been updated on-chain. The identity NFT and deposit are **Troubleshooting Tips:** 1. Verify the agent DID is correct 2. Your wallet must be the agent's current owner -3. Ensure wallet has enough ADA for transaction fees +3. Ensure wallet has enough AP3X for transaction fees 4. Check spend limits with vector_get_spend_limits`, }], }; @@ -578,7 +578,7 @@ The agent's identity NFT has been burned and the 10 AP3X deposit has been return **Troubleshooting Tips:** 1. Verify the agent DID is correct 2. Your wallet must be the agent's current owner -3. Ensure wallet has enough ADA for transaction fees +3. Ensure wallet has enough AP3X for transaction fees 4. Use vector_get_agent_profile to check the agent's current state`, }], }; @@ -666,7 +666,7 @@ Ownership has been transferred. The new owner can now update, transfer, or dereg 1. Verify the agent DID is correct 2. Your wallet must be the agent's current owner 3. The new owner address must be a verification key address (not a script) -4. Ensure wallet has enough ADA for transaction fees`, +4. Ensure wallet has enough AP3X for transaction fees`, }], }; } @@ -676,7 +676,7 @@ Ownership has been transferred. The new owner can now update, transfer, or dereg // vector_message_agent server.tool( "vector_message_agent", - "Send an on-chain message to a registered Vector agent via TX metadata (label 674). Delivers 2 ADA to the agent's owner address.", + "Send an on-chain message to a registered Vector agent via TX metadata (label 674). Delivers 2 AP3X to the agent's owner address.", { agent_id: z.string().describe("Recipient agent DID: did:vector:agent:{policyId}:{nftAssetName}"), message_type: z.enum(["inquiry", "proposal", "result"]).describe("Type of message"), @@ -730,7 +730,7 @@ The message is recorded on-chain in TX metadata label 674.`, **Troubleshooting Tips:** 1. Verify the agent DID is correct: did:vector:agent:{policyId}:{nftAssetName} -2. Ensure wallet has at least 3 ADA (2 ADA delivery + fees) +2. Ensure wallet has at least 3 AP3X (2 AP3X delivery + fees) 3. Use vector_get_agent_profile to verify the agent exists first 4. Check spend limits with vector_get_spend_limits`, }], diff --git a/src/vector/ogmios-provider.ts b/src/vector/ogmios-provider.ts index 1b52d30..5e893b6 100644 --- a/src/vector/ogmios-provider.ts +++ b/src/vector/ogmios-provider.ts @@ -162,7 +162,7 @@ export class OgmiosProvider implements Provider { } } } catch (err) { - // Koios unreachable — caller can fall back to scanning UTxOs + // Koios unreachable - caller can fall back to scanning UTxOs } } @@ -310,7 +310,7 @@ export class OgmiosProvider implements Provider { /** * Evaluate a transaction without submitting (dry run). - * Backward-compatible alias — returns raw Ogmios response. + * Backward-compatible alias - returns raw Ogmios response. */ async evaluateTransaction(txCborHex: string): Promise { return this.rpc('evaluateTransaction', { diff --git a/src/vector/safety.ts b/src/vector/safety.ts index 5e37222..c51fe49 100644 --- a/src/vector/safety.ts +++ b/src/vector/safety.ts @@ -3,8 +3,8 @@ import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; import type { SpendLimits, SpendStatus, AuditEntry } from './types.js'; -const VECTOR_SPEND_LIMIT_PER_TX = parseInt(process.env.VECTOR_SPEND_LIMIT_PER_TX || '100000000'); // 100 ADA -const VECTOR_SPEND_LIMIT_DAILY = parseInt(process.env.VECTOR_SPEND_LIMIT_DAILY || '500000000'); // 500 ADA +const VECTOR_SPEND_LIMIT_PER_TX = parseInt(process.env.VECTOR_SPEND_LIMIT_PER_TX || '100000000'); // 100 AP3X +const VECTOR_SPEND_LIMIT_DAILY = parseInt(process.env.VECTOR_SPEND_LIMIT_DAILY || '500000000'); // 500 AP3X const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -91,7 +91,7 @@ export class SafetyLayer { if (amountLovelace > this.limits.perTransaction) { return { allowed: false, - reason: `Transaction amount ${(amountLovelace / 1_000_000).toFixed(6)} ADA exceeds per-transaction limit of ${(this.limits.perTransaction / 1_000_000).toFixed(6)} ADA`, + reason: `Transaction amount ${(amountLovelace / 1_000_000).toFixed(6)} AP3X exceeds per-transaction limit of ${(this.limits.perTransaction / 1_000_000).toFixed(6)} AP3X`, }; } @@ -99,7 +99,7 @@ export class SafetyLayer { const remaining = this.limits.daily - this.dailySpent; return { allowed: false, - reason: `Transaction would exceed daily spend limit. Daily limit: ${(this.limits.daily / 1_000_000).toFixed(6)} ADA, already spent: ${(this.dailySpent / 1_000_000).toFixed(6)} ADA, remaining: ${(remaining / 1_000_000).toFixed(6)} ADA`, + reason: `Transaction would exceed daily spend limit. Daily limit: ${(this.limits.daily / 1_000_000).toFixed(6)} AP3X, already spent: ${(this.dailySpent / 1_000_000).toFixed(6)} AP3X, remaining: ${(remaining / 1_000_000).toFixed(6)} AP3X`, }; } diff --git a/src/vector/self-improvement.ts b/src/vector/self-improvement.ts index 7a75bbc..1c7d5b4 100644 --- a/src/vector/self-improvement.ts +++ b/src/vector/self-improvement.ts @@ -5,7 +5,7 @@ import { z } from "zod"; import { Lucid, fromText, toText, Data, Constr, credentialToAddress, getAddressDetails, SLOT_CONFIG_NETWORK } from '@lucid-evolution/lucid'; -// Vector slot config — resolved from chain via Ogmios queryNetwork/startTime +// Vector slot config - resolved from chain via Ogmios queryNetwork/startTime // Cached after first query so SLOT_CONFIG_NETWORK is set before Lucid needs it let vectorZeroTime: number | null = null; @@ -25,13 +25,13 @@ import { rateLimiter } from './rate-limiter.js'; // Env config const VECTOR_OGMIOS_URL = process.env.VECTOR_OGMIOS_URL || 'https://ogmios.vector.testnet.apexfusion.org'; const VECTOR_SUBMIT_URL = process.env.VECTOR_SUBMIT_URL || 'https://submit.vector.testnet.apexfusion.org/api/submit/tx'; -const VECTOR_KOIOS_URL = process.env.VECTOR_KOIOS_URL || 'https://koios.vector.testnet.apexfusion.org/'; +const VECTOR_KOIOS_URL = process.env.VECTOR_KOIOS_URL || 'https://v2.koios.vector.testnet.apexfusion.org/'; const VECTOR_EXPLORER_URL = process.env.VECTOR_EXPLORER_URL || 'https://vector.testnet.apexscan.org'; // Agent Registry policy ID (shared across all modules) const AGENT_REGISTRY_POLICY = process.env.AGENT_REGISTRY_POLICY || 'be1a0a2912da180757ed3cd61b56bb8eab0188c19dc3c0e3912d2c01'; -// Governance contract hashes (from deploy_state.json) +// Module contract hashes (from deploy_state.json) // These should be set via env vars in production const GOV_PROPOSAL_SPEND_HASH = process.env.GOV_PROPOSAL_SPEND_HASH || 'f815f51a76002d6a973e83fecf60f45473e040acee85c631fcce134d'; const GOV_PROPOSAL_MINT_HASH = process.env.GOV_PROPOSAL_MINT_HASH || 'e8f38052352a3d20c5fe025e2a02d615826a154b26f2239286b8d565'; @@ -40,11 +40,11 @@ const GOV_CRITIQUE_MINT_HASH = process.env.GOV_CRITIQUE_MINT_HASH || '2e252a8989 const GOV_ENDORSEMENT_SPEND_HASH = process.env.GOV_ENDORSEMENT_SPEND_HASH || '5fc449848d85f30287e5bc0bd2b3e95d872ef97be27f1480c12f1a9d'; const GOV_TREASURY_ADDRESS = process.env.GOV_TREASURY_ADDRESS || 'addr1wx434t2jc3m5uhdf7tq05xjdqu3q5z7a2lhrmn5mapsd43srh7ll8'; -// Reference script UTxOs (CIP-33) — for validated submit +// Reference script UTxOs (CIP-33) - for validated submit const GOV_PROPOSAL_SPEND_REF = process.env.GOV_PROPOSAL_SPEND_REF || 'c70a410c9c0c543a0a1103049680b89cbf6fd2277e8469c4d52632dc52b80996#0'; const GOV_PROPOSAL_MINT_REF = process.env.GOV_PROPOSAL_MINT_REF || 'c40b64fff5c4056689354076aa3d06431d786a4f8f0c1e492e70261d2309e50a#0'; -// Infrastructure UTxOs (governance reference inputs) +// Infrastructure UTxOs (module reference inputs) const GOV_PARAMS_UTXO = process.env.GOV_PARAMS_UTXO || '2c082e833649175b4a543a5a0cf61f9b736acdfa0d315d1184645185e9a52796#0'; const GOV_ORACLE_UTXO = process.env.GOV_ORACLE_UTXO || '7a23dfdf9468dd35cee3cad03008f2538c86834d4e5140e0ffaf2ff93e7c04a7#0'; const GOV_CROSSREFS_UTXO = process.env.GOV_CROSSREFS_UTXO || '96a4acff8be0fb96b3839ee6c9c1fa75809b94f4967218eaf813ac56b939c4b2#0'; @@ -276,7 +276,7 @@ export function registerSelfImprovementTools(server) { server.tool( "vector_self_improvement_browse", - "Browse governance proposals, critiques, and endorsements. Query on-chain UTxOs at governance script addresses and decode datums into human-readable format.", + "Browse improvement proposals, critiques, and endorsements. Query on-chain UTxOs at the module's script addresses and decode datums into human-readable format.", { entity: z.enum(["proposals", "critiques", "endorsements", "treasury"]).describe("What to browse"), state: z.string().optional().describe("Filter proposals by state: Open, Amended, Adopted, Rejected, Expired, Withdrawn"), @@ -388,7 +388,7 @@ Each batch UTxO holds ~30 AP3X for adoption rewards.`, return { content: [{ type: "text", - text: `# Governance Proposals (${items.length} found)\n\n${lines.join('\n\n') || 'No proposals match the filters.'}`, + text: `# Improvement Proposals (${items.length} found)\n\n${lines.join('\n\n') || 'No proposals match the filters.'}`, }], }; } else if (entity === "critiques") { @@ -424,10 +424,10 @@ Each batch UTxO holds ~30 AP3X for adoption rewards.`, return { content: [{ type: "text", - text: `Failed to browse governance data: ${err.message} + text: `Failed to browse proposal data: ${err.message} **Troubleshooting Tips:** -1. Verify the governance contracts are deployed on testnet +1. Verify the module contracts are deployed on this network 2. Check that Ogmios is reachable at ${VECTOR_OGMIOS_URL} 3. The script addresses may not have any UTxOs yet`, }], @@ -440,10 +440,10 @@ Each batch UTxO holds ~30 AP3X for adoption rewards.`, server.tool( "vector_self_improvement_submit_proposal", - "Submit a governance proposal to the Vector Self-Improvement Module. Requires staking AP3X. Provide proposalDocument (JSON string) for automatic IPFS upload via Filebase and blake2b_256 hashing, OR provide proposalHash and storageUri manually.", + "Submit an improvement proposal to the Vector Self-Improvement Module. Requires staking AP3X. Provide proposalDocument (JSON string) for automatic IPFS upload via Filebase and blake2b_256 hashing, OR provide proposalHash and storageUri manually.", { mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the wallet"), - agentDid: z.string().describe("Agent DID (hex) — the asset name from Agent Registry NFT"), + agentDid: z.string().describe("Agent DID (hex) - the asset name from Agent Registry NFT"), proposalDocument: z.string().optional().describe("Full proposal document as JSON string. Uploaded to IPFS via Filebase; hash and CID computed automatically. If provided, proposalHash and storageUri are ignored."), proposalHash: z.string().optional().describe("blake2b_256 hash of proposal document (64 hex chars). Required if proposalDocument is not provided."), proposalType: z.enum(["ParameterChange", "TreasurySpend", "ProtocolUpgrade", "GameActivation", "GeneralSuggestion"]).describe("Category of the proposal"), @@ -601,7 +601,7 @@ Each batch UTxO holds ~30 AP3X for adoption rewards.`, throw new Error( `Reference script UTxOs missing: found ${refScriptUtxos.length}/2. ` + `spend_ref=${GOV_PROPOSAL_SPEND_REF}, mint_ref=${GOV_PROPOSAL_MINT_REF}. ` + - `These UTxOs may have been consumed — redeploy with scripts/redeploy_ref_scripts.py ` + + `These UTxOs may have been consumed - redeploy with scripts/redeploy_ref_scripts.py ` + `and update GOV_PROPOSAL_SPEND_REF / GOV_PROPOSAL_MINT_REF env vars.` ); } @@ -614,7 +614,7 @@ Each batch UTxO holds ~30 AP3X for adoption rewards.`, ); } - // Get governance infrastructure reference inputs + // Get module infrastructure reference inputs const govRefUtxos = await lucid.utxosByOutRef([ parseUtxoRef(GOV_PARAMS_UTXO), parseUtxoRef(GOV_ORACLE_UTXO), @@ -708,7 +708,7 @@ activity tracking token (\`pact_\`) minted. Visible on the Foundation dashboard. server.tool( "vector_self_improvement_critique", - "Submit a critique on a governance proposal. Critiques can support, oppose, or propose amendments. Requires staking AP3X. Provide critiqueDocument (JSON string) for automatic IPFS upload, or critiqueHash + storageUri manually.", + "Submit a critique on an improvement proposal. Critiques can support, oppose, or propose amendments. Requires staking AP3X. Provide critiqueDocument (JSON string) for automatic IPFS upload, or critiqueHash + storageUri manually.", { mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the wallet"), agentDid: z.string().describe("Agent DID (hex)"), @@ -830,7 +830,7 @@ ${ipfsCid ? `**IPFS CID:** ${ipfsCid}\n**Hash (auto-computed):** ${finalHash}` : server.tool( "vector_self_improvement_endorse", - "Endorse a governance proposal by staking AP3X. Endorsements signal support to the Foundation Council and are weighted by stake amount.", + "Endorse an improvement proposal by staking AP3X. Endorsements signal support to the Foundation Council and are weighted by stake amount.", { mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the wallet"), agentDid: z.string().describe("Agent DID (hex)"), @@ -861,7 +861,7 @@ ${ipfsCid ? `**IPFS CID:** ${ipfsCid}\n**Hash (auto-computed):** ${finalHash}` : const tip = await provider.getNetworkTip?.() || { slot: 0 }; const currentSlot = tip.slot || 0; - // Build GovernanceEndorsementDatum + // Build the endorsement datum const endorsementDatum = Data.to(new Constr(0, [ agentDid, // endorser_did new Constr(0, [vkeyHash]), // endorser_credential @@ -916,7 +916,7 @@ ${ipfsCid ? `**IPFS CID:** ${ipfsCid}\n**Hash (auto-computed):** ${finalHash}` : server.tool( "vector_self_improvement_analyze_metrics", - "Analyze governance metrics: proposal activity, adoption rate, treasury health, and engagement statistics. Read-only — no mnemonic needed.", + "Analyze proposal metrics: proposal activity, adoption rate, treasury health, and engagement statistics. Read-only - no mnemonic needed.", { focus: z.enum(["overview", "adoption", "treasury", "activity"]).default("overview").describe("Analysis focus area"), }, @@ -985,7 +985,7 @@ ${Number(treasuryTotal) < 2_500_000_000 ? '**WARNING:** Treasury below 2,500 AP3 return { content: [{ type: "text", - text: `# Governance Metrics${focus !== 'overview' ? ` (${focus})` : ''} + text: `# Proposal Metrics${focus !== 'overview' ? ` (${focus})` : ''} ## Proposals - **Total on-chain:** ${totalCount} @@ -1009,11 +1009,11 @@ ${Number(treasuryTotal) < 2_500_000_000 ? '\n**WARNING:** Treasury below alert t return { content: [{ type: "text", - text: `Failed to analyze governance metrics: ${err.message} + text: `Failed to analyze proposal metrics: ${err.message} **Troubleshooting Tips:** 1. Verify Ogmios endpoint is reachable -2. The governance contracts may not be deployed yet`, +2. The module contracts may not be deployed yet`, }], }; } diff --git a/src/vector/vector.ts b/src/vector/vector.ts index a17f644..0c192e5 100644 --- a/src/vector/vector.ts +++ b/src/vector/vector.ts @@ -39,10 +39,10 @@ if (existsSync(envPath)) { // Configuration from environment variables const VECTOR_OGMIOS_URL = process.env.VECTOR_OGMIOS_URL || 'https://ogmios.vector.testnet.apexfusion.org'; const VECTOR_SUBMIT_URL = process.env.VECTOR_SUBMIT_URL || 'https://submit.vector.testnet.apexfusion.org/api/submit/tx'; -const VECTOR_KOIOS_URL = process.env.VECTOR_KOIOS_URL || 'https://koios.vector.testnet.apexfusion.org/'; +const VECTOR_KOIOS_URL = process.env.VECTOR_KOIOS_URL || 'https://v2.koios.vector.testnet.apexfusion.org/'; const VECTOR_EXPLORER_URL = process.env.VECTOR_EXPLORER_URL || 'https://vector.testnet.apexscan.org'; -// Helper function to format ADA amounts +// Helper function to format AP3X amounts function lovelaceToAda(lovelace: string | number | bigint): string { if (lovelace === undefined || lovelace === null) return '0.000000'; try { @@ -159,7 +159,7 @@ export async function getWalletInfo(mnemonic: string, accountIndex: number = 0): }; } -// Send ADA transaction +// Send AP3X transaction export async function sendAda( recipientAddress: string, amountAda: number, @@ -234,8 +234,8 @@ export async function sendTokens( throw new Error('Amount must be a positive number'); } - // Safety check on ADA portion - const adaLovelace = adaAmount ? Math.floor(adaAmount * 1_000_000) : 2_000_000; // min ~2 ADA + // Safety check on AP3X portion + const adaLovelace = adaAmount ? Math.floor(adaAmount * 1_000_000) : 2_000_000; // min ~2 AP3X const safetyCheck = safetyLayer.checkTransaction(adaLovelace); if (!safetyCheck.allowed) { throw new Error(`Safety limit exceeded: ${safetyCheck.reason}`); @@ -260,7 +260,7 @@ export async function sendTokens( const outputLovelace = adaAmount ? BigInt(Math.floor(adaAmount * 1_000_000)) - : BigInt(2_000_000); // Default min ADA + : BigInt(2_000_000); // Default min AP3X let tx = lucid.newTx() .pay.ToAddress(recipientAddress, { @@ -303,7 +303,7 @@ export async function buildTransaction( throw new Error('At least one output is required'); } - // Calculate total ADA across all outputs for safety check + // Calculate total AP3X across all outputs for safety check const totalLovelace = outputs.reduce((sum, o) => sum + o.lovelace, 0); const safetyCheck = safetyLayer.checkTransaction(totalLovelace); if (!safetyCheck.allowed) { @@ -494,7 +494,7 @@ export async function interactWithContract( const signedTx = await completedTx.sign.withWallet().complete(); const txHash = await signedTx.submit(); - // No spend recording for collecting — funds are coming back to wallet + // No spend recording for collecting - funds are coming back to wallet return { txHash, @@ -508,10 +508,10 @@ export async function interactWithContract( // Register all Vector MCP tools export function registerVectorTools(server: McpServer) { - // vector_get_balance — Get balance for any address + // vector_get_balance - Get balance for any address server.tool( "vector_get_balance", - "Get ADA and token balances for a Vector address", + "Get AP3X and token balances for a Vector address", { address: z.string().describe("Vector address to check (addr1...)"), }, @@ -563,7 +563,7 @@ export function registerVectorTools(server: McpServer) { type: "text", text: `Vector Address Balance for ${address}: -ADA Balance: ${lovelaceToAda(adaBalance)} ADA +AP3X Balance: ${lovelaceToAda(adaBalance)} AP3X UTxO Count: ${utxos.length} ${tokens.length > 0 ? `Token Holdings (${tokens.length}):\n${tokenList}` : 'No token holdings found'}`, @@ -581,7 +581,7 @@ ${tokens.length > 0 ? `Token Holdings (${tokens.length}):\n${tokenList}` : 'No t } ); - // vector_get_address — Get the agent's wallet address and balance + // vector_get_address - Get the agent's wallet address and balance server.tool( "vector_get_address", "Get the Vector wallet address, balance, and token holdings derived from a mnemonic", @@ -606,7 +606,7 @@ ${tokens.length > 0 ? `Token Holdings (${tokens.length}):\n${tokenList}` : 'No t text: `# Vector Wallet Information Address: ${walletInfo.address} -ADA Balance: ${walletInfo.ada} ADA +AP3X Balance: ${walletInfo.ada} AP3X UTXO Count: ${walletInfo.utxoCount} ${walletInfo.tokens.length > 0 ? `## Token Holdings (${walletInfo.tokens.length}):\n${tokenList}` : 'No token holdings found'}`, @@ -629,7 +629,7 @@ ${walletInfo.tokens.length > 0 ? `## Token Holdings (${walletInfo.tokens.length} } ); - // vector_get_utxos — List UTxOs for an address or the wallet + // vector_get_utxos - List UTxOs for an address or the wallet server.tool( "vector_get_utxos", "List unspent transaction outputs (UTxOs) for a Vector address or a wallet derived from a mnemonic", @@ -673,7 +673,7 @@ ${walletInfo.tokens.length > 0 ? `## Token Holdings (${walletInfo.tokens.length} const utxoList = utxos.map((utxo, i) => { const ada = utxo.assets['lovelace'] ? lovelaceToAda(utxo.assets['lovelace']) : '0'; const tokenCount = Object.keys(utxo.assets).filter(k => k !== 'lovelace').length; - return `${i + 1}. ${utxo.txHash}#${utxo.outputIndex} — ${ada} ADA${tokenCount > 0 ? ` + ${tokenCount} token(s)` : ''}`; + return `${i + 1}. ${utxo.txHash}#${utxo.outputIndex} - ${ada} AP3X${tokenCount > 0 ? ` + ${tokenCount} token(s)` : ''}`; }).join('\n'); return { @@ -698,13 +698,13 @@ ${utxoList}`, } ); - // vector_send_apex — Send APEX with safety limits (or craft unsigned TX) + // vector_send_apex - Send APEX with safety limits (or craft unsigned TX) server.tool( "vector_send_apex", - "Send ADA from a wallet to a recipient address. Set unsigned_only=true to return unsigned CBOR without submitting (transaction-crafter mode).", + "Send AP3X from a wallet to a recipient address. Set unsigned_only=true to return unsigned CBOR without submitting (transaction-crafter mode).", { recipientAddress: z.string().describe("Recipient Vector address (addr1...)"), - amount: z.number().min(1).describe("Amount of ADA to send"), + amount: z.number().min(1).describe("Amount of AP3X to send"), mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the sending wallet"), metadata: z.string().optional().describe("Optional transaction metadata in JSON format"), unsigned_only: z.boolean().optional().default(false).describe("If true, return unsigned TX CBOR without signing or submitting"), @@ -732,9 +732,9 @@ ${utxoList}`, type: "text", text: `# Unsigned Transaction (Transaction-Crafter Mode) -**Amount:** ${amount} ADA (${lovelaceAmount} lovelace) +**Amount:** ${amount} AP3X (${lovelaceAmount} lovelace) **To:** ${recipientAddress} -**Estimated Fee:** ${lovelaceToAda(fee)} ADA +**Estimated Fee:** ${lovelaceToAda(fee)} AP3X **Unsigned TX CBOR:** \`\`\` @@ -750,12 +750,12 @@ This transaction has NOT been submitted. Sign and submit it separately.`, return { content: [{ type: "text", - text: `# ADA Transaction Successful + text: `# AP3X Transaction Successful Transaction Hash: ${result.txHash} From: ${result.senderAddress} To: ${result.recipientAddress} -Amount: ${result.amount} ADA +Amount: ${result.amount} AP3X [View on Explorer](${result.links.explorer})`, }], @@ -765,7 +765,7 @@ Amount: ${result.amount} ADA return { content: [{ type: "text", - text: `Failed to send ADA: ${error.message} + text: `Failed to send AP3X: ${error.message} **Troubleshooting Tips:** 1. Check that your wallet has sufficient balance @@ -778,7 +778,7 @@ Amount: ${result.amount} ADA } ); - // vector_send_tokens — Send native tokens with safety limits (or craft unsigned TX) + // vector_send_tokens - Send native tokens with safety limits (or craft unsigned TX) server.tool( "vector_send_tokens", "Send Vector native tokens from a wallet to a recipient address. Set unsigned_only=true to return unsigned CBOR without submitting.", @@ -788,7 +788,7 @@ Amount: ${result.amount} ADA assetName: z.string().describe("Asset name (can be empty for policy-only tokens)"), amount: z.string().describe("Amount of tokens to send"), mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the sending wallet"), - adaAmount: z.number().optional().describe("Optional ADA to include (uses minimum required if not specified)"), + adaAmount: z.number().optional().describe("Optional AP3X to include (uses minimum required if not specified)"), unsigned_only: z.boolean().optional().default(false).describe("If true, return unsigned TX CBOR without signing or submitting"), }, async ({ recipientAddress, policyId, assetName, amount, mnemonic, adaAmount, unsigned_only }) => { @@ -821,8 +821,8 @@ Amount: ${result.amount} ADA **Token:** ${formatAssetName(assetNameHex) || policyId.substring(0,8) + '...'} **Amount:** ${amount} **To:** ${recipientAddress} -**Included ADA:** ${lovelaceToAda(outputLovelace)} ADA -**Estimated Fee:** ${lovelaceToAda(fee)} ADA +**Included AP3X:** ${lovelaceToAda(outputLovelace)} AP3X +**Estimated Fee:** ${lovelaceToAda(fee)} AP3X **Unsigned TX CBOR:** \`\`\` @@ -849,7 +849,7 @@ Token Details: - Asset Name: ${result.token.name || '(none)'} - Amount: ${result.token.amount} -Included ADA: ${result.ada} ADA +Included AP3X: ${result.ada} AP3X [View on Explorer](${result.links.explorer})`, }], @@ -862,7 +862,7 @@ Included ADA: ${result.ada} ADA text: `Failed to send tokens: ${error.message} **Troubleshooting Tips:** -1. Check that your wallet has sufficient ADA and token balance +1. Check that your wallet has sufficient AP3X and token balance 2. Verify the policy ID and asset name are correct 3. Verify the recipient address is correct (addr1...) 4. Check spend limits with vector_get_spend_limits`, @@ -872,7 +872,7 @@ Included ADA: ${result.ada} ADA } ); - // vector_get_spend_limits — Check safety layer status + // vector_get_spend_limits - Check safety layer status server.tool( "vector_get_spend_limits", "Check current spend limits and remaining daily budget", @@ -887,7 +887,7 @@ Included ADA: ${result.ada} ADA const log = safetyLayer.getAuditLog(); const recentTxs = log.slice(-5).reverse().map((entry) => - `- ${entry.timestamp}: ${lovelaceToAda(entry.amountLovelace)} ADA → ${entry.recipient.substring(0, 20)}... (${entry.txHash.substring(0, 16)}...)` + `- ${entry.timestamp}: ${lovelaceToAda(entry.amountLovelace)} AP3X → ${entry.recipient.substring(0, 20)}... (${entry.txHash.substring(0, 16)}...)` ).join('\n'); return { @@ -895,10 +895,10 @@ Included ADA: ${result.ada} ADA type: "text", text: `# Vector Spend Limits -Per-Transaction Limit: ${lovelaceToAda(status.perTransactionLimit)} ADA -Daily Limit: ${lovelaceToAda(status.dailyLimit)} ADA -Daily Spent: ${lovelaceToAda(status.dailySpent)} ADA -Daily Remaining: ${lovelaceToAda(status.dailyRemaining)} ADA +Per-Transaction Limit: ${lovelaceToAda(status.perTransactionLimit)} AP3X +Daily Limit: ${lovelaceToAda(status.dailyLimit)} AP3X +Daily Spent: ${lovelaceToAda(status.dailySpent)} AP3X +Daily Remaining: ${lovelaceToAda(status.dailyRemaining)} AP3X Resets At: ${status.resetTime} ${log.length > 0 ? `## Recent Transactions (last ${Math.min(5, log.length)}):\n${recentTxs}` : 'No transactions recorded yet.'}`, @@ -916,14 +916,14 @@ ${log.length > 0 ? `## Recent Transactions (last ${Math.min(5, log.length)}):\n$ } ); - // vector_build_transaction — Build a complex multi-output transaction + // vector_build_transaction - Build a complex multi-output transaction server.tool( "vector_build_transaction", "Build a complex multi-output transaction with metadata. Set submit=true to sign and submit, or false to return unsigned CBOR for review.", { outputs: z.array(z.object({ address: z.string().describe("Recipient Vector address"), - lovelace: z.number().describe("Amount in lovelace (1 ADA = 1,000,000 lovelace)"), + lovelace: z.number().describe("Amount in lovelace (1 AP3X = 1,000,000 lovelace)"), assets: z.record(z.string()).optional().describe("Optional native assets: { 'policyId+assetNameHex': 'quantity' }"), })).min(1).describe("Transaction outputs"), mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the signing wallet"), @@ -945,9 +945,9 @@ ${log.length > 0 ? `## Recent Transactions (last ${Math.min(5, log.length)}):\n$ text: `# Transaction Submitted Transaction Hash: ${result.txHash} -Fee: ${result.feeAda} ADA +Fee: ${result.feeAda} AP3X Outputs: ${result.outputCount} -Total ADA Sent: ${result.totalAda} ADA +Total AP3X Sent: ${result.totalAda} AP3X [View on Explorer](${result.links?.explorer})`, }], @@ -960,9 +960,9 @@ Total ADA Sent: ${result.totalAda} ADA text: `# Transaction Built (Not Submitted) Transaction Hash: ${result.txHash} -Fee: ${result.feeAda} ADA +Fee: ${result.feeAda} AP3X Outputs: ${result.outputCount} -Total ADA: ${result.totalAda} ADA +Total AP3X: ${result.totalAda} AP3X CBOR (hex): ${result.txCbor.substring(0, 200)}${result.txCbor.length > 200 ? '...' : ''} @@ -978,7 +978,7 @@ Use vector_dry_run with this CBOR to simulate, or call vector_build_transaction **Troubleshooting Tips:** 1. Verify all recipient addresses are valid (addr1...) -2. Ensure wallet has enough ADA for outputs + fees +2. Ensure wallet has enough AP3X for outputs + fees 3. Check spend limits with vector_get_spend_limits`, }], }; @@ -986,10 +986,10 @@ Use vector_dry_run with this CBOR to simulate, or call vector_build_transaction } ); - // vector_dry_run — Simulate a transaction without submitting + // vector_dry_run - Simulate a transaction without submitting server.tool( "vector_dry_run", - "Simulate a transaction without submitting — returns fee estimate and validation result", + "Simulate a transaction without submitting - returns fee estimate and validation result", { txCbor: z.string().optional().describe("Hex-encoded CBOR of a built transaction to evaluate"), outputs: z.array(z.object({ @@ -1071,7 +1071,7 @@ Use vector_dry_run with this CBOR to simulate, or call vector_build_transaction executionUnits: (totalMemory > 0 || totalCpu > 0) ? { memory: totalMemory, cpu: totalCpu } : undefined, }; } catch (evalErr) { - // evaluateTransaction failed — still return fee if we built the tx + // evaluateTransaction failed - still return fee if we built the tx if (feeFromBuild) { evalResult = { valid: true, @@ -1095,7 +1095,7 @@ Use vector_dry_run with this CBOR to simulate, or call vector_build_transaction text: `# Dry Run Result Valid: ${evalResult.valid ? 'Yes' : 'No'} -Estimated Fee: ${evalResult.feeAda} ADA (${evalResult.fee} lovelace) +Estimated Fee: ${evalResult.feeAda} AP3X (${evalResult.fee} lovelace) ${evalResult.executionUnits ? `Execution Units: Memory ${evalResult.executionUnits.memory}, CPU ${evalResult.executionUnits.cpu}` : ''} ${evalResult.error ? `\nNote: ${evalResult.error}` : ''} @@ -1114,7 +1114,7 @@ No transaction was submitted to the network.`, } ); - // vector_get_transaction_history — Get transaction history via Koios + // vector_get_transaction_history - Get transaction history via Koios server.tool( "vector_get_transaction_history", "Get transaction history for a Vector address via Koios indexed queries", @@ -1156,7 +1156,7 @@ No transaction was submitted to the network.`, const txList = txs.map((tx, i) => { const feeAda = tx.fee ? lovelaceToAda(tx.fee) : 'N/A'; - return `${i + 1}. ${tx.txHash}\n Block: ${tx.blockHeight} | Time: ${tx.blockTime} | Fee: ${feeAda} ADA`; + return `${i + 1}. ${tx.txHash}\n Block: ${tx.blockHeight} | Time: ${tx.blockTime} | Fee: ${feeAda} AP3X`; }).join('\n\n'); return { @@ -1188,7 +1188,7 @@ ${txList} } ); - // vector_deploy_contract — Deploy a Plutus/Aiken smart contract + // vector_deploy_contract - Deploy a Plutus/Aiken smart contract server.tool( "vector_deploy_contract", "Deploy a Plutus/Aiken smart contract to Vector by sending funds to its script address", @@ -1197,7 +1197,7 @@ ${txList} scriptType: z.enum(["PlutusV1", "PlutusV2", "PlutusV3"]).describe("Script version"), mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the deploying wallet"), initialDatum: z.string().optional().describe("Initial datum as CBOR hex. Use 'd87980' for void/unit datum. Defaults to void if omitted."), - lovelaceAmount: z.number().optional().describe("ADA to lock at the script address in lovelace (default: 2,000,000 = 2 ADA)"), + lovelaceAmount: z.number().optional().describe("AP3X to lock at the script address in lovelace (default: 2,000,000 = 2 AP3X)"), }, async ({ scriptCbor, scriptType, mnemonic, initialDatum, lovelaceAmount }) => { const rateCheck = rateLimiter.check(); @@ -1237,7 +1237,7 @@ Funds locked at the script address. Use vector_interact_contract to interact wit **Troubleshooting Tips:** 1. Verify the script CBOR is valid hex (compiled Aiken or Plutus output) -2. Ensure wallet has sufficient ADA for the locked amount + fees +2. Ensure wallet has sufficient AP3X for the locked amount + fees 3. Check that the script type matches the compiled version (PlutusV1/V2/V3) 4. Check spend limits with vector_get_spend_limits`, }], @@ -1246,10 +1246,10 @@ Funds locked at the script address. Use vector_interact_contract to interact wit } ); - // vector_interact_contract — Interact with a deployed smart contract + // vector_interact_contract - Interact with a deployed smart contract server.tool( "vector_interact_contract", - "Interact with a deployed Plutus/Aiken smart contract — lock funds or spend from it", + "Interact with a deployed Plutus/Aiken smart contract - lock AP3X or spend from it", { scriptCbor: z.string().describe("Compiled Plutus/Aiken script in CBOR hex"), scriptType: z.enum(["PlutusV1", "PlutusV2", "PlutusV3"]).describe("Script version"), @@ -1257,7 +1257,7 @@ Funds locked at the script address. Use vector_interact_contract to interact wit mnemonic: z.string().describe("15 or 24-word BIP39 mnemonic for the wallet"), redeemer: z.string().optional().describe("Redeemer as CBOR hex (required for spend, use 'd87980' for void)"), datum: z.string().optional().describe("Datum as CBOR hex (required for lock, use 'd87980' for void)"), - lovelaceAmount: z.number().optional().describe("Lovelace to lock (for lock action, default: 2,000,000 = 2 ADA)"), + lovelaceAmount: z.number().optional().describe("Lovelace to lock (for lock action, default: 2,000,000 = 2 AP3X)"), utxoRef: z.object({ txHash: z.string(), outputIndex: z.number(), @@ -1307,8 +1307,8 @@ Funds ${actionVerb} the script address. **Troubleshooting Tips:** 1. For 'spend': ensure the script address has UTxOs and the redeemer satisfies the validator -2. For 'lock': ensure wallet has sufficient ADA and the datum matches the script's expectations -3. Spending requires collateral — ensure wallet has a pure-ADA UTxO (no native tokens) +2. For 'lock': ensure wallet has sufficient AP3X and the datum matches the script's expectations +3. Spending requires collateral - ensure wallet has a pure-AP3X UTxO (no native tokens) 4. Verify the script CBOR matches the deployed script exactly 5. Check spend limits with vector_get_spend_limits`, }],