{"_id":"@closerclick/closer-click-reputation","_rev":"6-387c7913137c1fd35ddb7818f9f92a21","name":"@closerclick/closer-click-reputation","dist-tags":{"latest":"0.5.0"},"versions":{"0.1.0":{"name":"@closerclick/closer-click-reputation","version":"0.1.0","keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"author":{"name":"seyacat"},"license":"MIT","_id":"@closerclick/closer-click-reputation@0.1.0","maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"homepage":"https://github.com/closerclick/closer-click-reputation#readme","bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"dist":{"shasum":"4256d457abc302011ea5e573232da9f052f9ce50","tarball":"https://registry.npmjs.org/@closerclick/closer-click-reputation/-/closer-click-reputation-0.1.0.tgz","fileCount":6,"integrity":"sha512-PG8EQw4X3i1Me59jqbAxP+CTbiRgOGH4TK5vy6qnyWdlrtpxdkP9w0aQIHMX+2qK09lGf34IaE9LEmtMtl0Plw==","signatures":[{"sig":"MEUCIGPlgpIC3cOrsVq9z4pGJA3RHqWvEiIEW+ucSlgoPFHcAiEA2PWxFzgcTaD9TDBBdV60nWBbDIIZYQevaeYv1+PnWf8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17554},"main":"src/index.js","type":"module","types":"src/index.d.ts","module":"src/index.js","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"}},"gitHead":"7f56c94a74aba42a2d8954283943ea8359b61585","scripts":{"test":"node --test"},"_npmUser":{"name":"mycloserclick","email":"admin@closer.click"},"repository":{"url":"git+https://github.com/closerclick/closer-click-reputation.git","type":"git"},"_npmVersion":"11.12.1","description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/closer-click-reputation_0.1.0_1780372857398_0.15627129818598395","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@closerclick/closer-click-reputation","version":"0.2.0","keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"author":{"name":"seyacat"},"license":"MIT","_id":"@closerclick/closer-click-reputation@0.2.0","maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"homepage":"https://github.com/closerclick/closer-click-reputation#readme","bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"dist":{"shasum":"656299af54ef3ccf48b5d25613ffbd1e5d4ec344","tarball":"https://registry.npmjs.org/@closerclick/closer-click-reputation/-/closer-click-reputation-0.2.0.tgz","fileCount":6,"integrity":"sha512-GyXWZiykXoz8bChdmU/xOoPgLKPqFsZx7/j54OQZEHn4nlUg2e2OLNs+7xBR9DbmNk9HtSPRzYThnsaf9QDD3A==","signatures":[{"sig":"MEUCIQDq36yzGBhe+lCmuhYsDlqWvwE8q0nNCm9isqloWm4r4AIgZTbaGNhPia8XA8fPxd9UGhapcrYeggdmafBn8p00Npo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22178},"main":"src/index.js","type":"module","types":"src/index.d.ts","module":"src/index.js","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"}},"gitHead":"1f4f9d7f7c91e93388cc3e164618a6764b46eead","scripts":{"test":"node --test"},"_npmUser":{"name":"mycloserclick","email":"admin@closer.click"},"repository":{"url":"git+https://github.com/closerclick/closer-click-reputation.git","type":"git"},"_npmVersion":"11.12.1","description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/closer-click-reputation_0.2.0_1780373254537_0.3387021420148457","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@closerclick/closer-click-reputation","version":"0.3.0","keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"author":{"name":"seyacat"},"license":"MIT","_id":"@closerclick/closer-click-reputation@0.3.0","maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"homepage":"https://github.com/closerclick/closer-click-reputation#readme","bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"dist":{"shasum":"b002b6e8b6d97015dccf88be15e03514c4e38b87","tarball":"https://registry.npmjs.org/@closerclick/closer-click-reputation/-/closer-click-reputation-0.3.0.tgz","fileCount":6,"integrity":"sha512-V4Rmxestby/sTqaUY/yAvV6jYsEbQ8K9eL0fr7dXOiERIH9w4SalMMFFeD8v3wX6S8/K+4XAv8tZlAMQYO3OdA==","signatures":[{"sig":"MEUCIGKeXYqWLrlwx36MMtjGBKf7e23228J4RqrGCtO/GcJ7AiEA1pAl/aX/6SC7F2heMDtGSJoG8TXm0x9OG9S8lPG28kU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27075},"main":"src/index.js","type":"module","types":"src/index.d.ts","module":"src/index.js","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"}},"gitHead":"f2f2b9b455ee2e7da1900172a67dcaa6b968c701","scripts":{"test":"node --test"},"_npmUser":{"name":"mycloserclick","email":"admin@closer.click"},"repository":{"url":"git+https://github.com/closerclick/closer-click-reputation.git","type":"git"},"_npmVersion":"11.12.1","description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/closer-click-reputation_0.3.0_1780408743587_0.8596687716425973","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@closerclick/closer-click-reputation","version":"0.3.1","keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"author":{"name":"seyacat"},"license":"MIT","_id":"@closerclick/closer-click-reputation@0.3.1","maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"homepage":"https://github.com/closerclick/closer-click-reputation#readme","bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"dist":{"shasum":"fe715f5b6a73ee2cf3e58007693ce4c6a70da3ec","tarball":"https://registry.npmjs.org/@closerclick/closer-click-reputation/-/closer-click-reputation-0.3.1.tgz","fileCount":6,"integrity":"sha512-vIng2mbEQYaOBMfRA2g5mzuUk1rI4mDfElXz9T/cz9SuZEuD0pL7Md83dp3yd9Rp8Bge8gIczVL3R8zTnQo89g==","signatures":[{"sig":"MEUCIBvFKs9R8ujif8lAtDsBbbM32hOnZCYQaRvslD+B4YFcAiEA7PYb0T5QmZHLg0yYvsbUNj5x52tin2WPbc24asLLmaI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28899},"main":"src/index.js","type":"module","types":"src/index.d.ts","module":"src/index.js","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"}},"gitHead":"73ce395c1c87d72e3be4ded934c6a00156817199","scripts":{"test":"node --test"},"_npmUser":{"name":"mycloserclick","email":"admin@closer.click"},"repository":{"url":"git+https://github.com/closerclick/closer-click-reputation.git","type":"git"},"_npmVersion":"11.12.1","description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/closer-click-reputation_0.3.1_1780505197903_0.9775341600076819","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@closerclick/closer-click-reputation","version":"0.4.0","keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"author":{"name":"seyacat"},"license":"MIT","_id":"@closerclick/closer-click-reputation@0.4.0","maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"homepage":"https://github.com/closerclick/closer-click-reputation#readme","bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"dist":{"shasum":"3f71ebe27af91d2fe0d42cd864f44cb1c5c76a32","tarball":"https://registry.npmjs.org/@closerclick/closer-click-reputation/-/closer-click-reputation-0.4.0.tgz","fileCount":6,"integrity":"sha512-sDa++ftG8VeQnYrspHKLGpddel4OpGCarjJjLZlhAmuhOm9p20ihZOusOti1Q+0eE0Y/QvQQNivEInbENv6fog==","signatures":[{"sig":"MEQCIDOw7wGN5kvk5cT0HGb2fPAUzRRc4tV63ioWWfIGO9K8AiB518pEgarJeJ9SpcxFlpA0Xfbn9XKOiiIk40kL+0DrNQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31076},"main":"src/index.js","type":"module","types":"src/index.d.ts","module":"src/index.js","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"}},"gitHead":"6407b4984ea0e1d8246ecc92f24482a9a7e33a8a","scripts":{"test":"node --test"},"_npmUser":{"name":"mycloserclick","email":"admin@closer.click"},"repository":{"url":"git+https://github.com/closerclick/closer-click-reputation.git","type":"git"},"_npmVersion":"11.12.1","description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","directories":{},"_nodeVersion":"25.9.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/closer-click-reputation_0.4.0_1780534467020_0.7106956632295569","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@closerclick/closer-click-reputation","version":"0.5.0","description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","type":"module","main":"src/index.js","module":"src/index.js","types":"src/index.d.ts","exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"}},"scripts":{"test":"node --test"},"keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"author":{"name":"seyacat"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/closerclick/closer-click-reputation.git"},"gitHead":"bc06aff600111d6e71018edaa3ea0f1878d074f0","_id":"@closerclick/closer-click-reputation@0.5.0","bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"homepage":"https://github.com/closerclick/closer-click-reputation#readme","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-MsEYksun6704mMWu/Zkei+oiBNiGwhJKEQ0/nRDzrLz6QVaYtNzDJa59iutnKI+3kNvFFpmCh0pn8nT5PdPpMg==","shasum":"b5ada5ad9b39d0569bb1df0150857dc7b002b934","tarball":"https://registry.npmjs.org/@closerclick/closer-click-reputation/-/closer-click-reputation-0.5.0.tgz","fileCount":6,"unpackedSize":33999,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIC3b4XDymTsH6jdUzQY4PUa35BWVxaPHt/bRefjZNgKAAiEA/yEj0Vt1dpbd1u0OhbdvqKJJlA9HTuD+d/KwwSNWEaA="}]},"_npmUser":{"name":"mycloserclick","email":"admin@closer.click"},"directories":{},"maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/closer-click-reputation_0.5.0_1780550237065_0.5513385743903803"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-02T04:00:57.235Z","modified":"2026-06-04T05:17:17.345Z","0.1.0":"2026-06-02T04:00:57.551Z","0.2.0":"2026-06-02T04:07:34.680Z","0.3.0":"2026-06-02T13:59:03.755Z","0.3.1":"2026-06-03T16:46:38.043Z","0.4.0":"2026-06-04T00:54:27.208Z","0.5.0":"2026-06-04T05:17:17.218Z"},"bugs":{"url":"https://github.com/closerclick/closer-click-reputation/issues"},"author":{"name":"seyacat"},"license":"MIT","homepage":"https://github.com/closerclick/closer-click-reputation#readme","keywords":["reputation","web-of-trust","sybil-resistant","attestation","closer-click","ecdsa"],"repository":{"type":"git","url":"git+https://github.com/closerclick/closer-click-reputation.git"},"description":"Cliente del registro de reputación de Closer Click (reputation.closer.click): atestaciones firmadas + agregación anti-sybil anclada en web-of-trust","maintainers":[{"name":"mycloserclick","email":"admin@closer.click"}],"readme":"# @closerclick/closer-click-reputation\n\n**Registro de reputación** del ecosistema CloserClick: `reputation.closer.click`.\n**Quinto pilar**, complementario a identidad, transporte (proxy), almacenamiento\n(store) y descubrimiento (geo).\n\n| Pilar | Paquete | Rol |\n|-------|---------|-----|\n| Identidad | `closer-click-identity` | clave del vault, firma, **web-of-trust local** |\n| Transporte | `closer-click-proxy-client` | mensajería, canales, WebRTC (efímero) |\n| Almacenamiento | `closer-click-store` | datos del usuario en su navegador |\n| Descubrimiento geo | `closer-click-geo` | encontrar identidades cercanas (efímero) |\n| **Reputación** | **`closer-click-reputation`** | **atestaciones firmadas compartidas (persistente)** |\n\n## El registro es un tablón de atestaciones firmadas, no un juez\n\nA diferencia de geo/proxy (efímeros), este registro es **persistente** — pero lo\nque guarda es **opinión pública firmada**, no datos privados de peers. Cada fila\nes `{ subject, issuer, rating 0–5, notes?, ts, receipt? }` **firmada por el\nemisor**: el server no puede falsificarla y, si desaparece, las atestaciones\nsiguen donde cada peer las cacheó.\n\n**El server NO calcula un score** (eso sería trivial de atacar con sybils). Sólo\nalmacena y sirve las atestaciones crudas. **El significado se computa en el\ncliente.**\n\n## Anti-sybil: la confianza está anclada en vos\n\n`aggregateTrust(subject, { trustOf, ... })` pondera cada atestación por **cuánto\nconfiás VOS en quien la emite** (web-of-trust transitivo con decaimiento por\ndistancia). Consecuencias:\n\n- Un **flood de bots desconocidos vale ~0**: no podés rastrearlos a nadie en\n  quien confiás → no mueven la aguja. No hay número global que mover.\n- Defiende **las dos direcciones**: auto-inflado (sybils que se suben el rating)\n  y review-bombing (sybils que hunden a un objetivo).\n- **Cold-start honesto**: un vendedor nuevo legítimo también arranca sin score\n  para vos (mismo mecanismo). Mostrá el conteo crudo etiquetado aparte como\n  señal débil.\n\nLa confianza personal (`trustOf`) sale del **web-of-trust local del vault**\n(`getRatingsForSubject`/agregación). Local = mi opinión; registro = atestaciones\ncompartidas y consultables.\n\n## Instalación\n\n```bash\nnpm i @closerclick/closer-click-reputation\n```\n\n## Uso\n\n```js\nimport { createReputationClient } from '@closerclick/closer-click-reputation'\nimport identity from '@closerclick/closer-click-identity' // el vault\n\nconst rep = createReputationClient({\n  signData: identity.signData,\n  getPublicKeyJwk: identity.getPublicKeyJwk\n})\n\n// Calificar a un peer tras un trato (opcionalmente con recibo co-firmado)\nawait rep.publishRating({ subject: sellerPubkey, rating: 5, notes: 'todo ok' })\n\n// Ver la reputación del peer, ponderada por MI web-of-trust\nconst r = await rep.aggregateTrust(sellerPubkey, {\n  trustOf: async pk => myVaultTrustOf(pk),   // 0..1, o null si no tengo opinión\n  myPubkey: await identity.getPublicKeyJwk()\n})\n// r = { score: 0.92|null, confidence, trustedCount, rawCount, txBoundCount, samples }\n// score null + rawCount alto  => \"muchas reseñas, ninguna de tu red\" (señal débil)\n```\n\n### Multiindicador (v0.3.0)\n\nCada atestación lleva un **mapa de indicadores** independientes (entero 0..5):\n\n```js\nawait rep.rate(peerPubkey, { confianza: 5, afinidad: 3 })   // o rep.rate(pk, 5) → confianza\nconst r = await rep.reputationOf(peerPubkey)\n// r.indicators.confianza.score, r.indicators.afinidad.score  (cada eje independiente)\n// r.score === r.indicators.confianza.score  (compat)\n```\n\n- **`confianza` es el eje especial**: es el **ancla anti-sybil** con la que se\n  ponderan TODOS los indicadores (la credibilidad transitiva se calcula sobre\n  confianza). Los demás ejes (afinidad = me interesa/sigo/conozco, o los que la\n  app defina) se atestan y agregan **igual**, pero no gatean credibilidad.\n- **Compat**: `rating` (número) ↔ `indicators.confianza`; el top-level `score`\n  del resultado sigue siendo confianza. Apps 0.2.x siguen funcionando.\n\n### Integración de 1 línea con el vault (recomendado para apps)\n\nLas apps del ecosistema ya usan el web-of-trust local del vault. `createVaultReputation`\ncablea solo el `trustOf` desde ahí y mantiene local + nube en sync:\n\n```js\nimport { createVaultReputation } from '@closerclick/closer-click-reputation'\nconst rep = createVaultReputation(identity)   // identity = vault conectado\n\nawait rep.rate(peerPubkey, 5, { notes: 'buen trato' })  // guarda local + atesta firmado\nconst r = await rep.reputationOf(peerPubkey)             // ponderado por MI web-of-trust → badge\n```\n\n`identity` debe exponer `me.publickey`, `signData` y `getRatingsForSubject`\n(la instancia de `@closerclick/closer-click-identity`). El paquete no depende de\nidentity: se la inyectás.\n\n### Recibo de transacción (opcional, sube credibilidad)\n\nUna atestación puede llevar un **recibo co-firmado** `{ a, b, ts, sigA, sigB }`\n(ambas partes firman `{op:'receipt',a,b,ts}`). Prueba que hubo una interacción\nreal entre emisor y sujeto; marca la atestación `txBound`. No reemplaza al\nanclaje de confianza (una granja de sybils puede co-firmarse recibos), pero da un\nconteo de interacciones reales y sube el costo del fraude.\n\n## API del servicio (HTTP/JSON)\n\n| Método | Ruta | Auth | Descripción |\n|--------|------|------|-------------|\n| `PUT` | `/ratings` | sobre firmado por el emisor | publica/reemplaza una atestación |\n| `DELETE` | `/ratings` | sobre firmado | retira la atestación del emisor |\n| `GET` | `/ratings?subject=<JWK>` | pública | atestaciones crudas sobre un sujeto |\n| `GET` | `/health` | — | liveness |\n\nVer [`server/`](./server) y [`DEPLOY.md`](./DEPLOY.md). **Independiente de geo**:\nbase Postgres propia, puerto propio, despliegue propio (escalable a otro server).\n\n## Licencia\n\nMIT\n","readmeFilename":"README.md"}