npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ninepayjs/guardian-sdk

v0.1.1

Published

SDK do Guardian (antifraude da NinePay): fingerprint do dispositivo e sinais de comportamento no checkout, sem o conteúdo dos campos.

Readme

Guardian SDK (@ninepayjs/guardian-sdk)

O lado do navegador do Guardian, o antifraude da NinePay: a impressão digital do dispositivo (ThumbmarkJS) e os sinais de comportamento no checkout (ritmo de digitação, mouse, toque, colagem, autopreenchimento), mandados para a API do Guardian. O session_id vai junto com o pagamento, e a API de pagamentos pede a análise ao Guardian antes de cobrar.

Instalar

O escopo é @ninepayjs, a organização da NinePay no npm (conta ti-ninepay). Um guardian-sdk sem escopo, ou em outro escopo, não é nosso.

npm install --save-exact @ninepayjs/guardian-sdk

Numa página de pagamento, o SDK entra no bundle da página (a versão fixa no package-lock.json, revisada a cada troca), e não por <script> de uma CDN: assim ele não é um script de terceiro para o PCI DSS (req. 6.4.3), e a CSP não precisa liberar outro host em script-src.

Uso

import { init, flush, getSessionId } from '@ninepayjs/guardian-sdk'

await init({
  publicKey: 'grd_pk_...',              // a chave pública da company, presa à origem da página
  inputFieldIds: ['cardNumber', 'cardHolder', 'email'],
  styleNonce: '<o nonce da CSP da página>', // opcional, ver "CSP"
})

// Ao clicar em "Pagar":
await flush()                          // envia os eventos ainda pendentes
const sessionId = await getSessionId() // mande junto com o pagamento; se vier undefined, não mande o campo

| Opção | Padrão | O que é | |-|-|-| | publicKey | — | A chave pública da company (grd_pk_...). Sem ela, ou numa origem que não está liberada na chave, o Guardian recusa a sessão (401/403). | | apiUrl | https://guardian.ninepay.com.br/api | A API do Guardian (outra só em desenvolvimento). | | interval | 5000 | De quanto em quanto tempo (ms) os eventos vão para a API. | | inputFieldIds | — | Os ids dos campos cujo preenchimento é medido. | | styleNonce | — | O nonce da CSP, para o <style> da detecção de autopreenchimento nos navegadores sem CSSStyleSheet construível. |

  • getSessionId() espera o init terminar e devolve undefined se a sessão não pôde ser criada. Sem sessão, o SDK não envia eventos.
  • Um envio que falha por rede, 429 ou 5xx devolve os eventos ao lote seguinte, com no máximo 1.500 eventos de mouse e toque por lote (ficam os mais recentes).
  • Se o Guardian recusa a sessão (404: vencida, depois de 1 h, ou de outra company; 401: chave; 403: origem), o SDK para de enviar, e o getSessionId() passa a devolver undefined: o pagamento não leva uma sessão que o Guardian ignoraria. Um lote recusado por tamanho (413) é descartado.

O que sai do navegador

Só duas chamadas, as duas para a apiUrl, com a chave pública no cabeçalho x-guardian-key:

  • POST /sessions/init: o fingerprint e os componentes do dispositivo (thumbmarkData), uma vez por sessão.
  • POST /sessions/event, a cada interval e no flush(): o fingerprint, os movimentos do mouse e do toque (posição e tempo), o total de teclas (sem quais) e, por campo, os tempos e tamanhos do que foi digitado, colado ou preenchido.

Nunca sai o conteúdo de um campo, nem qual tecla foi apertada, nem o texto colado (só o tamanho dele). Um campo de CVV (autocomplete="cc-csc") nunca é medido, mesmo que esteja em inputFieldIds. Os testes (test/sdk.test.ts) conferem as três coisas e que nenhuma requisição vai para fora da apiUrl.

ThumbmarkJS

A versão é fixa (1.12.0) e a telemetria dele fica desligada (logging: false, collect_beacon: false): nada do dispositivo do cliente vai para thumbmarkjs.com. O código dele ainda traz, no caminho de logging (desligado), um script remoto executado com eval; ele nunca é alcançado, e numa página com CSP sem 'unsafe-eval' o navegador o barraria de qualquer jeito. Trocar de versão é um PR que revisa de novo esses caminhos.

CSP

  • connect-src: a origem da apiUrl (https://guardian.ninepay.com.br).
  • A detecção de autopreenchimento usa um CSS de animações. Ele vai por uma folha de estilo construída (CSSStyleSheet + document.adoptedStyleSheets), que a CSP não barra; nos navegadores sem ela, por um <style> com o styleNonce.
  • O ThumbmarkJS lê canvas, WebGL, áudio e fontes (com um <iframe> about:blank que ele cria e tira na hora). Nada disso sai da página.

Desenvolvimento

npm ci
npm run typecheck
npm test
npm run build      # dist/index.js e dist/index.d.ts
make dev           # tsdown --watch no Docker; a página de teste manual é test/teste.html

Publicar

npm version <patch|minor|major>
npm publish        # o prepublishOnly roda tipos, testes e build antes