@hivemind-os/collective-relay 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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/server/http-server.ts","../src/health/monitor.ts","../src/identity/relay-identity.ts","../src/payment/payment-gate.ts","../src/payment/fee-schedule.ts","../src/registry/relay-registry-service.ts","../src/routing/message-types.ts","../src/routing/router.ts","../src/routing/session-manager.ts","../src/server/middleware.ts","../src/server/routes.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url';\n\nimport { loadRelayConfig } from './config.js';\nimport { createRelayServer } from './server/http-server.js';\n\nexport * from './config.js';\nexport * from './server/http-server.js';\nexport * from './server/middleware.js';\nexport * from './server/routes.js';\nexport * from './routing/message-types.js';\nexport * from './routing/router.js';\nexport * from './routing/session-manager.js';\nexport * from './payment/payment-gate.js';\nexport * from './payment/fee-schedule.js';\nexport * from './identity/relay-identity.js';\nexport * from './health/monitor.js';\nexport * from './registry/relay-registry-service.js';\n\nexport async function startRelayServer() {\n const config = loadRelayConfig();\n const relay = await createRelayServer(config);\n const address = await relay.start();\n return { relay, address };\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n try {\n const { relay, address } = await startRelayServer();\n relay.app.log.info({ address, relayDid: relay.identity.did }, 'Relay server started');\n } catch (error) {\n console.error(error);\n process.exitCode = 1;\n }\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface RelayConfig {\n host: string;\n port: number;\n identity: {\n keyPath: string;\n };\n fees: {\n basePercentage: number;\n minimumMist: bigint;\n };\n limits: {\n maxConnections: number;\n maxRequestsPerSecond: number;\n taskTimeoutMs: number;\n heartbeatIntervalMs: number;\n heartbeatTimeoutMs: number;\n authNonceTtlMs: number;\n };\n cors?: {\n allowedOrigins: string[];\n };\n sui?: {\n rpcUrl: string;\n packageId: string;\n };\n relayRegistry?: {\n enabled: boolean;\n relayId?: string;\n stakePositionId?: string;\n endpoint?: string;\n capabilities: string[];\n region?: string;\n routingFeeBps?: number;\n heartbeatIntervalMs: number;\n };\n}\n\nexport function getDefaultRelayConfig(baseDir = resolve(homedir(), '.hivemind-os/collective', 'relay')): RelayConfig {\n return {\n host: '0.0.0.0',\n port: 8080,\n identity: {\n keyPath: join(baseDir, 'identity.key'),\n },\n fees: {\n basePercentage: 5,\n minimumMist: 1_000n,\n },\n limits: {\n maxConnections: 1_000,\n maxRequestsPerSecond: 100,\n taskTimeoutMs: 30_000,\n heartbeatIntervalMs: 10_000,\n heartbeatTimeoutMs: 30_000,\n authNonceTtlMs: 5 * 60_000,\n },\n cors: {\n allowedOrigins: [],\n },\n };\n}\n\nexport function loadRelayConfig(overrides: Partial<RelayConfig> = {}): RelayConfig {\n const dataDir = process.env.COLLECTIVE_RELAY_DATA_DIR ? resolve(process.env.COLLECTIVE_RELAY_DATA_DIR) : undefined;\n const defaults = getDefaultRelayConfig(dataDir);\n\n const config: RelayConfig = {\n host: process.env.COLLECTIVE_RELAY_HOST ?? overrides.host ?? defaults.host,\n port: readNumber(process.env.COLLECTIVE_RELAY_PORT) ?? overrides.port ?? defaults.port,\n identity: {\n keyPath: resolve(overrides.identity?.keyPath ?? process.env.COLLECTIVE_RELAY_KEY_PATH ?? defaults.identity.keyPath),\n },\n fees: {\n basePercentage:\n readNumber(process.env.COLLECTIVE_RELAY_FEE_PERCENT) ?? overrides.fees?.basePercentage ?? defaults.fees.basePercentage,\n minimumMist:\n readBigInt(process.env.COLLECTIVE_RELAY_MINIMUM_MIST) ?? overrides.fees?.minimumMist ?? defaults.fees.minimumMist,\n },\n limits: {\n maxConnections:\n readNumber(process.env.COLLECTIVE_RELAY_MAX_CONNECTIONS) ??\n overrides.limits?.maxConnections ??\n defaults.limits.maxConnections,\n maxRequestsPerSecond:\n readNumber(process.env.COLLECTIVE_RELAY_MAX_RPS) ??\n overrides.limits?.maxRequestsPerSecond ??\n defaults.limits.maxRequestsPerSecond,\n taskTimeoutMs:\n readNumber(process.env.COLLECTIVE_RELAY_TASK_TIMEOUT_MS) ??\n overrides.limits?.taskTimeoutMs ??\n defaults.limits.taskTimeoutMs,\n heartbeatIntervalMs:\n readNumber(process.env.COLLECTIVE_RELAY_HEARTBEAT_INTERVAL_MS) ??\n overrides.limits?.heartbeatIntervalMs ??\n defaults.limits.heartbeatIntervalMs,\n heartbeatTimeoutMs:\n readNumber(process.env.COLLECTIVE_RELAY_HEARTBEAT_TIMEOUT_MS) ??\n overrides.limits?.heartbeatTimeoutMs ??\n defaults.limits.heartbeatTimeoutMs,\n authNonceTtlMs:\n readNumber(process.env.COLLECTIVE_RELAY_AUTH_NONCE_TTL_MS) ??\n overrides.limits?.authNonceTtlMs ??\n defaults.limits.authNonceTtlMs,\n },\n cors: {\n allowedOrigins:\n overrides.cors?.allowedOrigins ??\n readStringList(process.env.COLLECTIVE_RELAY_ALLOWED_ORIGINS) ??\n defaults.cors?.allowedOrigins ??\n [],\n },\n sui:\n overrides.sui || process.env.COLLECTIVE_RELAY_SUI_RPC_URL || process.env.COLLECTIVE_RELAY_SUI_PACKAGE_ID\n ? {\n rpcUrl: overrides.sui?.rpcUrl ?? process.env.COLLECTIVE_RELAY_SUI_RPC_URL ?? '',\n packageId: overrides.sui?.packageId ?? process.env.COLLECTIVE_RELAY_SUI_PACKAGE_ID ?? '',\n }\n : undefined,\n relayRegistry:\n overrides.relayRegistry ||\n process.env.COLLECTIVE_RELAY_REGISTRY_ENABLED ||\n process.env.COLLECTIVE_RELAY_REGISTRY_STAKE_ID ||\n process.env.COLLECTIVE_RELAY_REGISTRY_RELAY_ID\n ? {\n enabled: readBoolean(process.env.COLLECTIVE_RELAY_REGISTRY_ENABLED) ?? overrides.relayRegistry?.enabled ?? true,\n relayId: overrides.relayRegistry?.relayId ?? process.env.COLLECTIVE_RELAY_REGISTRY_RELAY_ID,\n stakePositionId: overrides.relayRegistry?.stakePositionId ?? process.env.COLLECTIVE_RELAY_REGISTRY_STAKE_ID,\n endpoint: overrides.relayRegistry?.endpoint ?? process.env.COLLECTIVE_RELAY_REGISTRY_ENDPOINT,\n capabilities:\n overrides.relayRegistry?.capabilities ?? readStringList(process.env.COLLECTIVE_RELAY_REGISTRY_CAPABILITIES) ?? [],\n region: overrides.relayRegistry?.region ?? process.env.COLLECTIVE_RELAY_REGISTRY_REGION,\n routingFeeBps:\n readNumber(process.env.COLLECTIVE_RELAY_REGISTRY_FEE_BPS) ?? overrides.relayRegistry?.routingFeeBps,\n heartbeatIntervalMs:\n readNumber(process.env.COLLECTIVE_RELAY_REGISTRY_HEARTBEAT_INTERVAL_MS) ??\n overrides.relayRegistry?.heartbeatIntervalMs ??\n defaults.limits.heartbeatIntervalMs,\n }\n : undefined,\n };\n\n validateRelayConfig(config);\n return config;\n}\n\nexport function validateRelayConfig(config: RelayConfig): void {\n if (!config.host) {\n throw new Error('Relay host is required.');\n }\n\n if (!Number.isInteger(config.port) || config.port <= 0) {\n throw new Error('Relay port must be a positive integer.');\n }\n\n if (!config.identity.keyPath) {\n throw new Error('Relay identity keyPath is required.');\n }\n\n if (config.fees.basePercentage < 0) {\n throw new Error('Relay base fee percentage must be non-negative.');\n }\n\n if (config.fees.minimumMist < 0n) {\n throw new Error('Relay minimum fee must be non-negative.');\n }\n\n for (const [name, value] of Object.entries(config.limits)) {\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`Relay limit ${name} must be a positive integer.`);\n }\n }\n\n if (config.cors && config.cors.allowedOrigins.some((origin) => origin.trim().length === 0)) {\n throw new Error('Relay CORS allowed origins must be non-empty strings.');\n }\n\n if (!config.relayRegistry || config.relayRegistry.enabled === false) {\n return;\n }\n\n if (!config.sui?.rpcUrl || !config.sui.packageId) {\n throw new Error('Relay registry integration requires sui.rpcUrl and sui.packageId.');\n }\n\n if (config.relayRegistry.stakePositionId && !/^0x[0-9a-f]+$/i.test(config.relayRegistry.stakePositionId)) {\n throw new Error('Relay registry stakePositionId must be a 0x-prefixed object id.');\n }\n\n if (config.relayRegistry.relayId && !/^0x[0-9a-f]+$/i.test(config.relayRegistry.relayId)) {\n throw new Error('Relay registry relayId must be a 0x-prefixed object id.');\n }\n\n if (config.relayRegistry.routingFeeBps !== undefined) {\n if (!Number.isInteger(config.relayRegistry.routingFeeBps) || config.relayRegistry.routingFeeBps < 0 || config.relayRegistry.routingFeeBps > 10_000) {\n throw new Error('Relay registry routingFeeBps must be an integer between 0 and 10000.');\n }\n }\n\n if (!Number.isInteger(config.relayRegistry.heartbeatIntervalMs) || config.relayRegistry.heartbeatIntervalMs <= 0) {\n throw new Error('Relay registry heartbeat interval must be a positive integer.');\n }\n}\n\nfunction readNumber(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\nfunction readBigInt(value: string | undefined): bigint | undefined {\n if (!value) {\n return undefined;\n }\n\n return /^\\d+$/.test(value.trim()) ? BigInt(value.trim()) : undefined;\n}\n\nfunction readBoolean(value: string | undefined): boolean | undefined {\n if (!value) {\n return undefined;\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === 'true' || normalized === '1' || normalized === 'yes') {\n return true;\n }\n if (normalized === 'false' || normalized === '0' || normalized === 'no') {\n return false;\n }\n return undefined;\n}\n\nfunction readStringList(value: string | undefined): string[] | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = value\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean);\n\n return parsed.length > 0 ? parsed : undefined;\n}\n","import cors from '@fastify/cors';\nimport rateLimit from '@fastify/rate-limit';\nimport websocket from '@fastify/websocket';\nimport Fastify, { type FastifyInstance } from 'fastify';\nimport WebSocket from 'ws';\n\nimport type { RelayConfig } from '../config.js';\nimport { HealthMonitor } from '../health/monitor.js';\nimport { RelayIdentity } from '../identity/relay-identity.js';\nimport { PaymentGate } from '../payment/payment-gate.js';\nimport { RelayRegistryService, type RelayRegistryRuntime } from '../registry/relay-registry-service.js';\nimport { parseProviderMessage, serializeRelayMessage } from '../routing/message-types.js';\nimport { RelayRouter } from '../routing/router.js';\nimport { SessionManager } from '../routing/session-manager.js';\nimport { registerMeshMiddleware } from './middleware.js';\nimport { registerRelayRoutes } from './routes.js';\n\nconst RELAY_VERSION = '0.1.0';\n\nexport interface RelayServer {\n app: FastifyInstance;\n config: RelayConfig;\n identity: RelayIdentity;\n sessionManager: SessionManager;\n router: RelayRouter;\n paymentGate: PaymentGate;\n healthMonitor: HealthMonitor;\n relayRegistry?: RelayRegistryRuntime;\n start: () => Promise<string>;\n}\n\nexport interface RelayServerOptions {\n relayRegistry?: RelayRegistryRuntime;\n}\n\nexport async function createRelayServer(config: RelayConfig, options: RelayServerOptions = {}): Promise<RelayServer> {\n const app = Fastify({\n logger: {\n level: 'info',\n },\n });\n const identity = RelayIdentity.load(config.identity.keyPath);\n const sessionManager = new SessionManager({\n maxConnections: config.limits.maxConnections,\n heartbeatTimeoutMs: config.limits.heartbeatTimeoutMs,\n authNonceTtlMs: config.limits.authNonceTtlMs,\n });\n const router = new RelayRouter({\n sessionManager,\n taskTimeoutMs: config.limits.taskTimeoutMs,\n });\n const paymentGate = new PaymentGate({\n relayDid: identity.did,\n feeSchedule: config.fees,\n });\n const healthMonitor = new HealthMonitor({\n getConnectedProviders: () => sessionManager.getConnectedProviders().length,\n });\n const relayRegistry = options.relayRegistry ?? new RelayRegistryService(config, identity);\n\n await app.register(cors, {\n origin: (origin, callback) => {\n const allowedOrigins = config.cors?.allowedOrigins ?? [];\n if (!origin) {\n callback(null, false);\n return;\n }\n\n callback(null, allowedOrigins.includes(origin));\n },\n });\n app.register(rateLimit, {\n max: config.limits.maxRequestsPerSecond,\n timeWindow: '1 second',\n });\n await app.register(websocket);\n registerMeshMiddleware(app, identity.did);\n await registerRelayRoutes(app, {\n relayDid: identity.did,\n version: RELAY_VERSION,\n config,\n sessionManager,\n router,\n paymentGate,\n healthMonitor,\n relayRegistry,\n });\n\n app.get('/v1/ws', { websocket: true }, (socket) => {\n attachProviderSocket({\n ws: normalizeWebSocket(socket),\n identity,\n sessionManager,\n router,\n });\n });\n\n const heartbeatSweep = setInterval(() => {\n sessionManager.sweepExpiredSessions();\n paymentGate.pruneExpiredChallenges();\n }, Math.max(1_000, Math.floor(config.limits.heartbeatIntervalMs / 2)));\n\n app.addHook('onClose', async () => {\n clearInterval(heartbeatSweep);\n await relayRegistry.stop();\n router.close();\n sessionManager.disconnectAllSessions();\n });\n\n await app.ready();\n\n return {\n app,\n config,\n identity,\n sessionManager,\n router,\n paymentGate,\n healthMonitor,\n relayRegistry,\n start: async () => {\n const address = await app.listen({ host: config.host, port: config.port });\n const resolvedAddress = typeof address === 'string' ? address : `http://${config.host}:${config.port}`;\n await relayRegistry.start(resolvedAddress);\n return resolvedAddress;\n },\n };\n}\n\nfunction attachProviderSocket(params: {\n ws: WebSocket;\n identity: RelayIdentity;\n sessionManager: SessionManager;\n router: RelayRouter;\n}): void {\n let authenticatedSessionId: string | undefined;\n const authTimeout = setTimeout(() => {\n if (authenticatedSessionId) {\n return;\n }\n\n safeSend(params.ws, serializeRelayMessage({ type: 'auth_fail', reason: 'Authentication timeout.' }));\n safeClose(params.ws, 4003, 'Authentication timeout');\n }, 5_000);\n\n params.ws.on('message', (payload) => {\n const message = parseProviderMessage(payload);\n if (!message) {\n clearTimeout(authTimeout);\n safeSend(params.ws, serializeRelayMessage({ type: 'auth_fail', reason: 'Invalid relay message.' }));\n safeClose(params.ws, 4004, 'Invalid relay message');\n return;\n }\n\n if (!authenticatedSessionId) {\n if (message.type !== 'auth') {\n clearTimeout(authTimeout);\n safeSend(params.ws, serializeRelayMessage({ type: 'auth_fail', reason: 'Authentication required.' }));\n safeClose(params.ws, 4005, 'Authentication required');\n return;\n }\n\n try {\n const session = params.sessionManager.registerSession(params.ws, message);\n authenticatedSessionId = session.sessionId;\n clearTimeout(authTimeout);\n safeSend(\n params.ws,\n serializeRelayMessage({\n type: 'auth_ok',\n sessionId: session.sessionId,\n relayDid: params.identity.did,\n }),\n );\n } catch (error) {\n clearTimeout(authTimeout);\n safeSend(\n params.ws,\n serializeRelayMessage({\n type: 'auth_fail',\n reason: error instanceof Error ? error.message : 'Authentication failed.',\n }),\n );\n safeClose(params.ws, 4006, 'Authentication failed');\n }\n return;\n }\n\n if (message.type === 'auth') {\n safeSend(params.ws, serializeRelayMessage({ type: 'auth_fail', reason: 'Session already authenticated.' }));\n return;\n }\n\n if (message.type === 'heartbeat') {\n if (message.sessionId !== authenticatedSessionId) {\n safeClose(params.ws, 4007, 'Session mismatch');\n return;\n }\n\n params.sessionManager.handleHeartbeat(authenticatedSessionId);\n safeSend(params.ws, serializeRelayMessage({ type: 'heartbeat_ack' }));\n return;\n }\n\n try {\n params.router.handleProviderMessage(authenticatedSessionId, message);\n } catch (error) {\n safeClose(params.ws, 4008, error instanceof Error ? error.message : 'Provider message rejected');\n }\n });\n\n const cleanup = () => {\n clearTimeout(authTimeout);\n if (authenticatedSessionId) {\n params.sessionManager.removeSession(authenticatedSessionId);\n }\n };\n\n params.ws.once('close', cleanup);\n params.ws.once('error', cleanup);\n}\n\nfunction normalizeWebSocket(socket: WebSocket | { socket?: WebSocket }): WebSocket {\n if (\n 'on' in socket &&\n typeof socket.on === 'function' &&\n 'send' in socket &&\n typeof socket.send === 'function' &&\n 'close' in socket &&\n typeof socket.close === 'function'\n ) {\n return socket;\n }\n\n if ('socket' in socket && socket.socket) {\n return socket.socket;\n }\n\n throw new Error('Fastify websocket route did not provide a WebSocket connection.');\n}\n\nfunction safeSend(ws: WebSocket, message: string): void {\n if (ws.readyState !== WebSocket.OPEN) {\n return;\n }\n\n ws.send(message);\n}\n\nfunction safeClose(ws: WebSocket, code: number, reason: string): void {\n if (ws.readyState === WebSocket.CLOSED) {\n return;\n }\n\n ws.close(code, reason);\n}\n","export interface HealthMonitorStatus {\n status: 'healthy' | 'degraded' | 'unhealthy';\n uptime: number;\n connectedProviders: number;\n activeRequests: number;\n totalRequestsServed: number;\n averageLatencyMs: number;\n}\n\nexport interface HealthMonitorOptions {\n now?: () => number;\n getConnectedProviders?: () => number;\n}\n\nexport class HealthMonitor {\n private readonly now: () => number;\n private readonly startedAt: number;\n private activeRequests = 0;\n private connectedProviders = 0;\n private totalRequestsServed = 0;\n private totalLatencyMs = 0;\n\n constructor(private readonly options: HealthMonitorOptions = {}) {\n this.now = options.now ?? (() => Date.now());\n this.startedAt = this.now();\n }\n\n setConnectedProviders(count: number): void {\n this.connectedProviders = count;\n }\n\n beginRequest(): { finish: () => void } {\n const startedAt = this.now();\n let finished = false;\n this.activeRequests += 1;\n\n return {\n finish: () => {\n if (finished) {\n return;\n }\n\n finished = true;\n this.activeRequests -= 1;\n this.totalRequestsServed += 1;\n this.totalLatencyMs += this.now() - startedAt;\n },\n };\n }\n\n recordRequest(latencyMs: number): void {\n this.totalRequestsServed += 1;\n this.totalLatencyMs += latencyMs;\n }\n\n getStatus(): HealthMonitorStatus {\n const connectedProviders = this.options.getConnectedProviders?.() ?? this.connectedProviders;\n let status: HealthMonitorStatus['status'] = 'healthy';\n\n if (connectedProviders === 0 && this.activeRequests > 0) {\n status = 'unhealthy';\n } else if (connectedProviders === 0) {\n status = 'degraded';\n }\n\n return {\n status,\n uptime: this.now() - this.startedAt,\n connectedProviders,\n activeRequests: this.activeRequests,\n totalRequestsServed: this.totalRequestsServed,\n averageLatencyMs:\n this.totalRequestsServed === 0 ? 0 : Math.round(this.totalLatencyMs / this.totalRequestsServed),\n };\n }\n}\n","import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\n\nimport { createDID, generateKeypair, keypairFromSecretKey, signString, type SimpleKeypair } from '@hivemind-os/collective-core';\nimport type { DID } from '@hivemind-os/collective-types';\n\nexport class RelayIdentity {\n readonly did: DID;\n\n private constructor(\n readonly keyPath: string,\n readonly keypair: SimpleKeypair,\n ) {\n this.did = createDID(keypair.publicKey);\n }\n\n static load(keyPath: string): RelayIdentity {\n const resolvedKeyPath = resolve(keyPath);\n mkdirSync(dirname(resolvedKeyPath), { recursive: true, mode: 0o700 });\n\n if (existsSync(resolvedKeyPath)) {\n chmodSync(resolvedKeyPath, 0o600);\n const secretKey = Uint8Array.from(Buffer.from(readFileSync(resolvedKeyPath, 'utf8').trim(), 'hex'));\n return new RelayIdentity(resolvedKeyPath, keypairFromSecretKey(secretKey));\n }\n\n const keypair = generateKeypair();\n writeFileSync(resolvedKeyPath, Buffer.from(keypair.secretKey).toString('hex'), { mode: 0o600 });\n chmodSync(resolvedKeyPath, 0o600);\n return new RelayIdentity(resolvedKeyPath, keypair);\n }\n\n signPayload(payload: string): string {\n return signString(payload, this.keypair.secretKey);\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport {\n decodeRelaySuiPaymentProof,\n verifyRelaySuiPaymentProof,\n USDC_ADDRESS,\n} from '@hivemind-os/collective-core';\nimport { PaymentRail } from '@hivemind-os/collective-types';\nimport {\n decodePaymentSignatureHeader,\n encodePaymentRequiredHeader,\n encodePaymentResponseHeader,\n} from '@x402/core/http';\nimport { PERMIT2_ADDRESS, permit2WitnessTypes, x402ExactPermit2ProxyAddress } from '@x402/evm';\nimport { getAddress, verifyTypedData } from 'viem';\n\nimport type { ProviderSession } from '../routing/session-manager.js';\nimport { calculateRelayFee, type RelayFeeBreakdown, type RelayFeeSchedule } from './fee-schedule.js';\n\nconst DEFAULT_X402_NETWORK = 'base-sepolia';\nconst DEFAULT_EVM_PAYMENT_ADDRESS = '0x0000000000000000000000000000000000000abc';\n\nexport interface PaymentChallenge {\n rail: PaymentRail;\n paymentAddress: string;\n amount: string;\n currency: string;\n network: string;\n relayFee: string;\n expiresAt: number;\n nonce: string;\n asset?: string;\n extra?: Record<string, string>;\n}\n\nexport interface PaymentVerification {\n accepted: boolean;\n settlementReference?: string;\n relayFee?: string;\n totalPrice?: string;\n payer?: string;\n reason?: string;\n}\n\nexport interface PaymentGateOptions {\n relayDid: string;\n feeSchedule: RelayFeeSchedule;\n paymentAddress?: string;\n evmPaymentAddress?: string;\n defaultRail?: PaymentRail;\n challengeTtlMs?: number;\n now?: () => number;\n nonceFactory?: () => string;\n basePriceResolver?: (capability: string, provider: ProviderSession) => bigint;\n verifyPaymentProof?: (paymentHeader: string, challenge: PaymentChallenge) => Promise<PaymentVerification>;\n}\n\ninterface Permit2Authorization {\n from: string;\n permitted: {\n token: string;\n amount: string;\n };\n spender: string;\n nonce: string;\n deadline: string;\n witness: {\n to: string;\n validAfter: string;\n };\n}\n\ninterface Permit2Payload {\n signature: `0x${string}`;\n permit2Authorization: Permit2Authorization;\n}\n\ninterface PaymentReplayMetadata {\n key: string;\n expiresAt: number;\n}\n\nexport class PaymentGate {\n private readonly activeChallenges = new Map<string, PaymentChallenge>();\n private readonly consumedProofs = new Map<string, number>();\n private readonly now: () => number;\n private readonly nonceFactory: () => string;\n private readonly basePriceResolver: (capability: string, provider: ProviderSession) => bigint;\n readonly defaultRail: PaymentRail;\n\n constructor(private readonly options: PaymentGateOptions) {\n this.now = options.now ?? (() => Date.now());\n this.nonceFactory = options.nonceFactory ?? (() => randomUUID());\n this.basePriceResolver = options.basePriceResolver ?? (() => 0n);\n this.defaultRail = options.defaultRail ?? PaymentRail.SUI_TRANSFER;\n }\n\n generate402Challenge(rail: PaymentRail, capability: string, provider: ProviderSession): PaymentChallenge {\n const basePrice = this.basePriceResolver(capability, provider);\n const fee = this.calculateFee(basePrice);\n const nonce = this.nonceFactory();\n const expiresAt = this.now() + (this.options.challengeTtlMs ?? 60_000);\n\n const challenge =\n rail === PaymentRail.X402_BASE\n ? this.createX402Challenge(fee, nonce, expiresAt)\n : this.createSuiChallenge(rail, fee, nonce, expiresAt);\n\n this.activeChallenges.set(challenge.nonce, challenge);\n return challenge;\n }\n\n getChallenge(nonce: string): PaymentChallenge | null {\n return this.activeChallenges.get(nonce) ?? null;\n }\n\n isChallengeExpired(challenge: PaymentChallenge): boolean {\n return challenge.expiresAt <= this.now();\n }\n\n async verifyPayment(paymentHeader: string, challenge: PaymentChallenge): Promise<PaymentVerification> {\n this.pruneConsumedProofs();\n\n if (!this.activeChallenges.has(challenge.nonce)) {\n return {\n accepted: false,\n reason: 'Unknown payment challenge.',\n };\n }\n\n if (this.isChallengeExpired(challenge)) {\n this.activeChallenges.delete(challenge.nonce);\n return {\n accepted: false,\n reason: 'Payment challenge expired.',\n };\n }\n\n const replayMetadata = getPaymentReplayMetadata(paymentHeader, challenge);\n if (replayMetadata && this.consumedProofs.has(replayMetadata.key)) {\n return {\n accepted: false,\n reason: 'Payment proof has already been used.',\n };\n }\n\n const verifier = this.options.verifyPaymentProof;\n const verification = verifier\n ? await verifier(paymentHeader, challenge)\n : await this.verifyChallenge(paymentHeader, challenge);\n\n if (verification.accepted) {\n this.activeChallenges.delete(challenge.nonce);\n if (replayMetadata) {\n this.consumedProofs.set(replayMetadata.key, replayMetadata.expiresAt);\n }\n }\n\n return verification;\n }\n\n calculateFee(basePrice: bigint): RelayFeeBreakdown {\n return calculateRelayFee(basePrice, this.options.feeSchedule);\n }\n\n pruneExpiredChallenges(): number {\n this.pruneConsumedProofs();\n\n let removed = 0;\n for (const challenge of this.activeChallenges.values()) {\n if (!this.isChallengeExpired(challenge)) {\n continue;\n }\n\n this.activeChallenges.delete(challenge.nonce);\n removed += 1;\n }\n\n return removed;\n }\n\n private pruneConsumedProofs(): void {\n const now = this.now();\n for (const [replayKey, expiresAt] of this.consumedProofs.entries()) {\n if (expiresAt > now) {\n continue;\n }\n\n this.consumedProofs.delete(replayKey);\n }\n }\n\n private createSuiChallenge(\n rail: PaymentRail,\n fee: RelayFeeBreakdown,\n nonce: string,\n expiresAt: number,\n ): PaymentChallenge {\n return {\n rail,\n paymentAddress: this.options.paymentAddress ?? this.options.relayDid,\n amount: fee.totalPrice.toString(),\n currency: 'MIST',\n network: 'sui',\n relayFee: fee.relayFee.toString(),\n expiresAt,\n nonce,\n };\n }\n\n private createX402Challenge(fee: RelayFeeBreakdown, nonce: string, expiresAt: number): PaymentChallenge {\n const network = DEFAULT_X402_NETWORK;\n const asset = USDC_ADDRESS[network];\n const paymentAddress = this.options.evmPaymentAddress ?? DEFAULT_EVM_PAYMENT_ADDRESS;\n const paymentRequiredHeader = encodePaymentRequiredHeader({\n x402Version: 2,\n resource: { url: 'https://relay.hivemind-collective.local/execute' },\n accepts: [\n {\n scheme: 'exact',\n network: toCaip2Network(network),\n asset,\n amount: fee.totalPrice.toString(),\n payTo: paymentAddress,\n maxTimeoutSeconds: Math.max(1, Math.ceil((expiresAt - this.now()) / 1_000)),\n extra: {\n assetTransferMethod: 'permit2',\n currency: 'USDC',\n nonce,\n expiresAt: String(expiresAt),\n },\n },\n ],\n });\n\n return {\n rail: PaymentRail.X402_BASE,\n paymentAddress,\n amount: fee.totalPrice.toString(),\n currency: 'USDC',\n network,\n relayFee: fee.relayFee.toString(),\n expiresAt,\n nonce,\n asset,\n extra: {\n assetTransferMethod: 'permit2',\n currency: 'USDC',\n nonce,\n expiresAt: String(expiresAt),\n 'payment-required': paymentRequiredHeader,\n },\n };\n }\n\n private async verifyChallenge(paymentHeader: string, challenge: PaymentChallenge): Promise<PaymentVerification> {\n switch (challenge.rail) {\n case PaymentRail.X402_BASE:\n return verifyX402Payment(paymentHeader, challenge);\n case PaymentRail.SUI_TRANSFER:\n case PaymentRail.SUI_ESCROW:\n return verifySuiPayment(paymentHeader, challenge);\n default:\n return {\n accepted: false,\n reason: `Unsupported payment rail: ${String(challenge.rail)}`,\n };\n }\n }\n}\n\nasync function verifyX402Payment(paymentHeader: string, challenge: PaymentChallenge): Promise<PaymentVerification> {\n try {\n const payment = decodePaymentSignatureHeader(paymentHeader);\n const accepted = payment.accepted;\n if (\n accepted.scheme !== 'exact' ||\n accepted.amount !== challenge.amount ||\n normalizeNetwork(accepted.network) !== normalizeNetwork(toCaip2Network(challenge.network)) ||\n getAddress(accepted.payTo) !== getAddress(challenge.paymentAddress) ||\n (challenge.asset && getAddress(accepted.asset) !== getAddress(challenge.asset))\n ) {\n return {\n accepted: false,\n reason: 'x402 payment requirements did not match the relay challenge.',\n };\n }\n\n if (!hasPermit2Authorization(payment.payload)) {\n return {\n accepted: false,\n reason: 'Only Permit2 x402 payments are currently supported by the relay.',\n };\n }\n\n const authorization = payment.payload.permit2Authorization;\n const verified = await verifyTypedData({\n address: getAddress(authorization.from),\n domain: {\n name: 'Permit2',\n chainId: toChainId(challenge.network),\n verifyingContract: PERMIT2_ADDRESS,\n },\n types: permit2WitnessTypes,\n primaryType: 'PermitWitnessTransferFrom',\n message: {\n permitted: {\n token: getAddress(authorization.permitted.token),\n amount: BigInt(authorization.permitted.amount),\n },\n spender: getAddress(authorization.spender),\n nonce: BigInt(authorization.nonce),\n deadline: BigInt(authorization.deadline),\n witness: {\n to: getAddress(authorization.witness.to),\n validAfter: BigInt(authorization.witness.validAfter),\n },\n },\n signature: payment.payload.signature,\n });\n\n const deadlineMs = deadlineToTimestampMs(authorization.deadline);\n if (\n !verified ||\n getAddress(authorization.witness.to) !== getAddress(challenge.paymentAddress) ||\n getAddress(authorization.permitted.token) !== getAddress(challenge.asset ?? authorization.permitted.token) ||\n authorization.permitted.amount !== challenge.amount ||\n getAddress(authorization.spender) !== getAddress(x402ExactPermit2ProxyAddress) ||\n deadlineMs === null ||\n deadlineMs > challenge.expiresAt + 1_000\n ) {\n return {\n accepted: false,\n reason: 'x402 payment signature verification failed.',\n };\n }\n\n return {\n accepted: true,\n payer: authorization.from,\n settlementReference: encodePaymentResponseHeader({\n success: true,\n transaction: `x402-${challenge.nonce}`,\n network: toCaip2Network(challenge.network),\n amount: challenge.amount,\n payer: authorization.from,\n }),\n relayFee: challenge.relayFee,\n totalPrice: challenge.amount,\n };\n } catch (error) {\n return {\n accepted: false,\n reason: error instanceof Error ? error.message : 'x402 payment verification failed.',\n };\n }\n}\n\nasync function verifySuiPayment(paymentHeader: string, challenge: PaymentChallenge): Promise<PaymentVerification> {\n try {\n const proof = decodeRelaySuiPaymentProof(paymentHeader);\n if (\n proof.amount !== challenge.amount ||\n proof.nonce !== challenge.nonce ||\n proof.currency !== challenge.currency ||\n proof.network !== challenge.network ||\n proof.paymentAddress !== challenge.paymentAddress ||\n proof.expiresAt !== challenge.expiresAt\n ) {\n return {\n accepted: false,\n reason: 'Sui payment proof did not match the relay challenge.',\n };\n }\n\n if (!verifyRelaySuiPaymentProof(proof)) {\n return {\n accepted: false,\n reason: 'Sui payment proof signature verification failed.',\n };\n }\n\n return {\n accepted: true,\n payer: proof.payerAddress,\n settlementReference: JSON.stringify({\n rail: challenge.rail,\n nonce: challenge.nonce,\n payerDid: proof.payerDid,\n payerAddress: proof.payerAddress,\n }),\n relayFee: challenge.relayFee,\n totalPrice: challenge.amount,\n };\n } catch (error) {\n return {\n accepted: false,\n reason: error instanceof Error ? error.message : 'Sui payment proof verification failed.',\n };\n }\n}\n\nfunction hasPermit2Authorization(value: unknown): value is Permit2Payload {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const candidate = value as { signature?: unknown; permit2Authorization?: Record<string, unknown> };\n const authorization = candidate.permit2Authorization;\n return Boolean(\n typeof candidate.signature === 'string' &&\n authorization &&\n typeof authorization.from === 'string' &&\n typeof authorization.spender === 'string' &&\n typeof authorization.nonce === 'string' &&\n typeof authorization.deadline === 'string' &&\n typeof authorization.witness === 'object' &&\n typeof authorization.permitted === 'object',\n );\n}\n\nfunction getPaymentReplayMetadata(paymentHeader: string, challenge: PaymentChallenge): PaymentReplayMetadata | null {\n try {\n switch (challenge.rail) {\n case PaymentRail.X402_BASE: {\n const payment = decodePaymentSignatureHeader(paymentHeader);\n if (!hasPermit2Authorization(payment.payload)) {\n return null;\n }\n\n const expiresAt = deadlineToTimestampMs(payment.payload.permit2Authorization.deadline) ?? challenge.expiresAt;\n return {\n key: `x402:${payment.payload.signature}`,\n expiresAt,\n };\n }\n case PaymentRail.SUI_TRANSFER:\n case PaymentRail.SUI_ESCROW: {\n const proof = decodeRelaySuiPaymentProof(paymentHeader);\n return {\n key: `sui:${proof.signature}`,\n expiresAt: proof.expiresAt,\n };\n }\n default:\n return null;\n }\n } catch {\n return null;\n }\n}\n\nfunction deadlineToTimestampMs(deadlineSeconds: string): number | null {\n if (!/^\\d+$/.test(deadlineSeconds)) {\n return null;\n }\n\n const deadlineMs = BigInt(deadlineSeconds) * 1_000n;\n if (deadlineMs > BigInt(Number.MAX_SAFE_INTEGER)) {\n return null;\n }\n\n return Number(deadlineMs);\n}\n\nfunction normalizeNetwork(network: string): string {\n return network.trim().toLowerCase();\n}\n\nfunction toChainId(network: string): number {\n switch (normalizeNetwork(network)) {\n case 'base':\n return 8453;\n case 'base-sepolia':\n return 84_532;\n case 'localhost':\n return 31_337;\n default:\n throw new Error(`Unsupported x402 network: ${network}`);\n }\n}\n\nfunction toCaip2Network(network: string): `eip155:${string}` {\n return `eip155:${toChainId(network)}`;\n}\n","export interface RelayFeeSchedule {\n basePercentage: number;\n minimumMist: bigint;\n}\n\nexport interface RelayFeeBreakdown {\n relayFee: bigint;\n totalPrice: bigint;\n}\n\nexport function calculateRelayFee(basePrice: bigint, feeSchedule: RelayFeeSchedule): RelayFeeBreakdown {\n const computed = (basePrice * BigInt(feeSchedule.basePercentage)) / 100n;\n const relayFee = computed > feeSchedule.minimumMist ? computed : feeSchedule.minimumMist;\n\n return {\n relayFee,\n totalPrice: basePrice + relayFee,\n };\n}\n","import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\n\nimport { MeshSuiClient, RelayNodeStatus, RelayRegistryClient, type RelayNode } from '@hivemind-os/collective-core';\n\nimport type { RelayConfig } from '../config.js';\nimport { RelayIdentity } from '../identity/relay-identity.js';\n\nexport interface RelayRegistryRuntimeInfo {\n enabled: boolean;\n registered: boolean;\n relayId?: string;\n operator?: string;\n endpoint?: string;\n stakePositionId?: string;\n capabilities?: string[];\n region?: string;\n status?: 'ACTIVE' | 'INACTIVE' | 'SLASHED';\n routingFeeBps?: number;\n lastHeartbeat?: number;\n totalRouted?: number;\n totalFeesEarnedMist?: string;\n lastError?: string;\n}\n\nexport interface RelayRegistryRuntime {\n start: (serverAddress: string) => Promise<void>;\n stop: () => Promise<void>;\n recordRouting: (feeAmountMist: bigint) => Promise<void>;\n getInfo: () => RelayRegistryRuntimeInfo;\n}\n\nexport class RelayRegistryService implements RelayRegistryRuntime {\n private readonly enabled: boolean;\n private readonly signer: Ed25519Keypair;\n private readonly client?: RelayRegistryClient;\n private heartbeatTimer?: NodeJS.Timeout;\n private state: RelayRegistryRuntimeInfo;\n\n constructor(\n private readonly config: RelayConfig,\n private readonly identity: RelayIdentity,\n client?: RelayRegistryClient,\n ) {\n this.enabled = Boolean(config.relayRegistry?.enabled && config.sui?.rpcUrl && config.sui.packageId && config.relayRegistry.stakePositionId);\n this.signer = Ed25519Keypair.fromSecretKey(identity.keypair.secretKey);\n this.client = client ?? (this.enabled ? new RelayRegistryClient(createRelaySuiClient(config), { packageId: config.sui?.packageId ?? '' }) : undefined);\n this.state = {\n enabled: this.enabled,\n registered: false,\n capabilities: config.relayRegistry?.capabilities ?? [],\n region: config.relayRegistry?.region,\n stakePositionId: config.relayRegistry?.stakePositionId,\n endpoint: config.relayRegistry?.endpoint,\n routingFeeBps: config.relayRegistry?.routingFeeBps,\n };\n }\n\n async start(serverAddress: string): Promise<void> {\n if (!this.enabled || !this.client || !this.config.relayRegistry?.stakePositionId) {\n return;\n }\n\n const endpoint = resolveRelayEndpoint(this.config, serverAddress);\n this.state.endpoint = endpoint;\n this.state.capabilities = this.config.relayRegistry.capabilities;\n this.state.region = this.config.relayRegistry.region;\n this.state.stakePositionId = this.config.relayRegistry.stakePositionId;\n this.state.routingFeeBps = resolveRoutingFeeBps(this.config);\n this.state.operator = this.signer.getPublicKey().toSuiAddress();\n\n try {\n const existing = await this.resolveExistingRelay(endpoint);\n if (existing) {\n this.applyRelay(existing);\n } else {\n const registered = await this.client.registerRelay({\n endpoint,\n stakeId: this.config.relayRegistry.stakePositionId,\n capabilities: this.config.relayRegistry.capabilities,\n region: this.config.relayRegistry.region ?? 'global',\n routingFeeBps: resolveRoutingFeeBps(this.config),\n signer: this.signer,\n });\n await this.refreshRelay(registered.relayId);\n }\n\n await this.sendHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n void this.sendHeartbeat();\n }, this.config.relayRegistry.heartbeatIntervalMs);\n } catch (error) {\n this.state.lastError = error instanceof Error ? error.message : String(error);\n }\n }\n\n async stop(): Promise<void> {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = undefined;\n }\n }\n\n async recordRouting(feeAmountMist: bigint): Promise<void> {\n if (!this.state.relayId) {\n return;\n }\n if (feeAmountMist < 0n) {\n throw new Error('feeAmountMist must be non-negative.');\n }\n\n this.state.totalRouted = (this.state.totalRouted ?? 0) + 1;\n this.state.totalFeesEarnedMist = ((BigInt(this.state.totalFeesEarnedMist ?? '0') + feeAmountMist)).toString();\n this.state.lastError = undefined;\n }\n\n getInfo(): RelayRegistryRuntimeInfo {\n return { ...this.state };\n }\n\n private async sendHeartbeat(): Promise<void> {\n if (!this.client || !this.state.relayId) {\n return;\n }\n\n try {\n const result = await this.client.heartbeat({ relayId: this.state.relayId, signer: this.signer });\n this.state.lastHeartbeat = result.lastHeartbeat;\n this.state.lastError = undefined;\n await this.refreshRelay(this.state.relayId);\n } catch (error) {\n this.state.lastError = error instanceof Error ? error.message : String(error);\n }\n }\n\n private async resolveExistingRelay(endpoint: string): Promise<RelayNode | null> {\n if (!this.client || !this.config.relayRegistry) {\n return null;\n }\n\n if (this.config.relayRegistry.relayId) {\n return await this.client.getRelay(this.config.relayRegistry.relayId);\n }\n\n const operator = this.signer.getPublicKey().toSuiAddress();\n const matches = await this.client.listRelays({\n activeOnly: false,\n operator,\n stakePositionId: this.config.relayRegistry.stakePositionId,\n endpoint,\n });\n return matches.find((relay) => relay.status === RelayNodeStatus.ACTIVE) ?? matches[0] ?? null;\n }\n\n private async refreshRelay(relayId: string): Promise<void> {\n if (!this.client) {\n return;\n }\n const relay = await this.client.getRelay(relayId);\n if (relay) {\n this.applyRelay(relay);\n }\n }\n\n private applyRelay(relay: RelayNode): void {\n this.state = {\n ...this.state,\n enabled: true,\n registered: true,\n relayId: relay.id,\n operator: relay.operator,\n endpoint: relay.endpoint,\n stakePositionId: relay.stakePositionId,\n capabilities: relay.capabilities,\n region: relay.region,\n status: relayStatusToText(relay.status),\n routingFeeBps: relay.routingFeeBps,\n lastHeartbeat: relay.lastHeartbeat,\n totalRouted: relay.totalRouted,\n totalFeesEarnedMist: relay.totalFeesEarnedMist.toString(),\n lastError: undefined,\n };\n }\n}\n\nfunction createRelaySuiClient(config: RelayConfig): MeshSuiClient {\n return new MeshSuiClient({\n rpcUrl: config.sui?.rpcUrl ?? '',\n faucetUrl: config.sui?.rpcUrl ?? '',\n packageId: config.sui?.packageId ?? '',\n registryId: config.sui?.packageId ?? '',\n });\n}\n\nfunction resolveRelayEndpoint(config: RelayConfig, serverAddress: string): string {\n if (config.relayRegistry?.endpoint) {\n return config.relayRegistry.endpoint;\n }\n\n const url = new URL(serverAddress);\n url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';\n url.pathname = '/v1/ws';\n url.search = '';\n url.hash = '';\n return url.toString();\n}\n\nfunction resolveRoutingFeeBps(config: RelayConfig): number {\n return config.relayRegistry?.routingFeeBps ?? Math.max(0, Math.round(config.fees.basePercentage * 100));\n}\n\nfunction relayStatusToText(status: RelayNodeStatus): RelayRegistryRuntimeInfo['status'] {\n switch (status) {\n case RelayNodeStatus.INACTIVE:\n return 'INACTIVE';\n case RelayNodeStatus.SLASHED:\n return 'SLASHED';\n default:\n return 'ACTIVE';\n }\n}\n","import type { DID } from '@hivemind-os/collective-types';\n\nexport interface AuthMessage {\n type: 'auth';\n did: DID;\n nonce: string;\n signature: string;\n capabilities: string[];\n}\n\nexport interface HeartbeatMessage {\n type: 'heartbeat';\n sessionId: string;\n}\n\nexport interface TaskResultMessage {\n type: 'task_result';\n sessionId: string;\n taskId: string;\n sequence: number;\n result: unknown;\n}\n\nexport interface TaskProgressMessage {\n type: 'task_progress';\n sessionId: string;\n taskId: string;\n sequence: number;\n progress: number;\n message?: string;\n}\n\nexport interface TaskChunkMessage {\n type: 'task_chunk';\n sessionId: string;\n taskId: string;\n sequence: number;\n data: string;\n}\n\nexport interface TaskErrorMessage {\n type: 'task_error';\n sessionId: string;\n taskId: string;\n sequence: number;\n error: {\n code: string;\n message: string;\n };\n}\n\nexport type ProviderMessage =\n | AuthMessage\n | HeartbeatMessage\n | TaskResultMessage\n | TaskProgressMessage\n | TaskChunkMessage\n | TaskErrorMessage;\n\nexport interface AuthOkMessage {\n type: 'auth_ok';\n sessionId: string;\n relayDid: string;\n}\n\nexport interface AuthFailMessage {\n type: 'auth_fail';\n reason: string;\n}\n\nexport interface TaskRequestMessage {\n type: 'task_request';\n sessionId: string;\n taskId: string;\n capability: string;\n input: unknown;\n requesterDid: DID;\n sequence: number;\n}\n\nexport interface HeartbeatAckMessage {\n type: 'heartbeat_ack';\n}\n\nexport type RelayMessage = AuthOkMessage | AuthFailMessage | TaskRequestMessage | HeartbeatAckMessage;\n\nexport interface TaskRequest {\n requesterDid: DID;\n capability: string;\n input: unknown;\n providerDid?: DID;\n taskId?: string;\n timeoutMs?: number;\n}\n\nexport interface TaskResponse {\n taskId: string;\n providerDid: DID;\n sequence: number;\n result: unknown;\n}\n\nexport type TaskStreamEvent =\n | { type: 'progress'; taskId: string; sequence: number; progress: number; message?: string }\n | { type: 'chunk'; taskId: string; sequence: number; data: string }\n | { type: 'result'; taskId: string; sequence: number; result: unknown };\n\nexport type ProviderTaskMessage = Exclude<ProviderMessage, AuthMessage | HeartbeatMessage>;\n\nexport function normalizeCapability(capability: string): string {\n return capability.trim().toLowerCase();\n}\n\nexport function createAuthPayload(message: Pick<AuthMessage, 'did' | 'nonce' | 'capabilities'>): string {\n const capabilities = [...new Set(message.capabilities.map(normalizeCapability))].sort().join(',');\n return `mesh-relay-auth|${message.did}|${message.nonce}|${capabilities}`;\n}\n\nexport function serializeRelayMessage(message: RelayMessage): string {\n return JSON.stringify(message);\n}\n\nexport function parseProviderMessage(payload: string | Buffer | ArrayBuffer | Buffer[]): ProviderMessage | null {\n const raw =\n typeof payload === 'string'\n ? payload\n : payload instanceof ArrayBuffer\n ? Buffer.from(payload).toString('utf8')\n : Array.isArray(payload)\n ? Buffer.concat(payload).toString('utf8')\n : payload.toString('utf8');\n\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!isRecord(parsed) || typeof parsed.type !== 'string') {\n return null;\n }\n\n switch (parsed.type) {\n case 'auth':\n return typeof parsed.did === 'string' &&\n typeof parsed.nonce === 'string' &&\n typeof parsed.signature === 'string' &&\n Array.isArray(parsed.capabilities) &&\n parsed.capabilities.every((entry) => typeof entry === 'string')\n ? ({\n type: 'auth',\n did: parsed.did as DID,\n nonce: parsed.nonce,\n signature: parsed.signature,\n capabilities: parsed.capabilities,\n } satisfies AuthMessage)\n : null;\n case 'heartbeat':\n return typeof parsed.sessionId === 'string' ? { type: 'heartbeat', sessionId: parsed.sessionId } : null;\n case 'task_result':\n return typeof parsed.sessionId === 'string' && typeof parsed.taskId === 'string' && isPositiveInteger(parsed.sequence)\n ? { type: 'task_result', sessionId: parsed.sessionId, taskId: parsed.taskId, sequence: parsed.sequence, result: parsed.result }\n : null;\n case 'task_progress':\n return typeof parsed.sessionId === 'string' &&\n typeof parsed.taskId === 'string' &&\n isPositiveInteger(parsed.sequence) &&\n isValidProgress(parsed.progress) &&\n (parsed.message === undefined || typeof parsed.message === 'string')\n ? {\n type: 'task_progress',\n sessionId: parsed.sessionId,\n taskId: parsed.taskId,\n sequence: parsed.sequence,\n progress: parsed.progress,\n message: parsed.message,\n }\n : null;\n case 'task_chunk':\n return typeof parsed.sessionId === 'string' &&\n typeof parsed.taskId === 'string' &&\n isPositiveInteger(parsed.sequence) &&\n typeof parsed.data === 'string'\n ? { type: 'task_chunk', sessionId: parsed.sessionId, taskId: parsed.taskId, sequence: parsed.sequence, data: parsed.data }\n : null;\n case 'task_error':\n return typeof parsed.sessionId === 'string' &&\n typeof parsed.taskId === 'string' &&\n isPositiveInteger(parsed.sequence) &&\n isRecord(parsed.error) &&\n typeof parsed.error.code === 'string' &&\n typeof parsed.error.message === 'string'\n ? {\n type: 'task_error',\n sessionId: parsed.sessionId,\n taskId: parsed.taskId,\n sequence: parsed.sequence,\n error: {\n code: parsed.error.code,\n message: parsed.error.message,\n },\n }\n : null;\n default:\n return null;\n }\n } catch {\n return null;\n }\n}\n\nexport function parseRelayMessage(payload: string | Buffer | ArrayBuffer | Buffer[]): RelayMessage | null {\n const raw =\n typeof payload === 'string'\n ? payload\n : payload instanceof ArrayBuffer\n ? Buffer.from(payload).toString('utf8')\n : Array.isArray(payload)\n ? Buffer.concat(payload).toString('utf8')\n : payload.toString('utf8');\n\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!isRecord(parsed) || typeof parsed.type !== 'string') {\n return null;\n }\n\n switch (parsed.type) {\n case 'auth_ok':\n return typeof parsed.sessionId === 'string' && typeof parsed.relayDid === 'string'\n ? { type: 'auth_ok', sessionId: parsed.sessionId, relayDid: parsed.relayDid }\n : null;\n case 'auth_fail':\n return typeof parsed.reason === 'string' ? { type: 'auth_fail', reason: parsed.reason } : null;\n case 'heartbeat_ack':\n return { type: 'heartbeat_ack' };\n case 'task_request':\n return typeof parsed.sessionId === 'string' &&\n typeof parsed.taskId === 'string' &&\n typeof parsed.capability === 'string' &&\n typeof parsed.requesterDid === 'string' &&\n isPositiveInteger(parsed.sequence)\n ? {\n type: 'task_request',\n sessionId: parsed.sessionId,\n taskId: parsed.taskId,\n capability: parsed.capability,\n input: parsed.input,\n requesterDid: parsed.requesterDid as DID,\n sequence: parsed.sequence,\n }\n : null;\n default:\n return null;\n }\n } catch {\n return null;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isPositiveInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0;\n}\n\nfunction isValidProgress(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1;\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type { DID } from '@hivemind-os/collective-types';\nimport type WebSocket from 'ws';\n\nimport type { ProviderTaskMessage, TaskRequest, TaskResponse, TaskStreamEvent, TaskRequestMessage } from './message-types.js';\nimport { serializeRelayMessage } from './message-types.js';\nimport { SessionManager } from './session-manager.js';\n\ninterface RelayRouterOptions {\n sessionManager: SessionManager;\n taskTimeoutMs: number;\n}\n\ninterface PendingTask {\n taskId: string;\n sessionId: string;\n onChunk?: (event: TaskStreamEvent) => void;\n resolve: (response: TaskResponse) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout;\n}\n\nexport class RelayRouteError extends Error {\n constructor(\n readonly code: string,\n message: string,\n readonly statusCode: number,\n readonly retryable = false,\n ) {\n super(message);\n this.name = 'RelayRouteError';\n }\n}\n\nexport class RelayRouter {\n private readonly pendingTasks = new Map<string, PendingTask>();\n\n constructor(private readonly options: RelayRouterOptions) {\n this.options.sessionManager.on('session_removed', (session: { sessionId: string }) => {\n this.rejectSessionTasks(session.sessionId, new RelayRouteError('PROVIDER_DISCONNECTED', 'Provider disconnected.', 503, true));\n });\n }\n\n async routeTask(request: TaskRequest): Promise<TaskResponse> {\n return this.dispatch(request);\n }\n\n async routeStreamingTask(request: TaskRequest, onChunk: (chunk: TaskStreamEvent) => void): Promise<TaskResponse> {\n return this.dispatch(request, onChunk);\n }\n\n async routeMulti(request: TaskRequest, providerDids: DID[]): Promise<TaskResponse[]> {\n return await Promise.all(\n providerDids.map((providerDid, index) => this.dispatch({\n ...request,\n providerDid,\n taskId: request.taskId ? `${request.taskId}-${index + 1}` : undefined,\n })),\n );\n }\n\n close(): void {\n for (const taskId of [...this.pendingTasks.keys()]) {\n this.completeTask(\n taskId,\n undefined,\n new RelayRouteError('RELAY_SHUTDOWN', 'Relay is shutting down.', 503, true),\n );\n }\n }\n\n handleProviderMessage(sessionId: string, message: ProviderTaskMessage): void {\n if (message.sessionId !== sessionId) {\n throw new RelayRouteError('SESSION_MISMATCH', 'Relay session id did not match the authenticated connection.', 409);\n }\n\n if (!this.options.sessionManager.validateIncomingSequence(sessionId, message.sequence)) {\n throw new RelayRouteError('REPLAY_DETECTED', 'Out-of-order relay message rejected.', 409);\n }\n\n const session = this.options.sessionManager.getSession(sessionId);\n if (!session) {\n throw new RelayRouteError('SESSION_NOT_FOUND', 'Relay session was not found.', 404);\n }\n\n const pending = this.pendingTasks.get(message.taskId);\n if (!pending || pending.sessionId !== sessionId) {\n return;\n }\n\n switch (message.type) {\n case 'task_progress':\n this.emitTaskEvent(message.taskId, {\n type: 'progress',\n taskId: message.taskId,\n sequence: message.sequence,\n progress: message.progress,\n message: message.message,\n });\n break;\n case 'task_chunk':\n this.emitTaskEvent(message.taskId, {\n type: 'chunk',\n taskId: message.taskId,\n sequence: message.sequence,\n data: message.data,\n });\n break;\n case 'task_error':\n this.completeTask(\n message.taskId,\n undefined,\n new RelayRouteError(message.error.code, message.error.message, 502, true),\n );\n break;\n case 'task_result':\n if (!this.emitTaskEvent(message.taskId, {\n type: 'result',\n taskId: message.taskId,\n sequence: message.sequence,\n result: message.result,\n })) {\n return;\n }\n\n this.completeTask(message.taskId, {\n taskId: message.taskId,\n providerDid: session.providerDid,\n sequence: message.sequence,\n result: message.result,\n });\n break;\n }\n }\n\n private async dispatch(request: TaskRequest, onChunk?: (event: TaskStreamEvent) => void): Promise<TaskResponse> {\n const session = this.findSession(request.capability, request.providerDid);\n const taskId = request.taskId ?? randomUUID();\n const sequence = this.options.sessionManager.nextSequence(session.sessionId);\n const relayMessage: TaskRequestMessage = {\n type: 'task_request',\n sessionId: session.sessionId,\n taskId,\n capability: request.capability,\n input: request.input,\n requesterDid: request.requesterDid,\n sequence,\n };\n\n const response = new Promise<TaskResponse>((resolve, reject) => {\n const timeoutMs = request.timeoutMs ?? this.options.taskTimeoutMs;\n const timer = setTimeout(() => {\n this.pendingTasks.delete(taskId);\n reject(new RelayRouteError('TASK_TIMEOUT', `Task ${taskId} timed out.`, 504, true));\n }, timeoutMs);\n\n this.pendingTasks.set(taskId, {\n taskId,\n sessionId: session.sessionId,\n onChunk,\n resolve,\n reject,\n timer,\n });\n });\n\n try {\n await sendWebSocketMessage(session.ws, serializeRelayMessage(relayMessage));\n return await response;\n } catch (error) {\n this.completeTask(taskId, undefined, toRouteError(error));\n throw toRouteError(error);\n }\n }\n\n private emitTaskEvent(taskId: string, event: TaskStreamEvent): boolean {\n const pending = this.pendingTasks.get(taskId);\n if (!pending?.onChunk) {\n return true;\n }\n\n try {\n pending.onChunk(event);\n return true;\n } catch {\n this.completeTask(\n taskId,\n undefined,\n new RelayRouteError('STREAM_DELIVERY_FAILED', 'Streaming consumer disconnected before relay delivery completed.', 499, true),\n );\n return false;\n }\n }\n\n private completeTask(taskId: string, response?: TaskResponse, error?: Error): void {\n const pending = this.pendingTasks.get(taskId);\n if (!pending) {\n return;\n }\n\n clearTimeout(pending.timer);\n this.pendingTasks.delete(taskId);\n\n if (error) {\n pending.reject(error);\n return;\n }\n\n if (!response) {\n pending.reject(new RelayRouteError('TASK_FAILED', `Task ${taskId} failed.`, 500));\n return;\n }\n\n pending.resolve(response);\n }\n\n private rejectSessionTasks(sessionId: string, error: Error): void {\n for (const [taskId, pending] of this.pendingTasks.entries()) {\n if (pending.sessionId !== sessionId) {\n continue;\n }\n\n this.completeTask(taskId, undefined, error);\n }\n }\n\n private findSession(capability: string, providerDid?: DID) {\n const session = this.options.sessionManager.findProvider(capability, providerDid);\n if (!session) {\n throw new RelayRouteError('PROVIDER_NOT_FOUND', `No provider is connected for capability ${capability}.`, 404, true);\n }\n\n return session;\n }\n}\n\nasync function sendWebSocketMessage(ws: WebSocket, message: string): Promise<void> {\n if ('readyState' in ws && typeof ws.readyState === 'number' && ws.readyState !== 1) {\n throw new RelayRouteError('PROVIDER_UNAVAILABLE', 'Provider WebSocket is not open.', 503, true);\n }\n\n await new Promise<void>((resolve, reject) => {\n try {\n (ws as WebSocket & { send: (data: string, callback?: (error?: Error) => void) => void }).send(message, (error) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve();\n });\n } catch (error) {\n reject(error);\n }\n });\n}\n\nfunction toRouteError(error: unknown): RelayRouteError {\n if (error instanceof RelayRouteError) {\n return error;\n }\n\n return new RelayRouteError('ROUTING_FAILED', error instanceof Error ? error.message : 'Relay routing failed.', 502, true);\n}\n","import { randomUUID } from 'node:crypto';\nimport { EventEmitter } from 'node:events';\n\nimport { parseDID, verify } from '@hivemind-os/collective-core';\nimport type { DID } from '@hivemind-os/collective-types';\nimport type WebSocket from 'ws';\n\nimport { createAuthPayload, normalizeCapability, type AuthMessage } from './message-types.js';\n\nexport interface ProviderSession {\n sessionId: string;\n providerDid: DID;\n ws: WebSocket;\n capabilities: string[];\n connectedAt: number;\n lastHeartbeat: number;\n sequenceCounter: number;\n}\n\nexport interface ProviderInfo {\n sessionId: string;\n providerDid: DID;\n capabilities: string[];\n connectedAt: number;\n lastHeartbeat: number;\n}\n\ninterface ManagedProviderSession extends ProviderSession {\n normalizedCapabilities: string[];\n}\n\nexport interface SessionManagerOptions {\n maxConnections: number;\n heartbeatTimeoutMs: number;\n authNonceTtlMs?: number;\n now?: () => number;\n}\n\nconst encoder = new TextEncoder();\n\nexport class SessionManager extends EventEmitter {\n private readonly sessions = new Map<string, ManagedProviderSession>();\n private readonly sessionsByDid = new Map<DID, Set<string>>();\n private readonly capabilityIndex = new Map<string, Set<string>>();\n private readonly inboundSequences = new Map<string, number>();\n private readonly capabilityCursor = new Map<string, number>();\n private readonly recentAuthNonces = new Map<string, number>();\n private readonly now: () => number;\n\n constructor(private readonly options: SessionManagerOptions) {\n super();\n this.now = options.now ?? (() => Date.now());\n }\n\n registerSession(ws: WebSocket, authMessage: AuthMessage): ProviderSession {\n if (this.sessions.size >= this.options.maxConnections) {\n throw new Error('Relay connection limit reached.');\n }\n\n this.pruneRecentAuthNonces();\n if (this.getSessionByDid(authMessage.did)) {\n throw new Error(`Provider ${authMessage.did} is already connected to the relay.`);\n }\n\n this.verifyAuthMessage(authMessage);\n this.markAuthNonceUsed(authMessage);\n\n const sessionId = randomUUID();\n const timestamp = this.now();\n const normalizedCapabilities = [...new Set(authMessage.capabilities.map(normalizeCapability))];\n const session: ManagedProviderSession = {\n sessionId,\n providerDid: authMessage.did,\n ws,\n capabilities: [...normalizedCapabilities],\n normalizedCapabilities,\n connectedAt: timestamp,\n lastHeartbeat: timestamp,\n sequenceCounter: 0,\n };\n\n this.sessions.set(sessionId, session);\n this.addDidIndex(session.providerDid, sessionId);\n this.addCapabilities(sessionId, normalizedCapabilities);\n\n const cleanup = () => {\n this.removeSession(sessionId);\n };\n\n ws.once('close', cleanup);\n ws.once('error', cleanup);\n\n this.emit('session_registered', this.toProviderInfo(session));\n return session;\n }\n\n findProvider(capability: string, preferredDid?: DID): ProviderSession | null {\n const normalizedCapability = normalizeCapability(capability);\n if (preferredDid) {\n return this.getSessionByDid(preferredDid, normalizedCapability);\n }\n\n const ids = [...(this.capabilityIndex.get(normalizedCapability) ?? [])];\n if (ids.length === 0) {\n return null;\n }\n\n const cursor = this.capabilityCursor.get(normalizedCapability) ?? 0;\n const sessionId = ids[cursor % ids.length];\n this.capabilityCursor.set(normalizedCapability, cursor + 1);\n\n return sessionId ? this.sessions.get(sessionId) ?? null : null;\n }\n\n removeSession(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return;\n }\n\n this.sessions.delete(sessionId);\n this.inboundSequences.delete(sessionId);\n this.removeDidIndex(session.providerDid, sessionId);\n this.removeCapabilities(sessionId, session.normalizedCapabilities);\n this.emit('session_removed', this.toProviderInfo(session));\n }\n\n disconnectSession(sessionId: string, code = 4001, reason = 'Session expired'): void {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return;\n }\n\n try {\n session.ws.close(code, reason);\n } catch {\n this.removeSession(sessionId);\n }\n }\n\n disconnectAllSessions(code = 1012, reason = 'Relay shutting down'): void {\n for (const sessionId of [...this.sessions.keys()]) {\n this.disconnectSession(sessionId, code, reason);\n }\n }\n\n handleHeartbeat(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (!session) {\n return;\n }\n\n session.lastHeartbeat = this.now();\n }\n\n sweepExpiredSessions(): string[] {\n this.pruneRecentAuthNonces();\n const now = this.now();\n const expired = [...this.sessions.values()]\n .filter((session) => now - session.lastHeartbeat > this.options.heartbeatTimeoutMs)\n .map((session) => session.sessionId);\n\n for (const sessionId of expired) {\n this.disconnectSession(sessionId, 4002, 'Heartbeat timeout');\n }\n\n return expired;\n }\n\n getConnectedProviders(): ProviderInfo[] {\n return [...this.sessions.values()].map((session) => this.toProviderInfo(session));\n }\n\n getSession(sessionId: string): ProviderSession | null {\n return this.sessions.get(sessionId) ?? null;\n }\n\n getSessionByDid(did: DID, capability?: string): ProviderSession | null {\n const sessionIds = [...(this.sessionsByDid.get(did) ?? [])];\n if (sessionIds.length === 0) {\n return null;\n }\n\n const normalizedCapability = capability ? normalizeCapability(capability) : undefined;\n for (const sessionId of sessionIds) {\n const session = this.sessions.get(sessionId);\n if (!session) {\n continue;\n }\n\n if (!normalizedCapability || session.normalizedCapabilities.includes(normalizedCapability)) {\n return session;\n }\n }\n\n return null;\n }\n\n getSessionCount(): number {\n return this.sessions.size;\n }\n\n nextSequence(sessionId: string): number {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Unknown relay session: ${sessionId}`);\n }\n\n session.sequenceCounter += 1;\n return session.sequenceCounter;\n }\n\n validateIncomingSequence(sessionId: string, sequence: number): boolean {\n const previous = this.inboundSequences.get(sessionId) ?? 0;\n if (!Number.isInteger(sequence) || sequence <= previous) {\n return false;\n }\n\n this.inboundSequences.set(sessionId, sequence);\n return true;\n }\n\n private verifyAuthMessage(authMessage: AuthMessage): void {\n if (this.recentAuthNonces.has(this.getAuthNonceKey(authMessage))) {\n throw new Error('Authentication nonce has already been used.');\n }\n\n try {\n const payload = createAuthPayload(authMessage);\n const signature = decodeHex(authMessage.signature);\n const publicKey = parseDID(authMessage.did).publicKey;\n\n if (!verify(encoder.encode(payload), signature, publicKey)) {\n throw new Error('Invalid provider authentication signature.');\n }\n } catch (error) {\n if (error instanceof Error && error.message === 'Authentication nonce has already been used.') {\n throw error;\n }\n throw new Error('Invalid provider authentication signature.');\n }\n }\n\n private markAuthNonceUsed(authMessage: AuthMessage): void {\n this.recentAuthNonces.set(this.getAuthNonceKey(authMessage), this.now() + this.getAuthNonceTtlMs());\n }\n\n private pruneRecentAuthNonces(): void {\n const now = this.now();\n for (const [nonceKey, expiresAt] of this.recentAuthNonces.entries()) {\n if (expiresAt > now) {\n continue;\n }\n\n this.recentAuthNonces.delete(nonceKey);\n }\n }\n\n private getAuthNonceKey(authMessage: Pick<AuthMessage, 'did' | 'nonce'>): string {\n return `${authMessage.did}:${authMessage.nonce}`;\n }\n\n private getAuthNonceTtlMs(): number {\n return this.options.authNonceTtlMs ?? 5 * 60_000;\n }\n\n private addDidIndex(did: DID, sessionId: string): void {\n const ids = this.sessionsByDid.get(did) ?? new Set<string>();\n ids.add(sessionId);\n this.sessionsByDid.set(did, ids);\n }\n\n private removeDidIndex(did: DID, sessionId: string): void {\n const ids = this.sessionsByDid.get(did);\n if (!ids) {\n return;\n }\n\n ids.delete(sessionId);\n if (ids.size === 0) {\n this.sessionsByDid.delete(did);\n }\n }\n\n private addCapabilities(sessionId: string, capabilities: string[]): void {\n for (const capability of capabilities) {\n const sessions = this.capabilityIndex.get(capability) ?? new Set<string>();\n sessions.add(sessionId);\n this.capabilityIndex.set(capability, sessions);\n }\n }\n\n private removeCapabilities(sessionId: string, capabilities: string[]): void {\n for (const capability of capabilities) {\n const sessions = this.capabilityIndex.get(capability);\n if (!sessions) {\n continue;\n }\n\n sessions.delete(sessionId);\n if (sessions.size === 0) {\n this.capabilityIndex.delete(capability);\n this.capabilityCursor.delete(capability);\n }\n }\n }\n\n private toProviderInfo(session: ManagedProviderSession): ProviderInfo {\n return {\n sessionId: session.sessionId,\n providerDid: session.providerDid,\n capabilities: [...session.capabilities],\n connectedAt: session.connectedAt,\n lastHeartbeat: session.lastHeartbeat,\n };\n }\n}\n\nfunction decodeHex(value: string): Uint8Array {\n if (!/^[0-9a-f]+$/i.test(value) || value.length % 2 !== 0) {\n throw new Error('Authentication signature must be a hex string.');\n }\n\n return Uint8Array.from(Buffer.from(value, 'hex'));\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { PaymentRail, type DID } from '@hivemind-os/collective-types';\nimport type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';\n\nimport { isValidDID } from '@hivemind-os/collective-core';\n\nexport interface MeshRequestContext {\n requestId: string;\n requesterDid?: DID;\n targetProviderDid?: DID;\n timestamp?: string;\n signature?: string;\n paymentSignature?: string;\n paymentNonce?: string;\n paymentRail?: PaymentRail;\n sessionId?: string;\n sequence?: number;\n}\n\nexport function registerMeshMiddleware(app: FastifyInstance, relayDid: string): void {\n app.addHook('onRequest', async (request, reply) => {\n const requesterDid = request.headers['x-mesh-requester'];\n const targetProvider = request.headers['x-mesh-target-provider'];\n\n if (typeof requesterDid === 'string' && requesterDid.length > 0 && !isValidDID(requesterDid)) {\n reply.code(400).send({\n error: {\n code: 'INVALID_REQUESTER_DID',\n message: 'X-Mesh-Requester must be a valid did:mesh identifier.',\n },\n });\n return;\n }\n\n if (typeof targetProvider === 'string' && targetProvider.length > 0 && !isValidDID(targetProvider)) {\n reply.code(400).send({\n error: {\n code: 'INVALID_TARGET_PROVIDER_DID',\n message: 'X-Mesh-Target-Provider must be a valid did:mesh identifier.',\n },\n });\n return;\n }\n\n reply.header('X-Mesh-Relay', relayDid);\n });\n}\n\nexport function getMeshRequestContext(request: FastifyRequest): MeshRequestContext {\n return {\n requestId: readHeader(request, 'x-mesh-request-id') ?? randomUUID(),\n requesterDid: readHeader(request, 'x-mesh-requester') as DID | undefined,\n targetProviderDid: readHeader(request, 'x-mesh-target-provider') as DID | undefined,\n timestamp: readHeader(request, 'x-mesh-timestamp'),\n signature: readHeader(request, 'x-mesh-signature'),\n paymentSignature: readHeader(request, 'payment-signature') ?? readHeader(request, 'x-payment-signature'),\n paymentNonce: readHeader(request, 'x-mesh-payment-nonce'),\n paymentRail: normalizePaymentRail(readHeader(request, 'x-mesh-payment-rail')),\n sessionId: readHeader(request, 'x-mesh-session-id'),\n sequence: readPositiveInteger(readHeader(request, 'x-mesh-sequence')),\n };\n}\n\nexport function applyMeshResponseHeaders(reply: FastifyReply, relayDid: string, requestId: string): void {\n reply.header('X-Mesh-Relay', relayDid);\n reply.header('X-Mesh-Request-Id', requestId);\n}\n\nfunction readHeader(request: FastifyRequest, name: string): string | undefined {\n const value = request.headers[name];\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction readPositiveInteger(value: string | undefined): number | undefined {\n if (!value || !/^\\d+$/.test(value)) {\n return undefined;\n }\n\n return Number(value);\n}\n\nfunction normalizePaymentRail(value: string | undefined): PaymentRail | undefined {\n if (value === PaymentRail.SUI_ESCROW || value === PaymentRail.SUI_TRANSFER || value === PaymentRail.X402_BASE) {\n return value;\n }\n\n return undefined;\n}\n","import { encodePaymentResponseHeader } from '@x402/core/http';\nimport { PaymentRail, type DID } from '@hivemind-os/collective-types';\nimport type { FastifyInstance } from 'fastify';\n\nimport type { RelayConfig } from '../config.js';\nimport { HealthMonitor } from '../health/monitor.js';\nimport { PaymentGate } from '../payment/payment-gate.js';\nimport type { RelayRegistryRuntime } from '../registry/relay-registry-service.js';\nimport { RelayRouteError, RelayRouter } from '../routing/router.js';\nimport { SessionManager } from '../routing/session-manager.js';\nimport { applyMeshResponseHeaders, getMeshRequestContext } from './middleware.js';\n\nexport interface RelayRouteDependencies {\n relayDid: DID;\n version: string;\n config: RelayConfig;\n sessionManager: SessionManager;\n router: RelayRouter;\n paymentGate: PaymentGate;\n healthMonitor: HealthMonitor;\n relayRegistry?: RelayRegistryRuntime;\n}\n\nconst CONSUMER_SEQUENCE_TTL_MS = 60 * 60_000;\n\ninterface ConsumerSequenceState {\n sequence: number;\n updatedAt: number;\n}\n\nexport async function registerRelayRoutes(app: FastifyInstance, deps: RelayRouteDependencies): Promise<void> {\n const consumerSequences = new Map<string, ConsumerSequenceState>();\n\n app.get('/health', async () => {\n const status = deps.healthMonitor.getStatus();\n return {\n status: status.status === 'healthy' ? 'ok' : status.status,\n relayStatus: status.status,\n uptime: status.uptime,\n connectedProviders: status.connectedProviders,\n activeRequests: status.activeRequests,\n totalRequestsServed: status.totalRequestsServed,\n averageLatencyMs: status.averageLatencyMs,\n relayRegistry: deps.relayRegistry?.getInfo() ?? { enabled: false, registered: false },\n };\n });\n\n app.get('/info', async () => ({\n relayDid: deps.relayDid,\n version: deps.version,\n feeSchedule: {\n basePercentage: deps.config.fees.basePercentage,\n minimumMist: deps.config.fees.minimumMist.toString(),\n },\n capabilities: [...new Set(deps.sessionManager.getConnectedProviders().flatMap((provider) => provider.capabilities))].sort(),\n relayRegistry: deps.relayRegistry?.getInfo() ?? { enabled: false, registered: false },\n }));\n\n app.post('/mesh/providers/:providerDid/capabilities/:capability/execute', async (request, reply) => {\n const tracker = deps.healthMonitor.beginRequest();\n const context = getMeshRequestContext(request);\n applyMeshResponseHeaders(reply, deps.relayDid, context.requestId);\n\n try {\n const params = request.params as { providerDid: DID; capability: string };\n const sequenceError = validateConsumerSequence(consumerSequences, context, Date.now());\n if (sequenceError) {\n reply.code(sequenceError.statusCode).send(toError(sequenceError.code, sequenceError.message, context.requestId));\n return;\n }\n\n if (!context.requesterDid) {\n reply.code(400).send(toError('REQUESTER_REQUIRED', 'X-Mesh-Requester header is required.', context.requestId));\n return;\n }\n\n const provider = deps.sessionManager.findProvider(params.capability, params.providerDid);\n if (!provider) {\n reply.code(404).send(\n toError('PROVIDER_NOT_FOUND', `Provider ${params.providerDid} is not connected to the relay.`, context.requestId),\n );\n return;\n }\n\n const paymentRail = context.paymentRail ?? defaultPaymentRailForProvider(provider, deps.paymentGate);\n if (!context.paymentSignature) {\n const challenge = deps.paymentGate.generate402Challenge(paymentRail, params.capability, provider);\n reply\n .code(402)\n .header('PAYMENT-REQUIRED', challenge.extra?.['payment-required'] ?? '')\n .send({\n ...toError('PAYMENT_REQUIRED', 'Payment is required before relay execution.', context.requestId),\n payment: challenge,\n });\n return;\n }\n\n const challenge = context.paymentNonce ? deps.paymentGate.getChallenge(context.paymentNonce) : null;\n if (!challenge) {\n reply.code(400).send(\n toError('PAYMENT_CHALLENGE_REQUIRED', 'X-Mesh-Payment-Nonce must reference an active challenge.', context.requestId),\n );\n return;\n }\n\n const verification = await deps.paymentGate.verifyPayment(context.paymentSignature, challenge);\n if (!verification.accepted) {\n reply.code(402).send({\n ...toError('PAYMENT_REJECTED', verification.reason ?? 'Payment verification failed.', context.requestId),\n payment: challenge,\n });\n return;\n }\n\n if (!deps.sessionManager.getSession(provider.sessionId)) {\n reply.code(503).send(\n toError(\n 'PROVIDER_UNAVAILABLE',\n `Provider ${params.providerDid} disconnected before the relay could start the task. No funds were settled.`,\n context.requestId,\n true,\n ),\n );\n return;\n }\n\n if (isStreamingRequest(request)) {\n reply.hijack();\n reply.raw.writeHead(200, {\n 'content-type': 'text/event-stream; charset=utf-8',\n 'cache-control': 'no-cache, no-transform',\n connection: 'keep-alive',\n 'x-mesh-provider': provider.providerDid,\n 'x-mesh-request-id': context.requestId,\n 'x-mesh-relay': deps.relayDid,\n 'payment-response': verification.settlementReference ?? '',\n });\n\n try {\n const routed = await deps.router.routeStreamingTask(\n {\n requesterDid: context.requesterDid,\n providerDid: params.providerDid,\n capability: params.capability,\n input: request.body,\n timeoutMs: deps.config.limits.taskTimeoutMs,\n },\n (event) => {\n if (event.type === 'result') {\n return;\n }\n writeSse(reply.raw, event.type, event);\n },\n );\n\n await deps.relayRegistry?.recordRouting(BigInt(challenge.relayFee));\n writeSse(reply.raw, 'result', {\n taskId: routed.taskId,\n providerDid: routed.providerDid,\n result: routed.result,\n paymentReceipt: verification.settlementReference,\n relayFeeMist: challenge.relayFee,\n });\n } catch (error) {\n const routeError = error instanceof RelayRouteError ? error : new RelayRouteError('ROUTE_FAILED', 'Relay routing failed.', 502, true);\n writeSse(reply.raw, 'error', { code: routeError.code, message: routeError.message });\n } finally {\n reply.raw.end();\n }\n return;\n }\n\n const response = await deps.router.routeTask({\n requesterDid: context.requesterDid,\n providerDid: params.providerDid,\n capability: params.capability,\n input: request.body,\n timeoutMs: deps.config.limits.taskTimeoutMs,\n });\n\n await deps.relayRegistry?.recordRouting(BigInt(challenge.relayFee));\n reply\n .code(200)\n .header('X-Mesh-Provider', response.providerDid)\n .header('X-Mesh-Response-Id', response.taskId)\n .header('X-Mesh-Relay-Fee', challenge.relayFee)\n .header(\n 'PAYMENT-RESPONSE',\n verification.settlementReference ??\n encodePaymentResponseHeader({\n success: true,\n transaction: `relay-${response.taskId}`,\n network: toSettlementNetwork(challenge.network),\n amount: challenge.amount,\n payer: verification.payer,\n }),\n )\n .send(response.result);\n } catch (error) {\n const routeError = error instanceof RelayRouteError ? error : new RelayRouteError('ROUTE_FAILED', 'Relay routing failed.', 502, true);\n reply.code(routeError.statusCode).send(toError(routeError.code, routeError.message, context.requestId, routeError.retryable));\n } finally {\n tracker.finish();\n }\n });\n}\n\nfunction validateConsumerSequence(\n sequences: Map<string, ConsumerSequenceState>,\n context: ReturnType<typeof getMeshRequestContext>,\n now: number,\n) {\n pruneConsumerSequences(sequences, now);\n\n if (!context.sessionId && context.sequence === undefined) {\n return null;\n }\n\n if (!context.sessionId || context.sequence === undefined) {\n return {\n code: 'SEQUENCE_REQUIRED',\n message: 'X-Mesh-Session-Id and X-Mesh-Sequence must be provided together.',\n statusCode: 400,\n };\n }\n\n const previous = sequences.get(context.sessionId)?.sequence ?? 0;\n if (context.sequence <= previous) {\n return {\n code: 'REPLAY_DETECTED',\n message: 'Relay rejected a replayed or out-of-order consumer request.',\n statusCode: 409,\n };\n }\n\n sequences.set(context.sessionId, { sequence: context.sequence, updatedAt: now });\n return null;\n}\n\nfunction pruneConsumerSequences(sequences: Map<string, ConsumerSequenceState>, now: number): void {\n for (const [sessionId, state] of sequences.entries()) {\n if (now - state.updatedAt <= CONSUMER_SEQUENCE_TTL_MS) {\n continue;\n }\n\n sequences.delete(sessionId);\n }\n}\n\nfunction defaultPaymentRailForProvider(provider: { capabilities: string[] }, paymentGate: PaymentGate): PaymentRail {\n return paymentGate.defaultRail ?? PaymentRail.SUI_TRANSFER;\n}\n\nfunction isStreamingRequest(request: { headers: Record<string, unknown>; query: unknown }): boolean {\n const accept = typeof request.headers.accept === 'string' ? request.headers.accept : '';\n if (accept.includes('text/event-stream')) {\n return true;\n }\n\n if (typeof request.query !== 'object' || request.query === null) {\n return false;\n }\n\n const query = request.query as Record<string, unknown>;\n return query.stream === '1' || query.stream === 'true';\n}\n\nfunction writeSse(stream: NodeJS.WritableStream, event: string, data: unknown): void {\n stream.write(`event: ${event}\\n`);\n stream.write(`data: ${JSON.stringify(data)}\\n\\n`);\n}\n\nfunction toError(code: string, message: string, requestId: string, retryable = false) {\n return {\n error: {\n code,\n message,\n details: {},\n retryable,\n retryAfterMs: retryable ? 1_000 : null,\n requestId,\n },\n };\n}\n\nfunction toSettlementNetwork(network: string): `${string}:${string}` {\n switch (network) {\n case 'base':\n return 'eip155:8453';\n case 'base-sepolia':\n return 'eip155:84532';\n case 'sui-mainnet':\n return 'sui:mainnet';\n case 'sui-testnet':\n return 'sui:testnet';\n case 'sui-devnet':\n return 'sui:devnet';\n default:\n return network.includes(':') ? (network as `${string}:${string}`) : 'sui:testnet';\n }\n}\n"],"mappings":"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","names":["resolve","randomUUID","randomUUID","randomUUID","randomUUID","resolve","randomUUID","PaymentRail","encodePaymentResponseHeader","PaymentRail","challenge","encodePaymentResponseHeader","PaymentRail"]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@hivemind-os/collective-relay",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "bin": {
17
+ "collective-relay": "./dist/index.js"
18
+ },
19
+ "dependencies": {
20
+ "@mysten/sui": "^1.30.0",
21
+ "@x402/core": "^2.12.0",
22
+ "@x402/evm": "^2.12.0",
23
+ "@fastify/cors": "^10.0.0",
24
+ "@fastify/rate-limit": "^10.0.0",
25
+ "@fastify/websocket": "^11.0.0",
26
+ "fastify": "^5.0.0",
27
+ "pino": "^9.0.0",
28
+ "viem": "^2.48.11",
29
+ "ws": "^8.0.0",
30
+ "@hivemind-os/collective-core": "0.2.0",
31
+ "@hivemind-os/collective-types": "0.2.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/ws": "^8.0.0",
35
+ "tsup": "^8.0.0",
36
+ "typescript": "^5.7.0",
37
+ "vitest": "^3.0.0"
38
+ },
39
+ "scripts": {
40
+ "build": "tsup",
41
+ "test": "vitest",
42
+ "lint": "eslint src/ tests/ vitest.config.ts tsup.config.ts",
43
+ "start": "node dist/index.js"
44
+ }
45
+ }