@agentxv2/gateway 0.1.1
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/.env.example +53 -0
- package/db/migrations/001_init.sql +117 -0
- package/db/migrations/002_agents.sql +20 -0
- package/db/migrations/003_a2a_results.sql +23 -0
- package/deploy/.env.deploy.example +23 -0
- package/deploy/add_swap_build.py +45 -0
- package/deploy/build_and_deploy.py +110 -0
- package/deploy/build_deploy_a2a.py +190 -0
- package/deploy/build_no_lint.py +52 -0
- package/deploy/build_on_fe.py +86 -0
- package/deploy/build_on_gw.py +98 -0
- package/deploy/build_prod.py +54 -0
- package/deploy/check_bal.py +31 -0
- package/deploy/check_code.py +47 -0
- package/deploy/check_deploy.sh +20 -0
- package/deploy/check_docs.py +16 -0
- package/deploy/check_frontend.py +42 -0
- package/deploy/check_frontend2.py +35 -0
- package/deploy/check_pks.py +34 -0
- package/deploy/check_status.py +32 -0
- package/deploy/check_v2.py +8 -0
- package/deploy/clean_install.py +28 -0
- package/deploy/deploy_a2a.py +58 -0
- package/deploy/deploy_a2a.sh +33 -0
- package/deploy/deploy_a2a_bg.sh +40 -0
- package/deploy/deploy_a2a_v2.py +151 -0
- package/deploy/deploy_a2a_v2.sh +36 -0
- package/deploy/deploy_bin.py +64 -0
- package/deploy/deploy_config.py +34 -0
- package/deploy/deploy_final.py +42 -0
- package/deploy/deploy_frontend.py +108 -0
- package/deploy/deploy_mcp.py +108 -0
- package/deploy/deploy_now.py +49 -0
- package/deploy/deploy_push_all.py +128 -0
- package/deploy/deploy_script.py +64 -0
- package/deploy/deploy_sep_a2a.sh +18 -0
- package/deploy/dev_mode.py +51 -0
- package/deploy/diag.py +12 -0
- package/deploy/diff_test.py +22 -0
- package/deploy/final_check.py +33 -0
- package/deploy/final_deploy.py +50 -0
- package/deploy/final_fix.py +54 -0
- package/deploy/final_push.py +114 -0
- package/deploy/find_frontend.py +38 -0
- package/deploy/fix_a2a.py +43 -0
- package/deploy/fix_and_build.py +77 -0
- package/deploy/fix_and_verify.py +56 -0
- package/deploy/fix_build.py +51 -0
- package/deploy/forge_deploy.py +67 -0
- package/deploy/full_push.py +101 -0
- package/deploy/full_push2.py +106 -0
- package/deploy/go_prod.py +59 -0
- package/deploy/gw_deploy.py +133 -0
- package/deploy/gw_final.py +206 -0
- package/deploy/gw_restart.py +28 -0
- package/deploy/gw_status.py +18 -0
- package/deploy/inline_build.py +99 -0
- package/deploy/one_shot.py +84 -0
- package/deploy/ox_deploy.py +32 -0
- package/deploy/pg_setup.py +36 -0
- package/deploy/prod_deploy.py +126 -0
- package/deploy/prod_final.py +140 -0
- package/deploy/prod_go.py +61 -0
- package/deploy/prod_one_shot.py +139 -0
- package/deploy/prod_setup.sh +62 -0
- package/deploy/prod_v2.py +91 -0
- package/deploy/prod_v3.py +103 -0
- package/deploy/push_docs.py +93 -0
- package/deploy/push_mcp.py +66 -0
- package/deploy/push_mcp_doc.py +28 -0
- package/deploy/push_v063.py +80 -0
- package/deploy/push_v2.py +71 -0
- package/deploy/qcheck.py +13 -0
- package/deploy/qcheck2.py +18 -0
- package/deploy/quick_check.py +8 -0
- package/deploy/rebuild.py +47 -0
- package/deploy/rebuild_frontend.py +44 -0
- package/deploy/restart.py +28 -0
- package/deploy/restore_frontend.py +42 -0
- package/deploy/restore_frontend2.py +41 -0
- package/deploy/restore_gateway.py +34 -0
- package/deploy/restore_quick.py +33 -0
- package/deploy/run_bash.py +19 -0
- package/deploy/run_sep.py +20 -0
- package/deploy/sdk_upgrade.py +50 -0
- package/deploy/server_prepare.py +41 -0
- package/deploy/server_setup.py +41 -0
- package/deploy/ssh_check.py +14 -0
- package/deploy/ssh_push.py +24 -0
- package/deploy/start_deploy.py +35 -0
- package/deploy/start_frontend.py +12 -0
- package/deploy/start_v2.py +29 -0
- package/deploy/stat.py +18 -0
- package/deploy/tail_log.py +11 -0
- package/deploy/update_env.py +32 -0
- package/deploy/upload_and_start.py +107 -0
- package/deploy/verify_a2a.py +13 -0
- package/deploy/verify_mcp.py +37 -0
- package/deploy/verify_sdk.py +21 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +41 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/crypto.d.ts +2 -0
- package/dist/lib/crypto.js +43 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/db.d.ts +3 -0
- package/dist/lib/db.js +26 -0
- package/dist/lib/db.js.map +1 -0
- package/dist/lib/ethers-utils.d.ts +60 -0
- package/dist/lib/ethers-utils.js +186 -0
- package/dist/lib/ethers-utils.js.map +1 -0
- package/dist/middleware/adminAuth.d.ts +2 -0
- package/dist/middleware/adminAuth.js +31 -0
- package/dist/middleware/adminAuth.js.map +1 -0
- package/dist/middleware/auth.d.ts +22 -0
- package/dist/middleware/auth.js +192 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +36 -0
- package/dist/middleware/error-handler.js +100 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/rate-limiter.d.ts +5 -0
- package/dist/middleware/rate-limiter.js +107 -0
- package/dist/middleware/rate-limiter.js.map +1 -0
- package/dist/routes/a2a.d.ts +2 -0
- package/dist/routes/a2a.js +84 -0
- package/dist/routes/a2a.js.map +1 -0
- package/dist/routes/admin.d.ts +2 -0
- package/dist/routes/admin.js +180 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/agents.d.ts +2 -0
- package/dist/routes/agents.js +43 -0
- package/dist/routes/agents.js.map +1 -0
- package/dist/routes/chat.d.ts +2 -0
- package/dist/routes/chat.js +183 -0
- package/dist/routes/chat.js.map +1 -0
- package/dist/routes/history.d.ts +2 -0
- package/dist/routes/history.js +92 -0
- package/dist/routes/history.js.map +1 -0
- package/dist/routes/mcp.d.ts +13 -0
- package/dist/routes/mcp.js +513 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/tenant.d.ts +2 -0
- package/dist/routes/tenant.js +154 -0
- package/dist/routes/tenant.js.map +1 -0
- package/dist/services/a2a-worker.d.ts +7 -0
- package/dist/services/a2a-worker.js +406 -0
- package/dist/services/a2a-worker.js.map +1 -0
- package/dist/services/agent-indexer.d.ts +4 -0
- package/dist/services/agent-indexer.js +124 -0
- package/dist/services/agent-indexer.js.map +1 -0
- package/e2e_wallet.js +175 -0
- package/ecosystem.config.js +17 -0
- package/package.json +33 -0
- package/src/config.ts +47 -0
- package/src/index.ts +143 -0
- package/src/lib/crypto.ts +44 -0
- package/src/lib/db.ts +25 -0
- package/src/lib/ethers-utils.ts +229 -0
- package/src/middleware/adminAuth.ts +34 -0
- package/src/middleware/auth.ts +244 -0
- package/src/middleware/error-handler.ts +109 -0
- package/src/middleware/rate-limiter.ts +115 -0
- package/src/routes/a2a.ts +97 -0
- package/src/routes/admin.ts +219 -0
- package/src/routes/agents.ts +52 -0
- package/src/routes/chat.ts +219 -0
- package/src/routes/history.ts +114 -0
- package/src/routes/mcp.ts +567 -0
- package/src/routes/tenant.ts +196 -0
- package/src/services/a2a-worker.ts +486 -0
- package/src/services/agent-indexer.ts +127 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// AgentX Gateway — Agent Indexer (reads chain → stores in PostgreSQL)
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Syncs agent metadata from IdentityRegistry (ERC-721) into the agents table.
|
|
5
|
+
// Handles: IPFS CIDs, base64 data URIs, and malformed tokenURIs.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
import { ethers } from 'ethers'
|
|
9
|
+
import { getPool } from '../lib/db'
|
|
10
|
+
import { config } from '../config'
|
|
11
|
+
|
|
12
|
+
const IDENTITY_ABI = [
|
|
13
|
+
'function tokenURI(uint256 tokenId) view returns (string)',
|
|
14
|
+
'function ownerOf(uint256 tokenId) view returns (address)',
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
// Parse base64 data URI tokenURI → JSON metadata object
|
|
18
|
+
function parseTokenURIToJSON(tokenURI: string): Record<string, unknown> | null {
|
|
19
|
+
if (!tokenURI) return null
|
|
20
|
+
if (tokenURI.startsWith('ipfs://')) return null
|
|
21
|
+
|
|
22
|
+
const match = tokenURI.match(/^data:application\/json;base64,(.+)$/i)
|
|
23
|
+
if (!match) return null
|
|
24
|
+
|
|
25
|
+
// Clean up malformed base64: trim everything after the last "==" padding
|
|
26
|
+
let b64 = match[1]
|
|
27
|
+
const lastDoubleEq = b64.lastIndexOf('==')
|
|
28
|
+
if (lastDoubleEq > 0 && lastDoubleEq < b64.length - 2) {
|
|
29
|
+
b64 = b64.substring(0, lastDoubleEq + 2)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const decoded = Buffer.from(b64, 'base64').toString('utf-8')
|
|
34
|
+
// Try JSON parse first
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(decoded)
|
|
37
|
+
} catch {
|
|
38
|
+
// Unterminated JSON (contract bug): append missing closing quotes/braces
|
|
39
|
+
let fixed = decoded
|
|
40
|
+
// Count unclosed quotes
|
|
41
|
+
const quoteCount = (fixed.match(/"/g) || []).length
|
|
42
|
+
if (quoteCount % 2 !== 0) fixed += '"'
|
|
43
|
+
// Count unclosed braces
|
|
44
|
+
const openBraces = (fixed.match(/\{/g) || []).length
|
|
45
|
+
const closeBraces = (fixed.match(/\}/g) || []).length
|
|
46
|
+
for (let i = closeBraces; i < openBraces; i++) fixed += '}'
|
|
47
|
+
try { return JSON.parse(fixed) } catch { /* ok */ }
|
|
48
|
+
}
|
|
49
|
+
// Regex fallback
|
|
50
|
+
const nameM = decoded.match(/"name"\s*:\s*"([^"]*)/)
|
|
51
|
+
if (nameM) return { name: nameM[1] }
|
|
52
|
+
return null
|
|
53
|
+
} catch { return null }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Extract CID from IPFS tokenURI
|
|
57
|
+
function extractCID(tokenURI: string): string | null {
|
|
58
|
+
if (!tokenURI) return null
|
|
59
|
+
if (tokenURI.startsWith('ipfs://')) return tokenURI.replace('ipfs://', '').split('/')[0]
|
|
60
|
+
const match = tokenURI.match(/\/ipfs\/([^/?#]+)/)
|
|
61
|
+
if (match) return match[1]
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function syncAgents(): Promise<{ synced: number; total: number }> {
|
|
66
|
+
const provider = new ethers.JsonRpcProvider(config.rpcUrlOxaChain)
|
|
67
|
+
const contract = new ethers.Contract(config.identityRegistryOxaChain, IDENTITY_ABI, provider)
|
|
68
|
+
const pool = getPool()
|
|
69
|
+
|
|
70
|
+
let synced = 0
|
|
71
|
+
let consecutiveMisses = 0
|
|
72
|
+
const MAX_MISSES = 8
|
|
73
|
+
const BATCH_SIZE = 10
|
|
74
|
+
|
|
75
|
+
for (let batchStart = 1; consecutiveMisses < MAX_MISSES; batchStart += BATCH_SIZE) {
|
|
76
|
+
const batchIds: number[] = []
|
|
77
|
+
for (let i = batchStart; i < batchStart + BATCH_SIZE && consecutiveMisses < MAX_MISSES; i++) {
|
|
78
|
+
batchIds.push(i)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const results = await Promise.allSettled(
|
|
82
|
+
batchIds.map(async (id) => {
|
|
83
|
+
const [tokenURI, owner] = await Promise.all([
|
|
84
|
+
contract.tokenURI(id).catch(() => null),
|
|
85
|
+
contract.ownerOf(id).catch(() => null),
|
|
86
|
+
])
|
|
87
|
+
|
|
88
|
+
if (!tokenURI) {
|
|
89
|
+
consecutiveMisses++
|
|
90
|
+
return null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
consecutiveMisses = 0
|
|
94
|
+
const parsed = parseTokenURIToJSON(tokenURI)
|
|
95
|
+
|
|
96
|
+
const name = (parsed?.name as string) || `Agent ${id}`
|
|
97
|
+
const description = (parsed?.description as string) || ''
|
|
98
|
+
const tags = Array.isArray(parsed?.tags) ? parsed.tags.map(String) : []
|
|
99
|
+
const capabilities = Array.isArray(parsed?.capabilities) ? parsed.capabilities.map(String) : []
|
|
100
|
+
|
|
101
|
+
await pool.query(
|
|
102
|
+
`INSERT INTO agents (id, owner, name, description, tags, capabilities, token_uri, metadata_json, synced_at, updated_at)
|
|
103
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,NOW(),NOW())
|
|
104
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
105
|
+
owner = EXCLUDED.owner,
|
|
106
|
+
name = EXCLUDED.name,
|
|
107
|
+
description = EXCLUDED.description,
|
|
108
|
+
tags = EXCLUDED.tags,
|
|
109
|
+
capabilities = EXCLUDED.capabilities,
|
|
110
|
+
token_uri = EXCLUDED.token_uri,
|
|
111
|
+
metadata_json = EXCLUDED.metadata_json,
|
|
112
|
+
synced_at = NOW(),
|
|
113
|
+
updated_at = NOW()`,
|
|
114
|
+
[id, owner || '', name, description, tags, capabilities, tokenURI, JSON.stringify(parsed || {})]
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
return { id, name, owner }
|
|
118
|
+
})
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
synced += results.filter(r => r.status === 'fulfilled' && r.value !== null).length
|
|
122
|
+
|
|
123
|
+
if (consecutiveMisses >= MAX_MISSES) break
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return { synced, total: synced }
|
|
127
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"sourceMap": true,
|
|
8
|
+
"outDir": "./dist",
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true,
|
|
14
|
+
"resolveJsonModule": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|