From ac3234d1b87f9823acbdd4b362363461eb4e5dd4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 14:25:55 +0000 Subject: [PATCH] feat: align SDK and CLI with OCP Zero Trust and architectural pillars - Standardize 'Zero Trust Validation Failed:' error prefix across A2A, Agent, and Tokenization services. - Refactor ocp-cli to use core services (Web3/Tokenization) for x402 settlements, ensuring unified cryptographic validation. - Implement nested documentation support in Next.js app via [...slug] and recursive file discovery. - Update documentation sidebar with API Reference and Integrations categories. - Enhance cross-platform path handling in documentation utilities. Co-authored-by: dcplatforms <10982057+dcplatforms@users.noreply.github.com> --- .../app/docs/{[slug] => [...slug]}/page.tsx | 25 +++++++- ocp-docs/src/lib/docs.ts | 23 ++++++-- scripts/ocp-cli.js | 57 +++++++++---------- src/agents/agent_4f6f2eec.json | 7 +++ src/agents/agent_ab1c45e3.json | 7 +++ src/mandates/mandate_a72ae3cb27550a3d.jwt | 1 + src/mandates/mandate_b83f91c55f33c561.jwt | 1 + src/services/a2aService.js | 4 +- src/services/agent.js | 4 +- src/services/tokenization.js | 7 ++- 10 files changed, 93 insertions(+), 43 deletions(-) rename ocp-docs/src/app/docs/{[slug] => [...slug]}/page.tsx (67%) create mode 100644 src/agents/agent_4f6f2eec.json create mode 100644 src/agents/agent_ab1c45e3.json create mode 100644 src/mandates/mandate_a72ae3cb27550a3d.jwt create mode 100644 src/mandates/mandate_b83f91c55f33c561.jwt diff --git a/ocp-docs/src/app/docs/[slug]/page.tsx b/ocp-docs/src/app/docs/[...slug]/page.tsx similarity index 67% rename from ocp-docs/src/app/docs/[slug]/page.tsx rename to ocp-docs/src/app/docs/[...slug]/page.tsx index d21cc80..d71e58b 100644 --- a/ocp-docs/src/app/docs/[slug]/page.tsx +++ b/ocp-docs/src/app/docs/[...slug]/page.tsx @@ -6,12 +6,13 @@ import GlassPanel from "@/components/GlassPanel"; export async function generateStaticParams() { const slugs = await getAllDocSlugs(); return slugs.map((slug) => ({ - slug: slug, + slug: slug.replace(/\\/g, '/').split('/'), })); } -export default async function DocPage({ params }: { params: { slug: string } }) { - const source = await getDocBySlug(params.slug); +export default async function DocPage({ params }: { params: { slug: string | string[] } }) { + const slug = Array.isArray(params.slug) ? params.slug.join('/') : params.slug; + const source = await getDocBySlug(slug); if (!source) { notFound(); @@ -54,6 +55,24 @@ export default async function DocPage({ params }: { params: { slug: string } })
  • x402 Extension
  • + +
    +

    API Reference

    + +
    + +
    +

    Integrations

    + +
    diff --git a/ocp-docs/src/lib/docs.ts b/ocp-docs/src/lib/docs.ts index 0f57baf..df56ae7 100644 --- a/ocp-docs/src/lib/docs.ts +++ b/ocp-docs/src/lib/docs.ts @@ -14,8 +14,23 @@ export async function getDocBySlug(slug: string) { export async function getAllDocSlugs() { if (!fs.existsSync(CONTENT_PATH)) return []; - const files = fs.readdirSync(CONTENT_PATH); - return files - .filter((file) => file.endsWith('.md')) - .map((file) => file.replace(/\.md$/, '')); + + const getFiles = (dir: string): string[] => { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + const files = entries + .filter(e => !e.isDirectory() && e.name.endsWith('.md')) + .map(e => path.join(dir, e.name)); + + const folders = entries.filter(e => e.isDirectory()); + for (const folder of folders) { + files.push(...getFiles(path.join(dir, folder.name))); + } + return files; + }; + + const allFiles = getFiles(CONTENT_PATH); + return allFiles.map(file => { + const relativePath = path.relative(CONTENT_PATH, file); + return relativePath.replace(/\\/g, '/').replace(/\.md$/, ''); + }); } diff --git a/scripts/ocp-cli.js b/scripts/ocp-cli.js index 0f43e7f..288e5f2 100644 --- a/scripts/ocp-cli.js +++ b/scripts/ocp-cli.js @@ -11,6 +11,8 @@ const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const MandateService = require('../src/services/mandate'); +const TokenizationService = require('../src/services/tokenization'); +const Web3Service = require('../src/services/web3'); const program = new Command(); @@ -151,45 +153,40 @@ program.command('x402:settle') console.error(`Error: Mandate file not found at ${options.mandate}. In STRICT_MANDATE_MODE, a valid mandate is required for signing.`); return; } - } else { + } else if (process.env.STRICT_MANDATE_MODE === 'true') { console.error(`Error: Mandate required for x402 settlement in STRICT_MANDATE_MODE.`); return; } - // Simulation of x402 settlement with fiduciary validation - const signingKey = process.env.MANDATE_SIGNING_KEY || 'default-secret-key'; - const mandateService = new MandateService({ signingKey }); + // Initialize Services for real settlement rails logic + const tokenizationService = new TokenizationService({ + apiKey: process.env.TOKENIZATION_API_KEY || 'test-key', + mandateConfig: { + signingKey: process.env.MANDATE_SIGNING_KEY || 'default-secret-key' + } + }); + const web3Service = new Web3Service(tokenizationService); try { - const decodedMandate = await mandateService.verifyMandate(mandateToken); const amountNum = parseFloat(amount); - - // Validate budget - if (decodedMandate.max_budget && amountNum > decodedMandate.max_budget.value) { - console.error(`Zero Trust Validation Failed: Amount ${amountNum} exceeds mandate budget of ${decodedMandate.max_budget.value} ${decodedMandate.max_budget.currency}`); - return; - } - - // Validate expiration - if (decodedMandate.exp < Math.floor(Date.now() / 1000)) { - console.error('Zero Trust Validation Failed: Mandate has expired'); - return; - } + const result = await web3Service.executeX402Settlement({ + keyTokenId: 'cli-default-key', // Use default CLI key + to: options.to, + amount: amountNum, + stablecoin: options.token, + mandate: mandateToken + }); + + console.log(`Settlement Successful!`); + console.log(`ID: ${result.settlement_id}`); + console.log(`Token: ${result.stablecoin}`); + console.log(`Amount: ${result.amount}`); + console.log(`Recipient: ${result.recipient}`); + console.log(`Transaction Hash: ${result.tx_hash}`); + console.log(`Status: Finalized (24/7 Low-Latency Rails)`); } catch (error) { - console.error(`Zero Trust Validation Failed: ${error.message}`); - return; + console.error(error.message); } - - const settlementId = `x402_${crypto.randomBytes(8).toString('hex')}`; - const txHash = `0x${crypto.randomBytes(32).toString('hex')}`; - - console.log(`Settlement Successful!`); - console.log(`ID: ${settlementId}`); - console.log(`Token: ${options.token}`); - console.log(`Amount: ${amount}`); - console.log(`Recipient: ${options.to}`); - console.log(`Transaction Hash: ${txHash}`); - console.log(`Status: Finalized (24/7 Low-Latency Rails)`); }); program.parse(); diff --git a/src/agents/agent_4f6f2eec.json b/src/agents/agent_4f6f2eec.json new file mode 100644 index 0000000..0be2c22 --- /dev/null +++ b/src/agents/agent_4f6f2eec.json @@ -0,0 +1,7 @@ +{ + "id": "agent_4f6f2eec", + "name": "Architect Agent", + "did": "did:key:e4420e4bcd79b9bc4ebf82e3423b0b00", + "wallet_address": "0x08aa636fb32d8f0296a95bce9edbd00803a47623", + "created_at": "2026-05-29T14:00:18.725Z" +} \ No newline at end of file diff --git a/src/agents/agent_ab1c45e3.json b/src/agents/agent_ab1c45e3.json new file mode 100644 index 0000000..ecc0e70 --- /dev/null +++ b/src/agents/agent_ab1c45e3.json @@ -0,0 +1,7 @@ +{ + "id": "agent_ab1c45e3", + "name": "Verification Agent", + "did": "did:key:14219b271b8b070e52b8df08a6b265f7", + "wallet_address": "0x2bbc71707314c87d4f14e71f314935f69f3c2ac5", + "created_at": "2026-05-29T14:03:40.769Z" +} \ No newline at end of file diff --git a/src/mandates/mandate_a72ae3cb27550a3d.jwt b/src/mandates/mandate_a72ae3cb27550a3d.jwt new file mode 100644 index 0000000..4ae23d5 --- /dev/null +++ b/src/mandates/mandate_a72ae3cb27550a3d.jwt @@ -0,0 +1 @@ +eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkaWQ6d2ViOm9wZW4tY29tbWVyY2UtcHJvdG9jb2wuaW8iLCJzdWIiOiJkaWQ6a2V5OjRmNmYyZWVjIiwidXNlcl9kaWQiOiJkaWQ6a2V5OnVzZXItbG9jYWwiLCJhZ2VudF9kaWQiOiJkaWQ6a2V5OjRmNmYyZWVjIiwibWFuZGF0ZV9pZCI6Im1hbmRhdGVfYTcyYWUzY2IyNzU1MGEzZCIsIm1heF9idWRnZXQiOnsidmFsdWUiOjEwMDAsImN1cnJlbmN5IjoiVVNEIn0sImV4cCI6MTc4MDE0OTYzMCwicHVycG9zZV9jb2RlIjoiQ0xJX0lTU1VFRCIsImFsbG93ZWRfbWVyY2hhbnRzIjpbXSwiaWF0IjoxNzgwMDYzMjMwLCJ0eXBlIjoiaW50ZW50X21hbmRhdGUifQ.MKRk7_cIwxWNKxQQeDFmaHNWWKn02NH1ls3FSGaKkiQ \ No newline at end of file diff --git a/src/mandates/mandate_b83f91c55f33c561.jwt b/src/mandates/mandate_b83f91c55f33c561.jwt new file mode 100644 index 0000000..d52880d --- /dev/null +++ b/src/mandates/mandate_b83f91c55f33c561.jwt @@ -0,0 +1 @@ +eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkaWQ6d2ViOm9wZW4tY29tbWVyY2UtcHJvdG9jb2wuaW8iLCJzdWIiOiJkaWQ6a2V5OmFnZW50X2FiMWM0NWUzIiwidXNlcl9kaWQiOiJkaWQ6a2V5OnVzZXItbG9jYWwiLCJhZ2VudF9kaWQiOiJkaWQ6a2V5OmFnZW50X2FiMWM0NWUzIiwibWFuZGF0ZV9pZCI6Im1hbmRhdGVfYjgzZjkxYzU1ZjMzYzU2MSIsIm1heF9idWRnZXQiOnsidmFsdWUiOjEwMCwiY3VycmVuY3kiOiJVU0QifSwiZXhwIjoxNzgwMTQ5ODIxLCJwdXJwb3NlX2NvZGUiOiJDTElfSVNTVUVEIiwiYWxsb3dlZF9tZXJjaGFudHMiOltdLCJpYXQiOjE3ODAwNjM0MjEsInR5cGUiOiJpbnRlbnRfbWFuZGF0ZSJ9.U2YhVtpk-wcGUMAz6WcTDHbFlMw1InxHQrx2i0JSqks \ No newline at end of file diff --git a/src/services/a2aService.js b/src/services/a2aService.js index 3409bb0..4b8c885 100644 --- a/src/services/a2aService.js +++ b/src/services/a2aService.js @@ -84,7 +84,7 @@ class A2AService { amount > config.limits.perTransaction ) { throw new Error( - `Amount ${amount} exceeds agent per-transaction limit of ${config.limits.perTransaction}`, + `Zero Trust Validation Failed: Amount ${amount} exceeds agent per-transaction limit of ${config.limits.perTransaction}`, ); } @@ -95,7 +95,7 @@ class A2AService { ) { if (!config.authorizedCounterparties.includes(counterpartyId)) { throw new Error( - `Agent ${agent.id} is not authorized to trade with ${counterpartyId}`, + `Zero Trust Validation Failed: Agent ${agent.id} is not authorized to trade with ${counterpartyId}`, ); } } diff --git a/src/services/agent.js b/src/services/agent.js index ad47bc5..9b6d340 100644 --- a/src/services/agent.js +++ b/src/services/agent.js @@ -182,7 +182,7 @@ class AgentService { // Basic policy checks (more complex logic would be here) if (amount > fromAgent.policy.spendingLimit) { throw new Error( - `Transfer amount exceeds spending limit for agent ${fromAgentId}`, + `Zero Trust Validation Failed: Transfer amount exceeds spending limit for agent ${fromAgentId}`, ); } if ( @@ -190,7 +190,7 @@ class AgentService { fromAgent.policy.authorizedCounterparties.length > 0 ) { throw new Error( - `Agent ${toAgentId} is not an authorized counterparty for ${fromAgentId}`, + `Zero Trust Validation Failed: Agent ${toAgentId} is not an authorized counterparty for ${fromAgentId}`, ); } diff --git a/src/services/tokenization.js b/src/services/tokenization.js index 0ecaa28..5bfc751 100644 --- a/src/services/tokenization.js +++ b/src/services/tokenization.js @@ -335,10 +335,13 @@ class TokenizationService { try { decodedMandate = await this.mandateService.verifyMandate(mandate); } catch (error) { - if (error.message.includes("jwt expired")) { + if (error.message?.includes("jwt expired")) { throw new Error("Zero Trust Validation Failed: Mandate has expired"); } - throw new Error(`Zero Trust Validation Failed: ${error.message}`); + if (error.message?.includes("Zero Trust Validation Failed:")) { + throw error; + } + throw new Error(`Zero Trust Validation Failed: ${error.message || error}`); } // Validate budget if context amount is provided