@swal/edge-mesh 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +128 -0
- package/NOTICE +37 -0
- package/README.md +470 -2
- package/dist/adapters/gpu-agent/index.d.ts +61 -0
- package/dist/adapters/gpu-agent/index.d.ts.map +1 -0
- package/dist/adapters/gpu-agent/index.js +364 -0
- package/dist/adapters/gpu-agent/index.js.map +1 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.d.ts +19 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.js +51 -0
- package/dist/adapters/maloca-salud/citas-distribuidas.js.map +1 -0
- package/dist/adapters/maloca-salud/eps-bridge.d.ts +15 -0
- package/dist/adapters/maloca-salud/eps-bridge.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/eps-bridge.js +27 -0
- package/dist/adapters/maloca-salud/eps-bridge.js.map +1 -0
- package/dist/adapters/maloca-salud/patient-profile.d.ts +20 -0
- package/dist/adapters/maloca-salud/patient-profile.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/patient-profile.js +36 -0
- package/dist/adapters/maloca-salud/patient-profile.js.map +1 -0
- package/dist/adapters/maloca-salud/types.d.ts +40 -0
- package/dist/adapters/maloca-salud/types.d.ts.map +1 -0
- package/dist/adapters/maloca-salud/types.js +2 -0
- package/dist/adapters/maloca-salud/types.js.map +1 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.d.ts +31 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.js +103 -0
- package/dist/adapters/maloca-veeduria/contract-bridge.js.map +1 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.d.ts +14 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.js +40 -0
- package/dist/adapters/maloca-veeduria/evidentia-veeduria.js.map +1 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.d.ts +21 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.js +58 -0
- package/dist/adapters/maloca-veeduria/licitante-profile.js.map +1 -0
- package/dist/adapters/maloca-veeduria/types.d.ts +30 -0
- package/dist/adapters/maloca-veeduria/types.d.ts.map +1 -0
- package/dist/adapters/maloca-veeduria/types.js +2 -0
- package/dist/adapters/maloca-veeduria/types.js.map +1 -0
- package/dist/adapters/maloca-xavier/agent-profile.d.ts +32 -0
- package/dist/adapters/maloca-xavier/agent-profile.d.ts.map +1 -0
- package/dist/adapters/maloca-xavier/agent-profile.js +56 -0
- package/dist/adapters/maloca-xavier/agent-profile.js.map +1 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.d.ts +27 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.d.ts.map +1 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.js +58 -0
- package/dist/adapters/maloca-xavier/codegraph-bridge.js.map +1 -0
- package/dist/adapters/maloca-xavier/llm-router.d.ts +25 -0
- package/dist/adapters/maloca-xavier/llm-router.d.ts.map +1 -0
- package/dist/adapters/maloca-xavier/llm-router.js +58 -0
- package/dist/adapters/maloca-xavier/llm-router.js.map +1 -0
- package/dist/authz/index.d.ts +81 -0
- package/dist/authz/index.d.ts.map +1 -0
- package/dist/authz/index.js +271 -0
- package/dist/authz/index.js.map +1 -0
- package/dist/chat/index.d.ts +138 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +394 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/offline-queue.d.ts +32 -0
- package/dist/chat/offline-queue.d.ts.map +1 -0
- package/dist/chat/offline-queue.js +93 -0
- package/dist/chat/offline-queue.js.map +1 -0
- package/dist/core/DefaultEdgeMeshNode.d.ts +17 -0
- package/dist/core/DefaultEdgeMeshNode.d.ts.map +1 -0
- package/dist/core/DefaultEdgeMeshNode.js +57 -0
- package/dist/core/DefaultEdgeMeshNode.js.map +1 -0
- package/dist/core/node.d.ts +26 -0
- package/dist/core/node.d.ts.map +1 -0
- package/dist/core/node.js +16 -0
- package/dist/core/node.js.map +1 -0
- package/dist/edge-mesh.d.ts +139 -0
- package/dist/edge-mesh.d.ts.map +1 -0
- package/dist/edge-mesh.js +1146 -0
- package/dist/edge-mesh.js.map +1 -0
- package/dist/gos/GosBridge.d.ts +49 -0
- package/dist/gos/GosBridge.d.ts.map +1 -0
- package/dist/gos/GosBridge.js +133 -0
- package/dist/gos/GosBridge.js.map +1 -0
- package/dist/governance/authority.d.ts +44 -0
- package/dist/governance/authority.d.ts.map +1 -0
- package/dist/governance/authority.js +123 -0
- package/dist/governance/authority.js.map +1 -0
- package/dist/governance/index.d.ts +66 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +210 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/merge.d.ts +31 -0
- package/dist/governance/merge.d.ts.map +1 -0
- package/dist/governance/merge.js +167 -0
- package/dist/governance/merge.js.map +1 -0
- package/dist/identity/index.d.ts +199 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +415 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/maloca/backoffice.d.ts +31 -0
- package/dist/maloca/backoffice.d.ts.map +1 -0
- package/dist/maloca/backoffice.js +40 -0
- package/dist/maloca/backoffice.js.map +1 -0
- package/dist/maloca/event-bus.d.ts +60 -0
- package/dist/maloca/event-bus.d.ts.map +1 -0
- package/dist/maloca/event-bus.js +175 -0
- package/dist/maloca/event-bus.js.map +1 -0
- package/dist/maloca/evidentia.d.ts +136 -0
- package/dist/maloca/evidentia.d.ts.map +1 -0
- package/dist/maloca/evidentia.js +447 -0
- package/dist/maloca/evidentia.js.map +1 -0
- package/dist/maloca/gateway/api.d.ts +146 -0
- package/dist/maloca/gateway/api.d.ts.map +1 -0
- package/dist/maloca/gateway/api.js +228 -0
- package/dist/maloca/gateway/api.js.map +1 -0
- package/dist/maloca/gateway/auth.d.ts +20 -0
- package/dist/maloca/gateway/auth.d.ts.map +1 -0
- package/dist/maloca/gateway/auth.js +115 -0
- package/dist/maloca/gateway/auth.js.map +1 -0
- package/dist/maloca/gateway/dashboard.d.ts +42 -0
- package/dist/maloca/gateway/dashboard.d.ts.map +1 -0
- package/dist/maloca/gateway/dashboard.js +67 -0
- package/dist/maloca/gateway/dashboard.js.map +1 -0
- package/dist/maloca/gateway/websocket.d.ts +34 -0
- package/dist/maloca/gateway/websocket.d.ts.map +1 -0
- package/dist/maloca/gateway/websocket.js +71 -0
- package/dist/maloca/gateway/websocket.js.map +1 -0
- package/dist/maloca/karma.d.ts +165 -0
- package/dist/maloca/karma.d.ts.map +1 -0
- package/dist/maloca/karma.js +307 -0
- package/dist/maloca/karma.js.map +1 -0
- package/dist/maloca/kernel.d.ts +20 -0
- package/dist/maloca/kernel.d.ts.map +1 -0
- package/dist/maloca/kernel.js +76 -0
- package/dist/maloca/kernel.js.map +1 -0
- package/dist/maloca/metadata.d.ts +30 -0
- package/dist/maloca/metadata.d.ts.map +1 -0
- package/dist/maloca/metadata.js +80 -0
- package/dist/maloca/metadata.js.map +1 -0
- package/dist/maloca/perfil.d.ts +57 -0
- package/dist/maloca/perfil.d.ts.map +1 -0
- package/dist/maloca/perfil.js +113 -0
- package/dist/maloca/perfil.js.map +1 -0
- package/dist/maloca/plugin-registry.d.ts +27 -0
- package/dist/maloca/plugin-registry.d.ts.map +1 -0
- package/dist/maloca/plugin-registry.js +76 -0
- package/dist/maloca/plugin-registry.js.map +1 -0
- package/dist/maloca/polygon-bridge.d.ts +63 -0
- package/dist/maloca/polygon-bridge.d.ts.map +1 -0
- package/dist/maloca/polygon-bridge.js +198 -0
- package/dist/maloca/polygon-bridge.js.map +1 -0
- package/dist/maloca/types.d.ts +44 -0
- package/dist/maloca/types.d.ts.map +1 -0
- package/dist/maloca/types.js +2 -0
- package/dist/maloca/types.js.map +1 -0
- package/dist/medico/aval.d.ts +149 -0
- package/dist/medico/aval.d.ts.map +1 -0
- package/dist/medico/aval.js +281 -0
- package/dist/medico/aval.js.map +1 -0
- package/dist/medico/canonica.d.ts +96 -0
- package/dist/medico/canonica.d.ts.map +1 -0
- package/dist/medico/canonica.js +148 -0
- package/dist/medico/canonica.js.map +1 -0
- package/dist/medico/credencial.d.ts +160 -0
- package/dist/medico/credencial.d.ts.map +1 -0
- package/dist/medico/credencial.js +240 -0
- package/dist/medico/credencial.js.map +1 -0
- package/dist/medico/index.d.ts +36 -0
- package/dist/medico/index.d.ts.map +1 -0
- package/dist/medico/index.js +39 -0
- package/dist/medico/index.js.map +1 -0
- package/dist/medico/malla.d.ts +218 -0
- package/dist/medico/malla.d.ts.map +1 -0
- package/dist/medico/malla.js +347 -0
- package/dist/medico/malla.js.map +1 -0
- package/dist/medico/registro-profesional.d.ts +84 -0
- package/dist/medico/registro-profesional.d.ts.map +1 -0
- package/dist/medico/registro-profesional.js +135 -0
- package/dist/medico/registro-profesional.js.map +1 -0
- package/dist/medico/registro.d.ts +149 -0
- package/dist/medico/registro.d.ts.map +1 -0
- package/dist/medico/registro.js +173 -0
- package/dist/medico/registro.js.map +1 -0
- package/dist/medico/types.d.ts +287 -0
- package/dist/medico/types.d.ts.map +1 -0
- package/dist/medico/types.js +135 -0
- package/dist/medico/types.js.map +1 -0
- package/dist/medico/verificacion-registro.d.ts +300 -0
- package/dist/medico/verificacion-registro.d.ts.map +1 -0
- package/dist/medico/verificacion-registro.js +319 -0
- package/dist/medico/verificacion-registro.js.map +1 -0
- package/dist/mesh/index.d.ts +457 -0
- package/dist/mesh/index.d.ts.map +1 -0
- package/dist/mesh/index.js +929 -0
- package/dist/mesh/index.js.map +1 -0
- package/dist/namespaces/encrypted-plugin.d.ts +56 -0
- package/dist/namespaces/encrypted-plugin.d.ts.map +1 -0
- package/dist/namespaces/encrypted-plugin.js +173 -0
- package/dist/namespaces/encrypted-plugin.js.map +1 -0
- package/dist/namespaces/index.d.ts +52 -0
- package/dist/namespaces/index.d.ts.map +1 -0
- package/dist/namespaces/index.js +134 -0
- package/dist/namespaces/index.js.map +1 -0
- package/dist/namespaces/ivn-proofs.d.ts +54 -0
- package/dist/namespaces/ivn-proofs.d.ts.map +1 -0
- package/dist/namespaces/ivn-proofs.js +162 -0
- package/dist/namespaces/ivn-proofs.js.map +1 -0
- package/dist/namespaces/offers-gossip.d.ts +95 -0
- package/dist/namespaces/offers-gossip.d.ts.map +1 -0
- package/dist/namespaces/offers-gossip.js +213 -0
- package/dist/namespaces/offers-gossip.js.map +1 -0
- package/dist/node-memory/idb-store.d.ts +22 -0
- package/dist/node-memory/idb-store.d.ts.map +1 -0
- package/dist/node-memory/idb-store.js +154 -0
- package/dist/node-memory/idb-store.js.map +1 -0
- package/dist/node-memory/index.d.ts +14 -0
- package/dist/node-memory/index.d.ts.map +1 -0
- package/dist/node-memory/index.js +159 -0
- package/dist/node-memory/index.js.map +1 -0
- package/dist/node-memory/sync-flush.d.ts +11 -0
- package/dist/node-memory/sync-flush.d.ts.map +1 -0
- package/dist/node-memory/sync-flush.js +37 -0
- package/dist/node-memory/sync-flush.js.map +1 -0
- package/dist/node-memory/types.d.ts +34 -0
- package/dist/node-memory/types.d.ts.map +1 -0
- package/dist/node-memory/types.js +2 -0
- package/dist/node-memory/types.js.map +1 -0
- package/dist/node-memory/xavier-store.d.ts +12 -0
- package/dist/node-memory/xavier-store.d.ts.map +1 -0
- package/dist/node-memory/xavier-store.js +75 -0
- package/dist/node-memory/xavier-store.js.map +1 -0
- package/dist/op-log/index.d.ts +49 -0
- package/dist/op-log/index.d.ts.map +1 -0
- package/dist/op-log/index.js +190 -0
- package/dist/op-log/index.js.map +1 -0
- package/dist/presence/health.d.ts +54 -0
- package/dist/presence/health.d.ts.map +1 -0
- package/dist/presence/health.js +139 -0
- package/dist/presence/health.js.map +1 -0
- package/dist/presence/index.d.ts +85 -0
- package/dist/presence/index.d.ts.map +1 -0
- package/dist/presence/index.js +255 -0
- package/dist/presence/index.js.map +1 -0
- package/dist/presence/peer-health.d.ts +40 -0
- package/dist/presence/peer-health.d.ts.map +1 -0
- package/dist/presence/peer-health.js +118 -0
- package/dist/presence/peer-health.js.map +1 -0
- package/dist/protocol/canonical.d.ts +10 -0
- package/dist/protocol/canonical.d.ts.map +1 -0
- package/dist/protocol/canonical.js +32 -0
- package/dist/protocol/canonical.js.map +1 -0
- package/dist/protocol/crypto.d.ts +299 -0
- package/dist/protocol/crypto.d.ts.map +1 -0
- package/dist/protocol/crypto.js +739 -0
- package/dist/protocol/crypto.js.map +1 -0
- package/dist/protocol/index.d.ts +30 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +116 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/utils.d.ts +5 -0
- package/dist/protocol/utils.d.ts.map +1 -0
- package/dist/protocol/utils.js +27 -0
- package/dist/protocol/utils.js.map +1 -0
- package/dist/salones/manager.d.ts +100 -0
- package/dist/salones/manager.d.ts.map +1 -0
- package/dist/salones/manager.js +240 -0
- package/dist/salones/manager.js.map +1 -0
- package/dist/security/rate-limiter.d.ts +13 -0
- package/dist/security/rate-limiter.d.ts.map +1 -0
- package/dist/security/rate-limiter.js +32 -0
- package/dist/security/rate-limiter.js.map +1 -0
- package/dist/snapshot/index.d.ts +90 -0
- package/dist/snapshot/index.d.ts.map +1 -0
- package/dist/snapshot/index.js +189 -0
- package/dist/snapshot/index.js.map +1 -0
- package/dist/storage/index.d.ts +49 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +176 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/optimizer.d.ts +28 -0
- package/dist/storage/optimizer.d.ts.map +1 -0
- package/dist/storage/optimizer.js +50 -0
- package/dist/storage/optimizer.js.map +1 -0
- package/dist/storage/ydoc-persistence.d.ts +27 -0
- package/dist/storage/ydoc-persistence.d.ts.map +1 -0
- package/dist/storage/ydoc-persistence.js +128 -0
- package/dist/storage/ydoc-persistence.js.map +1 -0
- package/dist/sync/ChunkSyncManager.d.ts +41 -0
- package/dist/sync/ChunkSyncManager.d.ts.map +1 -0
- package/dist/sync/ChunkSyncManager.js +115 -0
- package/dist/sync/ChunkSyncManager.js.map +1 -0
- package/dist/sync/conflict-resolver.d.ts +33 -0
- package/dist/sync/conflict-resolver.d.ts.map +1 -0
- package/dist/sync/conflict-resolver.js +54 -0
- package/dist/sync/conflict-resolver.js.map +1 -0
- package/dist/sync/engine.d.ts +168 -0
- package/dist/sync/engine.d.ts.map +1 -0
- package/dist/sync/engine.js +315 -0
- package/dist/sync/engine.js.map +1 -0
- package/dist/sync/index.d.ts +3 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +3 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/transport/TorTransportAdapter.d.ts +70 -0
- package/dist/transport/TorTransportAdapter.d.ts.map +1 -0
- package/dist/transport/TorTransportAdapter.js +192 -0
- package/dist/transport/TorTransportAdapter.js.map +1 -0
- package/dist/transport/memory.d.ts +31 -0
- package/dist/transport/memory.d.ts.map +1 -0
- package/dist/transport/memory.js +114 -0
- package/dist/transport/memory.js.map +1 -0
- package/dist/transport/peerjs.d.ts +45 -0
- package/dist/transport/peerjs.d.ts.map +1 -0
- package/dist/transport/peerjs.js +301 -0
- package/dist/transport/peerjs.js.map +1 -0
- package/dist/transport/pqc-handshake.d.ts +72 -0
- package/dist/transport/pqc-handshake.d.ts.map +1 -0
- package/dist/transport/pqc-handshake.js +129 -0
- package/dist/transport/pqc-handshake.js.map +1 -0
- package/dist/transport/relay-config.d.ts +11 -0
- package/dist/transport/relay-config.d.ts.map +1 -0
- package/dist/transport/relay-config.js +48 -0
- package/dist/transport/relay-config.js.map +1 -0
- package/dist/transport/relay-server.d.ts +37 -0
- package/dist/transport/relay-server.d.ts.map +1 -0
- package/dist/transport/relay-server.js +230 -0
- package/dist/transport/relay-server.js.map +1 -0
- package/dist/transport/tor.d.ts +47 -0
- package/dist/transport/tor.d.ts.map +1 -0
- package/dist/transport/tor.js +158 -0
- package/dist/transport/tor.js.map +1 -0
- package/dist/transport/types.d.ts +34 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +2 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/types/index.d.ts +293 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +73 -0
- package/dist/types/index.js.map +1 -0
- package/dist/web/admission.d.ts +24 -0
- package/dist/web/admission.d.ts.map +1 -0
- package/dist/web/admission.js +41 -0
- package/dist/web/admission.js.map +1 -0
- package/dist/web/crypto.d.ts +18 -0
- package/dist/web/crypto.d.ts.map +1 -0
- package/dist/web/crypto.js +78 -0
- package/dist/web/crypto.js.map +1 -0
- package/dist/web/exchange.d.ts +23 -0
- package/dist/web/exchange.d.ts.map +1 -0
- package/dist/web/exchange.js +54 -0
- package/dist/web/exchange.js.map +1 -0
- package/dist/web/fragment.d.ts +58 -0
- package/dist/web/fragment.d.ts.map +1 -0
- package/dist/web/fragment.js +198 -0
- package/dist/web/fragment.js.map +1 -0
- package/dist/web/index.d.ts +25 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +14 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/merge/index.d.ts +104 -0
- package/dist/web/merge/index.d.ts.map +1 -0
- package/dist/web/merge/index.js +236 -0
- package/dist/web/merge/index.js.map +1 -0
- package/dist/web/oplog/hlc.d.ts +19 -0
- package/dist/web/oplog/hlc.d.ts.map +1 -0
- package/dist/web/oplog/hlc.js +39 -0
- package/dist/web/oplog/hlc.js.map +1 -0
- package/dist/web/oplog/index.d.ts +10 -0
- package/dist/web/oplog/index.d.ts.map +1 -0
- package/dist/web/oplog/index.js +6 -0
- package/dist/web/oplog/index.js.map +1 -0
- package/dist/web/oplog/log.d.ts +182 -0
- package/dist/web/oplog/log.d.ts.map +1 -0
- package/dist/web/oplog/log.js +693 -0
- package/dist/web/oplog/log.js.map +1 -0
- package/dist/web/oplog/store.d.ts +40 -0
- package/dist/web/oplog/store.d.ts.map +1 -0
- package/dist/web/oplog/store.js +85 -0
- package/dist/web/oplog/store.js.map +1 -0
- package/dist/web/oplog/sync.d.ts +54 -0
- package/dist/web/oplog/sync.d.ts.map +1 -0
- package/dist/web/oplog/sync.js +162 -0
- package/dist/web/oplog/sync.js.map +1 -0
- package/dist/web/oplog/types.d.ts +119 -0
- package/dist/web/oplog/types.d.ts.map +1 -0
- package/dist/web/oplog/types.js +2 -0
- package/dist/web/oplog/types.js.map +1 -0
- package/dist/web/pairing.d.ts +186 -0
- package/dist/web/pairing.d.ts.map +1 -0
- package/dist/web/pairing.js +395 -0
- package/dist/web/pairing.js.map +1 -0
- package/dist/web/pq.d.ts +36 -0
- package/dist/web/pq.d.ts.map +1 -0
- package/dist/web/pq.js +59 -0
- package/dist/web/pq.js.map +1 -0
- package/dist/web/provider.d.ts +188 -0
- package/dist/web/provider.d.ts.map +1 -0
- package/dist/web/provider.js +2042 -0
- package/dist/web/provider.js.map +1 -0
- package/dist/web/rooms.d.ts +20 -0
- package/dist/web/rooms.d.ts.map +1 -0
- package/dist/web/rooms.js +51 -0
- package/dist/web/rooms.js.map +1 -0
- package/dist/web/rotation.d.ts +73 -0
- package/dist/web/rotation.d.ts.map +1 -0
- package/dist/web/rotation.js +130 -0
- package/dist/web/rotation.js.map +1 -0
- package/dist/web/secstate.d.ts +213 -0
- package/dist/web/secstate.d.ts.map +1 -0
- package/dist/web/secstate.js +789 -0
- package/dist/web/secstate.js.map +1 -0
- package/dist/web/store.d.ts +9 -0
- package/dist/web/store.d.ts.map +1 -0
- package/dist/web/store.js +32 -0
- package/dist/web/store.js.map +1 -0
- package/dist/web/transports/loopback.d.ts +11 -0
- package/dist/web/transports/loopback.d.ts.map +1 -0
- package/dist/web/transports/loopback.js +97 -0
- package/dist/web/transports/loopback.js.map +1 -0
- package/dist/web/transports/qr-sdp.d.ts +27 -0
- package/dist/web/transports/qr-sdp.d.ts.map +1 -0
- package/dist/web/transports/qr-sdp.js +131 -0
- package/dist/web/transports/qr-sdp.js.map +1 -0
- package/dist/web/transports/ws.d.ts +12 -0
- package/dist/web/transports/ws.d.ts.map +1 -0
- package/dist/web/transports/ws.js +139 -0
- package/dist/web/transports/ws.js.map +1 -0
- package/dist/web/trust/canonical.d.ts +8 -0
- package/dist/web/trust/canonical.d.ts.map +1 -0
- package/dist/web/trust/canonical.js +27 -0
- package/dist/web/trust/canonical.js.map +1 -0
- package/dist/web/trust/docs.d.ts +51 -0
- package/dist/web/trust/docs.d.ts.map +1 -0
- package/dist/web/trust/docs.js +170 -0
- package/dist/web/trust/docs.js.map +1 -0
- package/dist/web/trust/index.d.ts +10 -0
- package/dist/web/trust/index.d.ts.map +1 -0
- package/dist/web/trust/index.js +7 -0
- package/dist/web/trust/index.js.map +1 -0
- package/dist/web/trust/keys.d.ts +37 -0
- package/dist/web/trust/keys.d.ts.map +1 -0
- package/dist/web/trust/keys.js +75 -0
- package/dist/web/trust/keys.js.map +1 -0
- package/dist/web/trust/store.d.ts +150 -0
- package/dist/web/trust/store.d.ts.map +1 -0
- package/dist/web/trust/store.js +587 -0
- package/dist/web/trust/store.js.map +1 -0
- package/dist/web/trust/types.d.ts +134 -0
- package/dist/web/trust/types.d.ts.map +1 -0
- package/dist/web/trust/types.js +4 -0
- package/dist/web/trust/types.js.map +1 -0
- package/dist/web/types.d.ts +115 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/types.js +2 -0
- package/dist/web/types.js.map +1 -0
- package/dist/web/util.d.ts +12 -0
- package/dist/web/util.d.ts.map +1 -0
- package/dist/web/util.js +54 -0
- package/dist/web/util.js.map +1 -0
- package/dist/web/webrtc.d.ts +35 -0
- package/dist/web/webrtc.d.ts.map +1 -0
- package/dist/web/webrtc.js +304 -0
- package/dist/web/webrtc.js.map +1 -0
- package/package.json +138 -4
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Aval` — the peer endorsement, and the line it cannot cross.
|
|
3
|
+
*
|
|
4
|
+
* ─── WHY AN AVAL IS STRUCTURALLY NOT A CITA ─────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* An `Aval` is a peer assertion *about a claim*: `avalador → avalado`, subject =
|
|
7
|
+
* a credential hash, carrying `metodoVerificacion` (how the checker checked) and
|
|
8
|
+
* no patient, no date of encounter, no diagnosis, no content. A `Cita` is a
|
|
9
|
+
* patient assertion *about an encounter*, and needs none of those fields.
|
|
10
|
+
*
|
|
11
|
+
* Conflating them destroys the anti-Sybil property, so the separation is
|
|
12
|
+
* enforced three ways here: the type carries a closed `objetoAval` union, the
|
|
13
|
+
* endorsement counter in {@link resumirAvales} only counts the two objects that
|
|
14
|
+
* are about licensure, and {@link OBJETO_QUE_CUENTA} is the single place that
|
|
15
|
+
* decision lives.
|
|
16
|
+
*
|
|
17
|
+
* ─── THE LOAD-BEARING RULE ───────────────────────────────────────────────────
|
|
18
|
+
*
|
|
19
|
+
* Only `licencia_verificada` and `especialidad_verificada` promote a credential
|
|
20
|
+
* to `atestiguada_pares`. An `Aval` of `interaccion_clinica` proves the claimer
|
|
21
|
+
* *treated patients*, not that they are *licensed*. Allowing clinical `Aval`s to
|
|
22
|
+
* count is precisely the hole that lets a well-liked non-doctor buy their way
|
|
23
|
+
* into a network of doctors — money can buy encounters, and it cannot buy a
|
|
24
|
+
* government record.
|
|
25
|
+
*/
|
|
26
|
+
import { bytesAval, hashCredencial, hashLicencia, idAval } from "./canonica.js";
|
|
27
|
+
import { ALCANCE_AVAL, CLASE_VERIFICACION, OBJETO_AVAL, VERSION_MODELO, } from "./types.js";
|
|
28
|
+
/** Why an `Aval` was refused. Every value means it does not count. */
|
|
29
|
+
export const MOTIVO_RECHAZO_AVAL = {
|
|
30
|
+
/** `avalador === avalado`. The `auto_emision` rule, copied. */
|
|
31
|
+
AUTO_ENDORSEMENT: "auto_endorsement",
|
|
32
|
+
/** No signature bytes. */
|
|
33
|
+
FIRMA_AUSENTE: "firma_ausente",
|
|
34
|
+
/** Signature does not verify against the avalador's public key. */
|
|
35
|
+
FIRMA_INVALIDA: "firma_invalida",
|
|
36
|
+
/** `objetoAval`, `alcance`, `revocable` or `metodoVerificacion.clase` invalid. */
|
|
37
|
+
CAMPO_INVALIDO: "campo_invalido",
|
|
38
|
+
/** `emitidoEn` / `vigenteHasta` incoherent. */
|
|
39
|
+
VIGENCIA_INVALIDA: "vigencia_invalida",
|
|
40
|
+
/** The `Aval` has lapsed. */
|
|
41
|
+
AVAL_CADUCADO: "aval_caducado",
|
|
42
|
+
/** `metodoVerificacion: 'registro_por_pais'` without `versionRegistro`. */
|
|
43
|
+
VERSION_REGISTRO_AUSENTE: "version_registro_ausente",
|
|
44
|
+
};
|
|
45
|
+
function fallo(motivo, detalle) {
|
|
46
|
+
return { ok: false, motivo, detalle, cuentaParaPromocion: false };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The only `objetoAval` values that may promote a credential to
|
|
50
|
+
* `atestiguada_pares`.
|
|
51
|
+
*
|
|
52
|
+
* Exported as data so that the rule has exactly one definition in the codebase.
|
|
53
|
+
* If a test, a counter or a threshold function disagreed with this set, a
|
|
54
|
+
* clinical `Aval` would end up counting toward licensure somewhere.
|
|
55
|
+
*/
|
|
56
|
+
export const OBJETO_QUE_CUENTA = [
|
|
57
|
+
OBJETO_AVAL.LICENCIA_VERIFICADA,
|
|
58
|
+
OBJETO_AVAL.ESPECIALIDAD_VERIFICADA,
|
|
59
|
+
];
|
|
60
|
+
export function avalCuentaParaPromocion(objeto) {
|
|
61
|
+
return OBJETO_QUE_CUENTA.includes(objeto);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Structural validation of an `Aval`, no signature check. Cheap first, PQC last,
|
|
65
|
+
* same ordering as the credential path.
|
|
66
|
+
*
|
|
67
|
+
* @param ahora - injected clock (ms epoch). The function never reads the clock
|
|
68
|
+
* itself, which is what keeps it pure.
|
|
69
|
+
*/
|
|
70
|
+
export function validarAval(aval, ahora) {
|
|
71
|
+
if (!aval || typeof aval !== "object") {
|
|
72
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "el aval no es un objeto");
|
|
73
|
+
}
|
|
74
|
+
// ── Self-endorsement, refused first and unconditionally ──
|
|
75
|
+
// `KarmaManager.applyTransaction` refuses `emisor === sujeto` with
|
|
76
|
+
// `auto_emision`; the same rule, copied, because the failure mode is identical
|
|
77
|
+
// (one node manufacturing its own evidence).
|
|
78
|
+
if (aval.avalador === aval.avalado) {
|
|
79
|
+
return fallo(MOTIVO_RECHAZO_AVAL.AUTO_ENDORSEMENT, `${aval.avalador} no puede avalarse a sí mismo (equivale a auto_emision en karma.ts)`);
|
|
80
|
+
}
|
|
81
|
+
if (aval.version !== VERSION_MODELO) {
|
|
82
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, `version no soportada: ${String(aval.version)}`);
|
|
83
|
+
}
|
|
84
|
+
if (!Object.values(OBJETO_AVAL).includes(aval.objetoAval)) {
|
|
85
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, `objetoAval desconocido: ${String(aval.objetoAval)}`);
|
|
86
|
+
}
|
|
87
|
+
if (!Object.values(ALCANCE_AVAL).includes(aval.alcance)) {
|
|
88
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, `alcance desconocido: ${String(aval.alcance)}`);
|
|
89
|
+
}
|
|
90
|
+
if (aval.revocable !== true) {
|
|
91
|
+
// An `Aval` that is not revocable is a permanent fact, and the design says
|
|
92
|
+
// endorsements must be revocable (`docs/medico/protocolo.md` §5).
|
|
93
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "revocable debe ser true: todo aval es revocable");
|
|
94
|
+
}
|
|
95
|
+
if (!aval.credencialRef || !aval.hashCredencial) {
|
|
96
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "un aval debe referirse a una credencial concreta (credencialRef + hashCredencial)");
|
|
97
|
+
}
|
|
98
|
+
// ── `metodoVerificacion` must be complete for its class ──
|
|
99
|
+
const metodo = aval.metodoVerificacion;
|
|
100
|
+
if (!metodo || !Object.values(CLASE_VERIFICACION).includes(metodo.clase)) {
|
|
101
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "metodoVerificacion.clase desconocida");
|
|
102
|
+
}
|
|
103
|
+
if (metodo.clase === CLASE_VERIFICACION.REGISTRO_POR_PAIS) {
|
|
104
|
+
// Mandatory so a stale snapshot is visible on the face of the record. A
|
|
105
|
+
// registry check with no version cannot be reasoned about later.
|
|
106
|
+
if (!metodo.versionRegistro) {
|
|
107
|
+
return fallo(MOTIVO_RECHAZO_AVAL.VERSION_REGISTRO_AUSENTE, "registro_por_pais exige versionRegistro: sin ella un snapshot obsoleto es indistinguible de uno fresco");
|
|
108
|
+
}
|
|
109
|
+
if (!metodo.pais) {
|
|
110
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "registro_por_pais exige pais");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (metodo.clase === CLASE_VERIFICACION.COLEGIO_DIRECTO && !metodo.ref) {
|
|
114
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "colegio_directo exige ref");
|
|
115
|
+
}
|
|
116
|
+
if (metodo.clase === CLASE_VERIFICACION.SUPERVISION) {
|
|
117
|
+
if (typeof metodo.desde !== "number" || typeof metodo.hasta !== "number") {
|
|
118
|
+
return fallo(MOTIVO_RECHAZO_AVAL.CAMPO_INVALIDO, "supervision exige desde y hasta");
|
|
119
|
+
}
|
|
120
|
+
if (metodo.desde > metodo.hasta) {
|
|
121
|
+
return fallo(MOTIVO_RECHAZO_AVAL.VIGENCIA_INVALIDA, `supervision desde (${metodo.desde}) > hasta (${metodo.hasta})`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// ── Dates ──
|
|
125
|
+
if (typeof aval.emitidoEn !== "number" || !Number.isFinite(aval.emitidoEn)) {
|
|
126
|
+
return fallo(MOTIVO_RECHAZO_AVAL.VIGENCIA_INVALIDA, `emitidoEn inválido: ${String(aval.emitidoEn)}`);
|
|
127
|
+
}
|
|
128
|
+
if (typeof aval.vigenteHasta !== "number" ||
|
|
129
|
+
!Number.isFinite(aval.vigenteHasta)) {
|
|
130
|
+
return fallo(MOTIVO_RECHAZO_AVAL.VIGENCIA_INVALIDA, "vigenteHasta ausente o no numérico");
|
|
131
|
+
}
|
|
132
|
+
if (aval.emitidoEn > aval.vigenteHasta) {
|
|
133
|
+
return fallo(MOTIVO_RECHAZO_AVAL.VIGENCIA_INVALIDA, `emitidoEn (${aval.emitidoEn}) es posterior a vigenteHasta (${aval.vigenteHasta})`);
|
|
134
|
+
}
|
|
135
|
+
if (aval.vigenteHasta <= ahora) {
|
|
136
|
+
return fallo(MOTIVO_RECHAZO_AVAL.AVAL_CADUCADO, `aval caducado: vigente hasta ${aval.vigenteHasta}, ahora ${ahora}`);
|
|
137
|
+
}
|
|
138
|
+
if (!(aval.firma instanceof Uint8Array) || aval.firma.length === 0) {
|
|
139
|
+
return fallo(MOTIVO_RECHAZO_AVAL.FIRMA_AUSENTE, "firma ausente o vacía");
|
|
140
|
+
}
|
|
141
|
+
return { ok: true, aval };
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Verify the avalador's signature over the canonical `Aval` bytes.
|
|
145
|
+
*
|
|
146
|
+
* Note the key must be the *avalador's*, never the avalado's: the whole content
|
|
147
|
+
* of an endorsement is that a second party looked and agreed.
|
|
148
|
+
*/
|
|
149
|
+
export async function verificarFirmaAval(aval, identidad, parPublicoAvalador) {
|
|
150
|
+
try {
|
|
151
|
+
return await identidad.verificar(bytesAval(aval), aval.firma, parPublicoAvalador);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Full validation: structure, then signature. */
|
|
158
|
+
export async function validarAvalFirmado(aval, identidad, parPublicoAvalador, ahora) {
|
|
159
|
+
const estructural = validarAval(aval, ahora);
|
|
160
|
+
if (!estructural.ok)
|
|
161
|
+
return estructural;
|
|
162
|
+
if (!(await verificarFirmaAval(aval, identidad, parPublicoAvalador))) {
|
|
163
|
+
return fallo(MOTIVO_RECHAZO_AVAL.FIRMA_INVALIDA, `la firma no verifica contra la clave pública de ${aval.avalador}`);
|
|
164
|
+
}
|
|
165
|
+
return { ok: true, aval };
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Build and sign an `Aval`.
|
|
169
|
+
*
|
|
170
|
+
* `hashCredencial` is computed from the credential object rather than taken on
|
|
171
|
+
* trust, so an `Aval` cannot be minted against a hash that does not match the
|
|
172
|
+
* bytes it claims to have checked.
|
|
173
|
+
*/
|
|
174
|
+
export async function crearAval(borrador, identidadAvalador, credencialVerificada) {
|
|
175
|
+
const id = idAval(borrador.avalador, borrador.avalado, borrador.emitidoEn, borrador.nonce);
|
|
176
|
+
if (credencialVerificada.hash !== borrador.hashCredencial) {
|
|
177
|
+
throw new Error(`crearAval: hashCredencial (${borrador.hashCredencial}) no corresponde a la credencial verificada (${credencialVerificada.hash})`);
|
|
178
|
+
}
|
|
179
|
+
const sinFirmar = {
|
|
180
|
+
id,
|
|
181
|
+
version: VERSION_MODELO,
|
|
182
|
+
avalador: borrador.avalador,
|
|
183
|
+
avalado: borrador.avalado,
|
|
184
|
+
objetoAval: borrador.objetoAval,
|
|
185
|
+
credencialRef: borrador.credencialRef,
|
|
186
|
+
hashCredencial: borrador.hashCredencial,
|
|
187
|
+
metodoVerificacion: borrador.metodoVerificacion,
|
|
188
|
+
evidenciaHash: borrador.evidenciaHash,
|
|
189
|
+
alcance: borrador.alcance,
|
|
190
|
+
emitidoEn: borrador.emitidoEn,
|
|
191
|
+
vigenteHasta: borrador.vigenteHasta,
|
|
192
|
+
revocable: true,
|
|
193
|
+
firma: new Uint8Array(0),
|
|
194
|
+
};
|
|
195
|
+
const firma = await identidadAvalador.firmar(bytesAval(sinFirmar));
|
|
196
|
+
return { ...sinFirmar, firma };
|
|
197
|
+
}
|
|
198
|
+
/** Convenience: hash a credential's canonical bytes for use in `crearAval`. */
|
|
199
|
+
export function prepararCredencialParaAval(credencial) {
|
|
200
|
+
return hashCredencial(credencial);
|
|
201
|
+
}
|
|
202
|
+
/** Convenience: `sha256(normalize(numeroLicencia))`. Never pass the number itself. */
|
|
203
|
+
export function idLicenciaDesdeNumero(numeroLicencia) {
|
|
204
|
+
return hashLicencia(numeroLicencia);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Fold live `Aval`s into a {@link ResumenAvales}.
|
|
208
|
+
*
|
|
209
|
+
* This fold, not a stored fact, is what makes `atestiguada_pares` revocable:
|
|
210
|
+
* drop a revocation and the count falls on the next recomputation.
|
|
211
|
+
*
|
|
212
|
+
* Only unexpired, self-consistent `Aval`s are counted, and only the two
|
|
213
|
+
* licensure objects feed {@link ResumenAvales.verificacionesLicencia}.
|
|
214
|
+
* `avaladoresUnicos` counts distinct signers, not `Aval`s, so one peer endorsing
|
|
215
|
+
* fifty times cannot move the threshold.
|
|
216
|
+
*
|
|
217
|
+
* @param ahora - injected clock. Pure: the function never reads time itself.
|
|
218
|
+
*/
|
|
219
|
+
export function resumirAvales(avales, ahora) {
|
|
220
|
+
const porObjeto = {
|
|
221
|
+
[OBJETO_AVAL.LICENCIA_VERIFICADA]: 0,
|
|
222
|
+
[OBJETO_AVAL.ESPECIALIDAD_VERIFICADA]: 0,
|
|
223
|
+
[OBJETO_AVAL.INTERACCION_CLINICA]: 0,
|
|
224
|
+
[OBJETO_AVAL.DOCENCIA]: 0,
|
|
225
|
+
};
|
|
226
|
+
const avaladoresUnicos = new Set();
|
|
227
|
+
const avaladoresDeLicencia = new Set();
|
|
228
|
+
let ultimoAval;
|
|
229
|
+
let total = 0;
|
|
230
|
+
for (const aval of avales) {
|
|
231
|
+
// Signature verification needs a public key and is async, so it is the
|
|
232
|
+
// caller's job (Phase 3) to hand over already-verified `Aval`s. Structural
|
|
233
|
+
// validity plus expiry is what this pure fold can check on its own.
|
|
234
|
+
if (!validarAval(aval, ahora).ok)
|
|
235
|
+
continue;
|
|
236
|
+
porObjeto[aval.objetoAval] = (porObjeto[aval.objetoAval] ?? 0) + 1;
|
|
237
|
+
avaladoresUnicos.add(aval.avalador);
|
|
238
|
+
if (avalCuentaParaPromocion(aval.objetoAval))
|
|
239
|
+
avaladoresDeLicencia.add(aval.avalador);
|
|
240
|
+
if (ultimoAval === undefined || aval.emitidoEn > ultimoAval)
|
|
241
|
+
ultimoAval = aval.emitidoEn;
|
|
242
|
+
total++;
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
total,
|
|
246
|
+
porObjeto,
|
|
247
|
+
avaladoresUnicos: avaladoresUnicos.size,
|
|
248
|
+
verificacionesLicencia: avaladoresDeLicencia.size,
|
|
249
|
+
...(ultimoAval === undefined ? {} : { ultimoAval }),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Adapt an `Aval` to the existing {@link TransaccionKarma} shape.
|
|
254
|
+
*
|
|
255
|
+
* The signature envelope of an endorsement — `id`, `emisor`, `timestamp`,
|
|
256
|
+
* `firma` — is karma's, reused rather than reinvented, so an `Aval` can ride
|
|
257
|
+
* the OpLog and the replay/idempotency path that already exist.
|
|
258
|
+
*
|
|
259
|
+
* `razon` states *what was verified and how*, so the karma ledger is auditable
|
|
260
|
+
* without a join back to the `Aval`. The subject is the **endorsed** node, which
|
|
261
|
+
* is the node earning standing — matching karma's `sujeto` semantics.
|
|
262
|
+
*
|
|
263
|
+
* `delta` is deliberately left to the caller as `deltaPorAvalacion`: the weight
|
|
264
|
+
* of an `Aval` is a policy decision (DECISIÓN B.3), and this module must not
|
|
265
|
+
* quietly pick one. Note that karma is a *signal* and never grants access
|
|
266
|
+
* (`docs/medico/reglas-red.md` §1).
|
|
267
|
+
*/
|
|
268
|
+
export function aTransaccionKarma(aval, deltaPorAvalacion) {
|
|
269
|
+
return {
|
|
270
|
+
id: aval.id,
|
|
271
|
+
tipo: "aval",
|
|
272
|
+
proyecto: aval.objetoAval,
|
|
273
|
+
sujeto: aval.avalado,
|
|
274
|
+
delta: deltaPorAvalacion,
|
|
275
|
+
razon: `${aval.objetoAval} via ${aval.metodoVerificacion.clase}`,
|
|
276
|
+
emisor: aval.avalador,
|
|
277
|
+
timestamp: aval.emitidoEn,
|
|
278
|
+
firma: aval.firma,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=aval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aval.js","sourceRoot":"","sources":["../../src/medico/aval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical bytes for the medical layer.
|
|
3
|
+
*
|
|
4
|
+
* Every signature in this layer is taken over a *deterministic* serialisation,
|
|
5
|
+
* because a signature that covers `JSON.stringify` output is not verifiable by
|
|
6
|
+
* anyone who re-serialises in a different key order. The pattern is lifted from
|
|
7
|
+
* `src/maloca/karma.ts` (`canonicalStringify`) rather than reinvented, so the
|
|
8
|
+
* medical layer and the karma layer agree on what "the same bytes" means.
|
|
9
|
+
*
|
|
10
|
+
* `canonicalEnvelopeBytes` in `src/protocol/index.ts` does the same job for the
|
|
11
|
+
* transport envelope. Three copies of this idea in the repo is a smell, but the
|
|
12
|
+
* envelope format is owned by a parallel agent and the karma one is internal to
|
|
13
|
+
* its module, so this file keeps its own copy instead of exporting a helper from
|
|
14
|
+
* a file that may change underneath it.
|
|
15
|
+
*
|
|
16
|
+
* Pure: no I/O, no clock, no randomness, no network. Hashing goes through WebCrypto
|
|
17
|
+
* (`crypto.subtle`), the same primitive `src/identity/index.ts` uses, so the
|
|
18
|
+
* module runs unchanged in Node and in the browser transport.
|
|
19
|
+
*/
|
|
20
|
+
import type { NodoId } from "../types/index.js";
|
|
21
|
+
import type { Aval, CredencialMedica } from "./types.js";
|
|
22
|
+
/** Hex encoding of a byte array, lower case. */
|
|
23
|
+
export declare function bytesAHex(bytes: Uint8Array): string;
|
|
24
|
+
export declare function hexABytes(hex: string): Uint8Array;
|
|
25
|
+
/**
|
|
26
|
+
* Deterministically stringify for signing: object keys sorted, arrays in order,
|
|
27
|
+
* `undefined` members dropped, byte arrays hex-encoded.
|
|
28
|
+
*
|
|
29
|
+
* `undefined` is dropped rather than serialised as `null` so that an absent
|
|
30
|
+
* optional field and a present one holding `undefined` cannot produce two
|
|
31
|
+
* different signed payloads for what the caller means as the same record.
|
|
32
|
+
*/
|
|
33
|
+
export declare function canonicalStringify(obj: unknown): string;
|
|
34
|
+
export declare function canonicalBytes(obj: unknown): Uint8Array;
|
|
35
|
+
/**
|
|
36
|
+
* The exact fields a credential signature covers: everything except `firma`
|
|
37
|
+
* itself. A signature cannot be inside the bytes it signs.
|
|
38
|
+
*/
|
|
39
|
+
export declare function canonicalizarCredencial(credencial: CredencialMedica): Record<string, unknown>;
|
|
40
|
+
export declare function bytesCredencial(credencial: CredencialMedica): Uint8Array;
|
|
41
|
+
/** The exact fields an `Aval` signature covers: everything except `firma`. */
|
|
42
|
+
export declare function canonicalizarAval(aval: Aval): Record<string, unknown>;
|
|
43
|
+
export declare function bytesAval(aval: Aval): Uint8Array;
|
|
44
|
+
/**
|
|
45
|
+
* SHA-256 via WebCrypto — the same primitive, and the same copy-into-a-fresh-
|
|
46
|
+
* `ArrayBuffer` workaround, as `src/identity/index.ts`.
|
|
47
|
+
*
|
|
48
|
+
* Async because `crypto.subtle` is. Every caller in this layer is already async
|
|
49
|
+
* (`firmar`, `verificar`), so no synchronous substitute is exposed in its place.
|
|
50
|
+
*
|
|
51
|
+
* Copying matters: the input may be a `Uint8Array` view over a larger backing
|
|
52
|
+
* store that is not itself an `ArrayBuffer`, which `subtle.digest` rejects.
|
|
53
|
+
*/
|
|
54
|
+
export declare function sha256(datos: Uint8Array): Promise<Uint8Array>;
|
|
55
|
+
/** Lower-case hex of {@link sha256}. */
|
|
56
|
+
export declare function sha256Hex(datos: Uint8Array): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* SHA-256 over the canonical credential bytes, lower-case hex.
|
|
59
|
+
*
|
|
60
|
+
* This is what `Aval.hashCredencial` binds to: an `Aval` covers *exact*
|
|
61
|
+
* credential bytes, so editing a credential after endorsement invalidates every
|
|
62
|
+
* `Aval` bound to the old hash (`docs/medico/protocolo.md` Phase 3).
|
|
63
|
+
*/
|
|
64
|
+
export declare function hashCredencial(credencial: CredencialMedica): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Normalise a licence number the way the registry does, before hashing.
|
|
67
|
+
*
|
|
68
|
+
* Mirrors `LicenseVerifier.verify` in
|
|
69
|
+
* `apps/OrionHealth/lib/features/doctor_verification/domain/services/license_verifier.dart`:
|
|
70
|
+
* strip whitespace, upper-case. The *number* never leaves this function — only
|
|
71
|
+
* its hash is ever published.
|
|
72
|
+
*/
|
|
73
|
+
export declare function normalizarLicencia(numero: string): string;
|
|
74
|
+
/** `sha256(normalize(licenceNumber))`, lower-case hex. The public-safe id. */
|
|
75
|
+
export declare function hashLicencia(numeroLicencia: string): Promise<string>;
|
|
76
|
+
/** Domain separation for credential ids. */
|
|
77
|
+
export declare const DOMINIO_ID_CREDENCIAL = "shelf-edge-mesh/v1/id-credencial";
|
|
78
|
+
/**
|
|
79
|
+
* Stable credential id: `hash(idLicencia + tipo + pais)`.
|
|
80
|
+
*
|
|
81
|
+
* Each component is hex-encoded and joined with a separator before hashing, so
|
|
82
|
+
* no two different triples can produce the same pre-image by moving characters
|
|
83
|
+
* across a field boundary — `('AB','licencia','CO')` must not collide with
|
|
84
|
+
* `('A','blicencia','CO')`.
|
|
85
|
+
*/
|
|
86
|
+
export declare function idCredencial(idLicencia: string, tipo: string, pais: string): Promise<string>;
|
|
87
|
+
/**
|
|
88
|
+
* Build an `Aval` id: `${avalador}:${avalado}:${timestamp}:${nonce}`.
|
|
89
|
+
*
|
|
90
|
+
* The nonce is what makes this an idempotency key rather than a timestamp: two
|
|
91
|
+
* independent avaladores never collide, and a captured `Aval` replayed from the
|
|
92
|
+
* OpLog is recognised as already applied and cannot be counted twice
|
|
93
|
+
* (`docs/medico/protocolo.md` Phase 3).
|
|
94
|
+
*/
|
|
95
|
+
export declare function idAval(avalador: NodoId, avalado: NodoId, timestamp: number, nonce: string): string;
|
|
96
|
+
//# sourceMappingURL=canonica.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonica.d.ts","sourceRoot":"","sources":["../../src/medico/canonica.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEzD,gDAAgD;AAChD,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAInD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAQjD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAUvD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAEvD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACtC,UAAU,EAAE,gBAAgB,GAC1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,gBAAgB,GAAG,UAAU,CAExE;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGrE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,UAAU,CAEhD;AAED;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAInE;AAED,wCAAwC;AACxC,wBAAsB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAElE;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CACnC,UAAU,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,8EAA8E;AAC9E,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI1E;AAED,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB,qCAAqC,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAsB,YAAY,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACX,MAAM,CAER"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical bytes for the medical layer.
|
|
3
|
+
*
|
|
4
|
+
* Every signature in this layer is taken over a *deterministic* serialisation,
|
|
5
|
+
* because a signature that covers `JSON.stringify` output is not verifiable by
|
|
6
|
+
* anyone who re-serialises in a different key order. The pattern is lifted from
|
|
7
|
+
* `src/maloca/karma.ts` (`canonicalStringify`) rather than reinvented, so the
|
|
8
|
+
* medical layer and the karma layer agree on what "the same bytes" means.
|
|
9
|
+
*
|
|
10
|
+
* `canonicalEnvelopeBytes` in `src/protocol/index.ts` does the same job for the
|
|
11
|
+
* transport envelope. Three copies of this idea in the repo is a smell, but the
|
|
12
|
+
* envelope format is owned by a parallel agent and the karma one is internal to
|
|
13
|
+
* its module, so this file keeps its own copy instead of exporting a helper from
|
|
14
|
+
* a file that may change underneath it.
|
|
15
|
+
*
|
|
16
|
+
* Pure: no I/O, no clock, no randomness, no network. Hashing goes through WebCrypto
|
|
17
|
+
* (`crypto.subtle`), the same primitive `src/identity/index.ts` uses, so the
|
|
18
|
+
* module runs unchanged in Node and in the browser transport.
|
|
19
|
+
*/
|
|
20
|
+
/** Hex encoding of a byte array, lower case. */
|
|
21
|
+
export function bytesAHex(bytes) {
|
|
22
|
+
let out = "";
|
|
23
|
+
for (const b of bytes)
|
|
24
|
+
out += b.toString(16).padStart(2, "0");
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
export function hexABytes(hex) {
|
|
28
|
+
if (hex.length % 2 !== 0 || /[^0-9a-fA-F]/.test(hex)) {
|
|
29
|
+
throw new TypeError("hexABytes: input must be an even-length hex string");
|
|
30
|
+
}
|
|
31
|
+
const out = new Uint8Array(hex.length / 2);
|
|
32
|
+
for (let i = 0; i < out.length; i++)
|
|
33
|
+
out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Deterministically stringify for signing: object keys sorted, arrays in order,
|
|
38
|
+
* `undefined` members dropped, byte arrays hex-encoded.
|
|
39
|
+
*
|
|
40
|
+
* `undefined` is dropped rather than serialised as `null` so that an absent
|
|
41
|
+
* optional field and a present one holding `undefined` cannot produce two
|
|
42
|
+
* different signed payloads for what the caller means as the same record.
|
|
43
|
+
*/
|
|
44
|
+
export function canonicalStringify(obj) {
|
|
45
|
+
if (obj === null || typeof obj !== "object")
|
|
46
|
+
return JSON.stringify(obj) ?? "null";
|
|
47
|
+
if (obj instanceof Uint8Array)
|
|
48
|
+
return JSON.stringify(bytesAHex(obj));
|
|
49
|
+
if (Array.isArray(obj))
|
|
50
|
+
return `[${obj.map(canonicalStringify).join(",")}]`;
|
|
51
|
+
const source = obj;
|
|
52
|
+
const keys = Object.keys(source)
|
|
53
|
+
.filter((k) => source[k] !== undefined)
|
|
54
|
+
.sort();
|
|
55
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalStringify(source[k])}`).join(",")}}`;
|
|
56
|
+
}
|
|
57
|
+
export function canonicalBytes(obj) {
|
|
58
|
+
return new TextEncoder().encode(canonicalStringify(obj));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The exact fields a credential signature covers: everything except `firma`
|
|
62
|
+
* itself. A signature cannot be inside the bytes it signs.
|
|
63
|
+
*/
|
|
64
|
+
export function canonicalizarCredencial(credencial) {
|
|
65
|
+
const { firma: _firma, ...resto } = credencial;
|
|
66
|
+
return { ...resto };
|
|
67
|
+
}
|
|
68
|
+
export function bytesCredencial(credencial) {
|
|
69
|
+
return canonicalBytes(canonicalizarCredencial(credencial));
|
|
70
|
+
}
|
|
71
|
+
/** The exact fields an `Aval` signature covers: everything except `firma`. */
|
|
72
|
+
export function canonicalizarAval(aval) {
|
|
73
|
+
const { firma: _firma, ...resto } = aval;
|
|
74
|
+
return { ...resto };
|
|
75
|
+
}
|
|
76
|
+
export function bytesAval(aval) {
|
|
77
|
+
return canonicalBytes(canonicalizarAval(aval));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* SHA-256 via WebCrypto — the same primitive, and the same copy-into-a-fresh-
|
|
81
|
+
* `ArrayBuffer` workaround, as `src/identity/index.ts`.
|
|
82
|
+
*
|
|
83
|
+
* Async because `crypto.subtle` is. Every caller in this layer is already async
|
|
84
|
+
* (`firmar`, `verificar`), so no synchronous substitute is exposed in its place.
|
|
85
|
+
*
|
|
86
|
+
* Copying matters: the input may be a `Uint8Array` view over a larger backing
|
|
87
|
+
* store that is not itself an `ArrayBuffer`, which `subtle.digest` rejects.
|
|
88
|
+
*/
|
|
89
|
+
export async function sha256(datos) {
|
|
90
|
+
const buffer = new ArrayBuffer(datos.length);
|
|
91
|
+
new Uint8Array(buffer).set(datos);
|
|
92
|
+
return new Uint8Array(await crypto.subtle.digest("SHA-256", buffer));
|
|
93
|
+
}
|
|
94
|
+
/** Lower-case hex of {@link sha256}. */
|
|
95
|
+
export async function sha256Hex(datos) {
|
|
96
|
+
return bytesAHex(await sha256(datos));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* SHA-256 over the canonical credential bytes, lower-case hex.
|
|
100
|
+
*
|
|
101
|
+
* This is what `Aval.hashCredencial` binds to: an `Aval` covers *exact*
|
|
102
|
+
* credential bytes, so editing a credential after endorsement invalidates every
|
|
103
|
+
* `Aval` bound to the old hash (`docs/medico/protocolo.md` Phase 3).
|
|
104
|
+
*/
|
|
105
|
+
export async function hashCredencial(credencial) {
|
|
106
|
+
return sha256Hex(bytesCredencial(credencial));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Normalise a licence number the way the registry does, before hashing.
|
|
110
|
+
*
|
|
111
|
+
* Mirrors `LicenseVerifier.verify` in
|
|
112
|
+
* `apps/OrionHealth/lib/features/doctor_verification/domain/services/license_verifier.dart`:
|
|
113
|
+
* strip whitespace, upper-case. The *number* never leaves this function — only
|
|
114
|
+
* its hash is ever published.
|
|
115
|
+
*/
|
|
116
|
+
export function normalizarLicencia(numero) {
|
|
117
|
+
return numero.replace(/\s+/g, "").toUpperCase();
|
|
118
|
+
}
|
|
119
|
+
/** `sha256(normalize(licenceNumber))`, lower-case hex. The public-safe id. */
|
|
120
|
+
export async function hashLicencia(numeroLicencia) {
|
|
121
|
+
return sha256Hex(new TextEncoder().encode(normalizarLicencia(numeroLicencia)));
|
|
122
|
+
}
|
|
123
|
+
/** Domain separation for credential ids. */
|
|
124
|
+
export const DOMINIO_ID_CREDENCIAL = "shelf-edge-mesh/v1/id-credencial";
|
|
125
|
+
/**
|
|
126
|
+
* Stable credential id: `hash(idLicencia + tipo + pais)`.
|
|
127
|
+
*
|
|
128
|
+
* Each component is hex-encoded and joined with a separator before hashing, so
|
|
129
|
+
* no two different triples can produce the same pre-image by moving characters
|
|
130
|
+
* across a field boundary — `('AB','licencia','CO')` must not collide with
|
|
131
|
+
* `('A','blicencia','CO')`.
|
|
132
|
+
*/
|
|
133
|
+
export async function idCredencial(idLicencia, tipo, pais) {
|
|
134
|
+
const partes = [DOMINIO_ID_CREDENCIAL, idLicencia, tipo, pais].map((p) => bytesAHex(new TextEncoder().encode(p)));
|
|
135
|
+
return sha256Hex(new TextEncoder().encode(partes.join("|")));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Build an `Aval` id: `${avalador}:${avalado}:${timestamp}:${nonce}`.
|
|
139
|
+
*
|
|
140
|
+
* The nonce is what makes this an idempotency key rather than a timestamp: two
|
|
141
|
+
* independent avaladores never collide, and a captured `Aval` replayed from the
|
|
142
|
+
* OpLog is recognised as already applied and cannot be counted twice
|
|
143
|
+
* (`docs/medico/protocolo.md` Phase 3).
|
|
144
|
+
*/
|
|
145
|
+
export function idAval(avalador, avalado, timestamp, nonce) {
|
|
146
|
+
return `${avalador}:${avalado}:${timestamp}:${nonce}`;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=canonica.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonica.js","sourceRoot":"","sources":["../../src/medico/canonica.ts"],"names":[],"mappings":"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"}
|