Primeiro Uso
Carregue um certificado A1, inspecione a identidade e assine seus primeiros bytes — depois um XML e um PDF — em um único programa Effect.
O que você vai fazer: montar um programa Effect que carrega o certificado A1, lê a identidade, assina e verifica bytes — depois assina um XML e um PDF reaproveitando a mesma camada de assinatura.
Adicione a camada de assinatura central e o signer A1. Inclua effect para o runtime do Effect e o Redacted.
bun add @signature-kit/core @signature-kit/a1 effectO a1SignaturesLayer recebe os bytes do .pfx e a senha em Redacted e fornece o serviço Signatures. Dentro de um único Effect.gen, o signatures.inspect() retorna um SignerIdentity normalizado — o document traz o e-CPF ou o e-CNPJ quando presente — e então signatures.sign e signatures.verify rodam sobre a mesma camada de assinatura. O verify retorna um valor: result.valid é um boolean, e uma falha real surge como um SignatureKitError no canal de erro, nunca uma exceção lançada.
Os bytes do .pfx, não o caminho
pfx é um Uint8Array com o conteúdo binário do .pfx/.p12 — não a string com o caminho do arquivo. Mantenha esses bytes e a senha fora de logs e do controle de versão.
import { a1SignaturesLayer } from "@signature-kit/a1/signer"
import { signatures } from "@signature-kit/core/signatures"
import { Effect, Redacted } from "effect"
const layer = a1SignaturesLayer({
pfx, // Uint8Array — bytes do .pfx/.p12
password: Redacted.make(process.env.A1_PASSWORD ?? ""),
})
export const program = Effect.gen(function* () {
// identidade normalizada — identity.document traz e-CPF / e-CNPJ
const identity = yield* signatures.inspect()
const content = new TextEncoder().encode("content to sign")
const artifact = yield* signatures.sign({
content,
algorithm: "rsa-sha256",
})
const result = yield* signatures.verify({
content,
signature: artifact.signature,
algorithm: artifact.algorithm,
})
return { identity, artifact, result }
}).pipe(Effect.provide(layer))Execute o Effect com Effect.runPromise, ou chame-o a partir de outro programa Effect.
import { Effect } from "effect"
const { result } = await Effect.runPromise(program)
console.log(result.valid) // boolean — true se a assinatura for válidaAmbos os formatos consomem a mesma camada de assinatura via Effect.provide; a linha do layer é idêntica à da etapa anterior. O XML também precisa do xmlRuntimeLayer; verifyXml / verifyPdf leem a chave pública do documento e não exigem a camada de assinatura.
import { signXml } from "@signature-kit/xml/sign"
import { xmlRuntimeLayer } from "@signature-kit/xml/runtime"
import { signPdf } from "@signature-kit/pdf/sign"
import { a1SignaturesLayer } from "@signature-kit/a1/signer"
import { Effect, Redacted } from "effect"
const layer = a1SignaturesLayer({
pfx, // Uint8Array — bytes do .pfx/.p12
password: Redacted.make(process.env.A1_PASSWORD ?? ""),
})
const signedXml = signXml({ xml, referenceId: "nfe-1" })
.pipe(Effect.provide(layer), Effect.provide(xmlRuntimeLayer))
const signedPdf = signPdf({ pdf, policy: "pades-icp-brasil" })
.pipe(Effect.provide(layer))Erros que você pode encontrar
Senha do certificado incorreta
Se a senha do .pfx estiver errada, a camada de assinatura falha com signature-kit.WRONG_PASSWORD no canal de erro — e não com uma exceção. Verifique o segredo antes de prosseguir.
signature-kit.WRONG_PASSWORD— senha do certificado incorreta.signature-kit.SIGN_FAILED— falha ao assinar o conteúdo.signature-kit.VERIFY_FAILED— falha ao verificar a assinatura.